Fake SMTP server for development and testing
A fake SMTP server accepts email over the standard SMTP protocol, stores each message for inspection, and never relays anything to a real recipient. Your application connects, authenticates, and sends exactly as it would in production, but every email lands in a capture inbox instead of a customer's mailbox.
- 500 emails a month, no card
- EU-hosted
- Plain SMTP, any language
How does SMTP capture actually work?
Your app connects to a fake SMTP server with a host, port, username and password, exactly as it would connect to SendGrid or Postmark. The server accepts every message and confirms it was sent, so your app carries on as usual and cannot tell the difference. It just never passes the email on to the recipient.
Instead, the message is kept. You open it in a web inbox or fetch it over an API, with the rendered HTML, the links, the headers and the address it was meant for, while [email protected] never hears about it.
Why not just send through your real provider?
Sending test email through your real provider risks delivering unfinished messages to real customers and feeding bounces and spam complaints from test runs into your production sending reputation. The classic version: a staging database gets seeded from a production dump, someone re-enables the reminder cron job to test it, and a few thousand customers get a half-finished email with a broken staging link on a Saturday morning. A fake SMTP server makes that mistake structurally impossible. The mail is accepted, stored, and goes nowhere, no matter what addresses are in the database. It also keeps test traffic off your sending domain entirely.
Real provider
- Unfinished email reaches customers
- Bounces count against your reputation
- Test traffic on your sending domain
Fake SMTP server
- Accepted and stored
- Delivered to no one
- Sending domain untouched
How do I point Nodemailer, Laravel, Django, or Rails at a fake SMTP server?
Point any framework at a fake SMTP server by changing four environment values, the SMTP
host, port, username, and password; no application code changes are needed because the
fake server speaks standard SMTP. The examples below use Mailloop; for a local Mailpit,
replace the host with localhost and the port with 1025. Port 587
uses STARTTLS, 465 uses implicit TLS, and 25 and 2525 also work if your network blocks the
others.
Nodemailer (Node.js)
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
host: 'sandbox.mailloop.io',
port: 587, // also works on 25, 465, and 2525
secure: false, // set true for port 465
auth: {
user: 'your-sandbox-username',
pass: 'your-sandbox-password',
},
}); Laravel (.env)
MAIL_MAILER=smtp
MAIL_HOST=sandbox.mailloop.io
MAIL_PORT=587
MAIL_USERNAME=your-sandbox-username
MAIL_PASSWORD=your-sandbox-password
MAIL_ENCRYPTION=tls Django (settings.py)
# settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'sandbox.mailloop.io'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'your-sandbox-username'
EMAIL_HOST_PASSWORD = 'your-sandbox-password'
EMAIL_USE_TLS = True Rails (Action Mailer)
# config/environments/development.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'sandbox.mailloop.io',
port: 587,
user_name: 'your-sandbox-username',
password: 'your-sandbox-password',
authentication: :plain,
enable_starttls_auto: true
}
Mailloop captures by SMTP authentication, not by recipient: whatever address is in the
To field, the message lands in the sandbox that owns the credentials. That is what
makes the production-dump scenario safe.
Fake SMTP servers at a glance
| Tool | Hosting | Cost | Maintained |
|---|---|---|---|
| Mailpit | Self-hosted (Go binary or Docker) | Free, MIT license | Yes, active |
| smtp4dev | Self-hosted (.NET or Docker) | Free, BSD license | Yes, active |
| Mailloop | Hosted (sandbox.mailloop.io) | Free plan: 1 sandbox, 500 emails/mo, then from $12/mo | Yes |
| MailHog | Self-hosted (Go binary or Docker) | Free, MIT license | No, abandoned since 2020, use Mailpit |
Should you self-host a fake SMTP server or use a hosted one?
Self-host a free tool like Mailpit when you test alone on a single machine; pick a hosted sandbox when a team, a staging environment, a CI pipeline, or an AI agent needs to reach the same inbox without extra infrastructure.
Self-hosted: Mailpit and smtp4dev
For testing on a single machine, the self-hosted tools are genuinely good and cost nothing. Mailpit is a single Go binary with no runtime dependencies: SMTP on port 1025, web UI on 8025, a REST API you can assert against, and active maintenance (it is the successor Laravel Sail and DDEV adopted after MailHog was abandoned). smtp4dev is the .NET equivalent with a web UI, IMAP and POP3 access, and a Swagger-documented API. If your whole workflow is "run the app locally, look at the email", run Mailpit in Docker and you are done.
The self-hosted model gets awkward when more than one machine is involved. A teammate cannot open the inbox running on your laptop. CI needs a service container wired up per pipeline. Staging needs the tool deployed, secured, and kept up to date. Spam scoring in Mailpit requires running a separate SpamAssassin server. Each problem is solvable; they just add up to infrastructure you maintain for a debugging tool.
Hosted: Mailloop
Mailloop is a hosted fake SMTP server at sandbox.mailloop.io, listening on
ports 25, 465, 587, and 2525. Each sandbox has its own SMTP credentials and a shared web
inbox, so local dev, staging, CI, and every teammate point at the same place with nothing
to deploy. Captured email is readable through the REST API at
api.mailloop.io and the @mailloop/sdk npm package for automated assertions,
webhooks can push new messages to your test harness, and the inbox includes spam and deliverability
checks plus email screenshots. When a message needs to reach an actual mailbox (a designer checking
rendering in real Gmail), you can resend it to a verified real address. AI coding agents get
the same access through an OAuth MCP server at https://api.mailloop.io/mcp and
agent skills at
github.com/mailloop/skills.
Which one fits your setup?
| Concern | Self-hosted (Mailpit, smtp4dev) | Hosted (Mailloop) |
|---|---|---|
| Cost | Free (MIT / BSD), your infrastructure | Free plan: 1 sandbox, 500 emails/mo. Paid from $12/mo |
| Setup | Run a binary or Docker container per environment | Change SMTP host and credentials, nothing to run |
| Team access | Inbox lives on one machine unless you network it | Shared web inbox per sandbox |
| CI | Service container per pipeline, wire ports and env vars | Point tests at sandbox.mailloop.io, assert via API or SDK |
| Spam scoring | Mailpit needs a separate SpamAssassin server; none in smtp4dev | Built-in spam and deliverability checks |
| AI agent access | Third-party MCP for Mailpit only, none for smtp4dev | Hosted OAuth MCP server, no key to paste |
| Maintenance | You patch, upgrade, and secure it | None |
Solo developer testing locally: use Mailpit. Team, staging, CI, or AI agents that need to read email: use a hosted sandbox like Mailloop.
One tool to avoid for new projects: MailHog. It has had no release since 2020, ships an unpatched stored XSS in its web UI, and only accepts unencrypted connections. Mailpit is the drop-in replacement.
If you are weighing hosted services against each other, see Mailtrap alternatives compared side by side and our roundup of the best email testing tools in 2026. Related: what an email sandbox adds on top of raw SMTP capture, and how to wire email testing into coding agents with the Mailloop MCP server. Replacing a local catcher? See Mailloop vs MailHog and Mailloop vs Mailpit.
Frequently asked questions
Can't find what you're looking for? Email our team →
What is a fake SMTP server?
How do I point my app at a fake SMTP server?
What is a good MailHog alternative?
Can I use a fake SMTP server in CI?
Last updated