MailHog alternative for teams and CI.
MailHog has not had a release since 2020. Drop the container, point SMTP at a Mailloop sandbox, and every test email lands in an inbox that staging, CI and your teammates share.
- 500 emails a month, no card
- EU-hosted
- Plain SMTP, any language
- SMTP on 587 and 465
- TLS vs none
- mail after a restart
- Kept vs lost
- who can open the inbox
- Team vs 1 login
- how a test gets the email
- Wait vs poll
Why teams are replacing MailHog
It still catches mail. What it stopped doing is keeping up.
No release since 2020
Last release v1.0.1 on 2020-08-11, last commit 2022-08-02. Its Docker image is built for amd64 only, so on an Apple silicon laptop it runs under emulation.
A known XSS in the web UI
Version 1.0.1 has a published stored XSS (Exploit-DB 50971) that was never fixed. A captured email can run script in the browser of whoever opens it, which matters as soon as the inbox is on a shared server.
No TLS on SMTP
MailHog accepts plain SMTP only, with no STARTTLS and no implicit TLS; the request has been open since 2016. An app configured like production, with STARTTLS on 587, has to be reconfigured just for testing.
Mail lives in memory
By default MailHog keeps messages in memory, so a restart empties the inbox unless you set up MongoDB or maildir storage. Redeploy staging and the emails a tester was about to check are gone.
On your laptop, Mailpit is the answer.
If MailHog only ever ran on your own machine, replace it with Mailpit: same ports, maintained, free. Laravel Sail and DDEV already did. Mailloop is for the moment the inbox has to leave your laptop.
Mailpit, when
- Only you read the email
- It runs next to the app in docker-compose
- You want it free and offline
Mailloop, when
- Staging mail has to be checked by QA
- A test in CI waits for the email
- Nobody wants to run and patch a mail catcher
What you get instead
One inbox per environment, open to the team
MailHog gives one shared inbox per running instance, behind one password file. A Mailloop sandbox per environment keeps staging, dev and QA apart, and every teammate signs in with their own account. 5 members and 5 sandboxes from $12 a month.
Wait for the email instead of polling
With MailHog a test calls /api/v2/search in a loop until the message shows up. Mailloop holds one request open on the server until a matching email lands and returns it parsed.
Waiting for an email with Mailloop
import { MailloopClient } from '@mailloop/sdk';
const client = new MailloopClient({
apiKey: process.env.MAILLOOP_API_KEY,
});
// Held open on the server until the email lands
const email = await client.emails.waitFor(sandboxId, {
to: '[email protected]',
timeout: 30_000,
}); Polling MailHog for an email
async function waitForMail(to, timeoutMs = 30000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const q = new URLSearchParams({ kind: 'to', query: to });
const res = await fetch(`http://localhost:8025/api/v2/search?${q}`);
const { items } = await res.json();
if (items.length > 0) return items[0];
await new Promise(r => setTimeout(r, 500));
}
throw new Error(`No email to ${to} within ${timeoutMs} ms`);
}
const msg = await waitForMail('[email protected]'); MailHog vs Mailloop
| | MailHog | |
|---|---|---|
| Running it | ||
| Maintenance | Yes: Hosted and updated for you | No: Last release in 2020 |
| Where it runs | Yes: Hosted in the EU, nothing to deploy | Partly: Your laptop or server |
| Cost | Yes: Free for 500 emails a month | Yes: Free, you pay for the machine |
| Capture | ||
| TLS on SMTP | Yes: STARTTLS on 587, TLS on 465 | No: Plain SMTP only |
| Mail after a restart | Yes: Kept, 200 per sandbox on Free | Partly: Lost unless you add MongoDB or maildir |
| Separate inboxes | Yes: 5 sandboxes on Basic | Partly: One per running instance |
| Inbound address | Yes: Every sandbox, every plan | No: None |
| Testing and teams | ||
| Wait for an email in a test | Yes: waitFor in the SDK and API | No: Poll /api/v2/search |
| Screenshots in email clients | Yes: Gmail, Outlook, Apple Mail and more | No: HTML in your browser |
| Team access | Yes: Own login per member | Partly: One shared password file |
| MCP server for agents | Yes: Hosted, OAuth | No: None |
MailHog facts checked on September 26, 2026 against its GitHub repository, Docker Hub and Exploit-DB. Mailloop numbers come from our pricing page.
Seen something inaccurate? Tell usLeaving MailHog, common questions
Choosing between hosted tools? See Mailloop vs Mailpit and the Mailtrap alternatives overview.
Is MailHog still maintained?
Is it safe to keep MailHog on a shared staging server?
What replaced MailHog in Laravel Sail and DDEV?
Can I keep port 1025 when I move to Mailloop?
What about MailCatcher?
Last updated