Developer ToolsEmail & SMTPQA

Testing your emails like a PRO with MailHog

Transactional email is easy to break: wrong variables, broken HTML, missing attachments, or messages that never leave the queue. MailHog gives you a fake SMTP server and a web inbox so every password reset, receipt, and notification is visible in development—without spamming real users.

TL;DR

Run MailHog locally (often via Docker), point your app's SMTP host to localhost and port 1025, open the UI at http://localhost:8025, and verify HTML, headers, and links before anything reaches a real provider. Keep MailHog off production networks and drive configuration with environment variables so staging behaves like production—minus the deliverability stack.

9 min read
Developer workflow: testing transactional email locally with MailHog SMTP capture and web UI
Illustration representing local SMTP testing and MailHog web UI workflow for developers.

Why email testing deserves first-class tooling

Registrations, magic links, invoices, and alerts usually ride on SMTP. If you only test in production, you risk silent failures (misconfigured credentials), bad UX (broken layout in Outlook), and compliance issues (PII in the wrong template). A local capture tool turns email into something you can diff, screenshot, and automate like any other API response.

What MailHog does

MailHog implements an SMTP server your application can send mail to. Instead of relaying messages to the internet, it stores them and serves a small web application to browse messages, view source, and download MIME parts. That loop—send → capture → inspect—is the core of professional email QA in dev.

  • No real delivery — Nothing hits Gmail or your customer's inbox unless you explicitly configure an upstream relay (avoid that in dev).
  • Fast feedback — See HTML rendering, plain-text fallbacks, and headers side by side.
  • Team-friendly — Share a compose file or document the ports once; everyone gets the same behavior.

Run MailHog with Docker

Docker is the most reproducible way to run MailHog. The image exposes SMTP and the web UI; map them to the host ports your team expects (defaults below).

docker run -d --name mailhog -p 1025:1025 -p 8025:8025 mailhog/mailhog

For Compose-based projects, add a mailhog service and depend on it from your app container so MailHog starts with docker compose up. Commit the file so new hires get a working mail sandbox on day one.

Default ports (memorize these)

  • 1025 — SMTP for your app (use MAIL_PORT or equivalent).
  • 8025 — Web UI in the browser (search, view raw, delete messages).

Wire your application

Point your mailer at host localhost (or the Docker service name from another container), port 1025, and disable TLS for local MailHog unless you have configured it otherwise. Most frameworks read SMTP_HOST, SMTP_PORT, and SMTP_TLS—keep those in .env.local and never commit secrets.

If you are polishing templates and variables, pair this setup with a structured templating approach—see our post on building a robust mail template system for layout and versioning ideas that complement MailHog testing.

Pro workflows in the web UI

  • Search and filter — Find the latest reset email quickly when you iterate on copy.
  • View source — Validate headers like Message-ID, Reply-To, and encoding.
  • Release API — Automate clearing or releasing messages in advanced setups (useful for integration tests that assert on queue behavior).

CI and automated tests

In CI, run MailHog as a service container, wait for the SMTP port to accept connections, execute tests that trigger email, then fetch messages via the HTTP API or assert through your app's outbox abstraction. Keep tests idempotent: clear messages between runs or use unique recipient addresses per test worker.

Security and environment hygiene

Treat MailHog like a debug endpoint: fine on a developer laptop or private network, unacceptable on the public internet. Never point production DNS or customer traffic at it. For staging, mirror production SMTP settings where it matters (timeouts, pooling), but still route to a capture tool or provider sandbox so mistakes do not email real users.

Alternatives worth knowing

Mailpit offers a similar developer experience with active maintenance and a modern UI. Cloud sandboxes (e.g. Mailtrap-style services) add collaboration, inboxes per environment, and analytics—useful for larger teams. Pick local capture when you want zero external dependency; pick cloud when PMs and QA need shared access without running Docker.

Frequently asked questions

What is MailHog used for?
MailHog is a development SMTP server that stores outgoing messages and shows them in a web UI so you can inspect content and headers without delivering to real addresses.
Which ports does MailHog use by default?
Typically SMTP on 1025 and the web UI on 8025.
Is MailHog safe to use in production?
No—it is for dev and isolated test environments. Use a real transactional email provider with auth, monitoring, and compliance controls in production.
What are good alternatives to MailHog?
Consider Mailpit for local capture, or cloud inbox services when teams need shared, hosted sandboxes.

Official project

MailHog is open source; check the repository for releases, API docs, and issue trackers.

MailHog on GitHub