2
1 Comment

I built InboxTap to test email flows without real inboxes

If a signup test stops after "email sent," it has not tested the full signup flow.

I ran into this problem often. I was switching between Gmail accounts to open verification links and copy OTPs. Mocking the email sender was easier, but it did not test the email itself.

So I built InboxTap. It catches your app's emails on localhost and lets your tests read the real link or code.

It is available on npm, free, open source, and MIT licensed.

The problem

The usual options did not work well for me:

  • A mock tells me that the send function ran, but not that the email is correct.
  • A real inbox needs another account and depends on an outside service.
  • A shared test inbox can mix up emails when tests run at the same time.
  • A larger setup or paid tool can turn a simple test into more work.

I wanted a small tool that stayed local and tested what the user would actually receive.

How it works

Start InboxTap:

npx inboxtap

Point your app at it:

SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_SECURE=false

Then use a unique inbox in your test:

import { InboxTapClient } from "inboxtap/client";

const inboxTap = new InboxTapClient();
const inbox = await inboxTap.createInbox({ alias: "signup" });

await page.getByLabel("Email").fill(inbox.address);
await page.getByRole("button", { name: "Create account" }).click();

const verificationUrl = await inbox.waitForLink({
  subject: /verify your email/i,
});

await page.goto(verificationUrl);

Each test gets its own address, so parallel tests do not read each other's emails. InboxTap can also return OTPs, custom matches, complete messages, and data through a local REST API.

Why I made it free

I do not think every developer tool needs to become another subscription.

I understand why hosted tools charge money. Servers, support, and maintenance cost money. But InboxTap runs locally and solves a basic development problem, so I wanted anyone to be able to use it.

Email is part of signup, password resets, security, invitations, and onboarding. Testing those flows should not depend on whether a developer or small team can pay for another account.

Making InboxTap free and open source is one way I can support the developer community. People can use it, read the code, change it, and contribute back.

What I kept simple

InboxTap does one job: catch an email and return what the test needs.

  • It runs on localhost and never sends mail outside your machine.
  • Every test can use its own inbox address.
  • Storage and wait times have clear limits.
  • There is no browser inbox, persistence, attachment support, webhooks, or Docker image.

If you need a visual inbox or saved messages, another tool may suit you better. InboxTap is for automated tests that need a link, code, or message and then move on.

What I learned

The missing part was not another large testing platform. It was a simple way to connect the email my app sent with the next step in the test.

What I would love feedback on

  1. How are you testing verification links, password resets, invitations, and OTPs today?
  2. Where do you draw the line between a developer tool that should stay free and a service worth paying for?

Try InboxTap

View the InboxTap source on GitHub

on July 21, 2026
  1. 1

    The distinction between testing that an email was sent and testing the actual user journey is what stood out to me.

    Treating email as part of the product flow rather than a side effect makes the problem feel much more concrete.