Mailtrap

mailtrap.iocontributed by Samuele Ongaro

YES

Replaceable in one session with an AI coding agent.

A fake inbox for development: your app sends mail to it instead of to real people, and you can read the message, check the HTML and see how it scores against spam filters.

Promptfree, for everyone, and the only version there is
Build me a development mail catcher that replaces Mailtrap: my application sends to it, nothing reaches a real person, and I can see exactly what would have arrived.

STACK
- Node 20+ with Fastify for the web interface
- An SMTP server in the same process, or smtp-server as a library
- SQLite through better-sqlite3, WAL mode, with FTS5
- Caddy in front, on a private network

THE ONE RULE
- Nothing is ever delivered onward. This server accepts mail and stores it, and there is no configuration anywhere that can make it relay to the internet
- That is the entire safety property. Write it in the README, and make sure there is no code path — not a forwarding feature, not a 'send to real address' button — that could ever be switched on by accident
- Accepting on a private interface only, by default

THE DATA MODEL
- inboxes: id, name, slug, username, password_hash, retention_hours, max_messages, is_shared
- messages: id, inbox_id, from_address, from_name, to_json, cc_json, bcc_json, subject, message_id, in_reply_to, raw_path, size_bytes, html_body, text_body, headers_json, spf_result, dkim_result, dmarc_result, spam_score, received_at, read_at
- attachments: id, message_id, filename, mime, bytes, path, sha256, is_inline, content_id
- links: id, message_id, url, position — extracted, so a test can click one
- checks: id, message_id, kind, status, detail — the analysis results
- The raw message is always stored whole. Every view is derived from it, and it is what you fall back to when something looks wrong

RECEIVING
- Plain SMTP, with STARTTLS and authentication accepted but never required in a development context
- Accept anything: malformed headers, a wrong From, an enormous attachment, an eight-bit body. The point is to see what your application actually sends, not to validate it
- Multiple inboxes distinguished by the SMTP username, so several projects share one server
- A per-inbox message cap and retention, applied by a sweeper

READING
- The message list with sender, subject, recipients and time, and unread state
- Four views per message: rendered HTML, plain text, the raw source, and the headers as a table. All four, always — a bug in mail is usually visible in exactly one of them
- Attachments listed and downloadable, with inline images resolved by content id in the HTML view
- The HTML rendered inside a sandboxed iframe with no network access, so a remote tracking pixel is not fetched and an external stylesheet cannot leak that you opened it
- A width switcher to see it at phone and desktop size

THE ANALYSIS, WHICH IS WHY THIS BEATS A LOG FILE
- Spam scoring with SpamAssassin or its rule set, with the individual rules that fired listed rather than only a number
- SPF, DKIM and DMARC evaluated against what the message claims, so an authentication mistake is caught in development rather than by a spam folder in production
- HTML checks: unsupported CSS for common mail clients, missing alt text, missing plain-text alternative, a subject that will be truncated, images without dimensions, a total size over the threshold where clients clip the message
- Broken links checked with a request that does not follow anything into a private address
- Every check is a rule with a plain-sentence explanation, and the rules are a file that can be extended

THE API, WHICH IS WHAT TESTS USE
- List messages in an inbox, get one, get its HTML, text and headers, delete it, empty the inbox
- Wait-for-message with a filter and a timeout, which is the endpoint an end-to-end test actually needs
- Extract a link matching a pattern — the confirmation link, the reset link — because that is what nine out of ten tests are doing
- Tokens per inbox, and everything scoped

SHARING
- A shared inbox is the point: the whole team looks at the same messages rather than at one developer's machine
- A read-only link to a single message, for showing somebody what arrived
- No account needed to read a shared inbox on the internal network

OPERATIONS
- .env: DATABASE_PATH, STORAGE_PATH, BASE_URL, SMTP_PORT, SMTP_BIND, SESSION_SECRET, RETENTION_HOURS
- Migrations on boot, each once
- Bound to a private interface. If it must be reachable more widely, put it behind authentication — an open mail catcher is a place strangers store things
- A disk watchdog and a working sweeper
- Health endpoint that accepts and reads back one message

WHAT MATTERS MOST
Never relaying, and the wait-for-message endpoint. Get the safety property right first and prove there is no path out, then build the API your tests will use. Everything else is a mail client, and a mail client is easy.

Give me the repository, the SMTP server, migrations, .env.example, the test-helper client, and a README with deploy steps and the no-relay guarantee stated at the top.

What you lose

  • Spam scoring and blacklist checks against rule sets somebody keeps current
  • HTML previews rendered across a range of real email clients
  • A shared inbox the whole team can open, rather than one on a developer machine

If you would rather not build

  • maildev, if you want it as an npm dependency

What it costs

read from their page 15 Aug 2026

PlanBilled monthlyBilled yearlyLast read
—$15/mo—15 Aug 2026

Their pricing page is where these came from. Seeing a different price? Tell us.

The escape hatch

open source · no votes, no paid placement

Mailpit

$0

One binary: SMTP sink, web inbox, HTML checks and an API.

axllent/mailpitfree · open source

MailHog

$0

The original local mail catcher; still fine for simple use.

mailhog/MailHogfree · open source

Why this verdict

our own opinion · changed only by a person

82/100

Verdict yes at 82: an SMTP sink and a message viewer are two libraries and an afternoon. Spam scoring is the one thing you would not reproduce, and most teams never look at it.

History

tracked since 10 Aug 2026 · nothing is ever overwritten

Interest · last 30 dayspeak 2/day
views01230 Aug4 Sept9 Sept14 Sept19 Sept24 Sept28 Sept
— views— prompt copies none yet— votes none yet

Questions about Mailtrap

answered from the record above

Is Mailtrap free?

No — the plan we track is $15 a month. Email Testing from around $15/month billed monthly; the sending product is priced separately by volume.

Can you replace Mailtrap by building your own?

YES. Replaceable in one session with an AI coding agent. Replacement score 82 out of 100, build time one session. Read what you lose before you decide.

How much does Mailtrap cost?

$15 a month on Email Testing — $180 a year. Recorded 9 Aug 2026.

What do you lose by replacing Mailtrap?

Spam scoring and blacklist checks against rule sets somebody keeps current; HTML previews rendered across a range of real email clients; A shared inbox the whole team can open, rather than one on a developer machine. If any of those carry weight for you, keep paying.

Is there an open-source alternative to Mailtrap?

Yes: Mailpit, MailHog. The prompt on this page is for when you want it your way instead.

Related entries

same category first, most replaced first

All 33 in Email & newsletters

Not sending yet

Every week, something stops being worth paying for.

New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.

free forever · no tracking pixel · stored here, never passed to anyone

Esc