Sahan Dulanjaya

QA Automation Engineer

API Tester

ISTQB Certified

Web3 Enthusiast

Freelancer

Sahan Dulanjaya

QA Automation Engineer

API Tester

ISTQB Certified

Web3 Enthusiast

Freelancer

Anon Mail

  • Date: September 2026
  • Categories: Web Apps
  • Stack: JavaScript, Vite, Cloudflare Workers, Cloudflare D1, Cloudflare Email Routing, Resend Pro, Spaceship
Try Anon Mail

Anon Mail started with a problem I kept running into as a QA engineer. Every sign-up flow, password reset and one-time code needs a real inbox to land in. Using my own email for that got messy fast, and the free temp-mail sites were unreliable, often blocked, and open for anyone to read. So I built my own disposable inbox service, made for testing.

How it works

  1. Generate an address on the mail domain, either a random one or a custom name with an optional label like “signup test 2”. It goes straight to the clipboard.
  2. Paste it into the app being tested and trigger the email.
  3. A few seconds later the email shows up in that address’s inbox, ready to read, with attachments opening right in the reader.
  4. If the flow needs a reply, a signed-in account can answer or send fresh mail from the same address, which is handy for checking two-way email flows.

Anything flagged as spam is labelled instead of quietly disappearing, addresses can be pinned or deleted, and a desktop notification plus an unread count mean I don’t have to keep watching the tab.

Access levels

I’m the only admin. From the admin panel I can create an account for anyone, choose how they sign in and decide exactly what they’re allowed to do. Guests can try it without an account, but with tight limits.

GuestTesterAdmin
WhoAnyone, no sign-in needed (limits are counted per IP address)Accounts I create for peopleMe, the only admin
Send and replyNo, receive onlyYes, 20 messages a dayUnlimited
Message sizeNot applicable2 MB, up to 5 attachments and 5 recipients25 MB, up to 20 recipients
Addresses3 at a time, 5 new per hour50 at a time, 30 new per hourUnlimited
Checks for mailEvery 30 secondsEvery 30 secondsAs often as every 3 seconds
Mail kept for7 days365 days365 days
ExtrasNoneLimits can be raised or lowered per accountCan take over existing addresses and sees mail sent to addresses nobody generated

The admin panel

This is the part I use the most. I can create accounts, reset passwords, disable or delete them, and set default policies for testers and guests, while any single account can keep its own figure for one setting and follow the defaults for the rest. A usage dashboard shows requests over time, addresses created, storage per account against Cloudflare D1’s free tier, and delivery stats straight from Resend. In Settings I can switch the theme, set the refresh rate and default domain, and turn on auto-copy, desktop notifications and the unread count.

How it’s all connected

Anon Mail is split into a few pieces that only talk to each other over HTTPS:

  • The app is a single-page app written in vanilla JavaScript and built with Vite into a handful of static files, served from anon.sahandulanjaya.com. The same code can also run as a Chrome extension, which is where the unread count on the toolbar icon comes from.
  • The API is a Cloudflare Worker. Every request from the app carries a sign-in token, and the Worker checks that account’s role and limits before it does anything. Accounts, addresses, messages and usage figures all live in Cloudflare D1, Cloudflare’s SQLite database, which runs right next to the Worker.
  • Incoming mail arrives through Cloudflare Email Routing. The mail domain’s MX records point at Cloudflare, a catch-all rule hands every message to the Worker, and the Worker parses it and files it under the right address. That’s also how mail sent to an address nobody has generated yet still gets caught, and only I can see it.
  • Outgoing mail goes through Resend. The sending domain is verified there with SPF and DKIM records, so replies sent from the app land in real inboxes instead of spam folders. The domain is registered with Spaceship and its DNS is managed on Cloudflare.

Keeping polling cheap

An inbox that refreshes every few seconds can burn through requests quickly, so this is the part I spent the most time on:

  • Instead of downloading the inbox on every refresh, the app sends a tiny “has anything changed?” probe along with a token from its last check. If nothing has changed, the Worker answers with a 304 and the app stops there. Only a real change triggers a full fetch.
  • Everyone picks a refresh rate in Settings (every 3, 5, 10 or 30 seconds, or only when they press refresh), but never faster than their role allows: every 3 seconds for me, every 30 seconds for testers and guests.
  • The app slows itself down when you step away. After a minute without a click or key press it checks every 15 seconds at most, and after five minutes, every 30.
  • When the tab is hidden, polling stops completely and catches up the moment you come back. It also pauses on the admin dashboards, where live mail isn’t needed.
  • Usage counters are buffered in the Worker and written to D1 in batches instead of on every request, and a nightly job clears out expired mail and records how much storage is left.

The usage dashboard keeps an eye on all of this. When I last checked, 86% of probes over the past month came back with nothing new, so watching a quiet inbox costs almost nothing. It also measures traffic against the Workers free plan’s 100,000 requests a day and storage against D1’s free 5 GB, so I can see how much room is left before anything would cost money.

Why Resend Pro

Resend’s free plan allows 3,000 emails a month, but never more than 100 in a single day. Testing doesn’t spread out evenly: one regression run can fire off dozens of sign-ups, password resets and replies in an afternoon, and with testers using it too, that daily cap would stop sending right in the middle of a busy day. Resend Pro removes the daily limit completely and raises the monthly allowance to 50,000 emails, so a heavy testing day never gets cut short.

Tech stack

Vanilla JavaScript and Vite for the app, Cloudflare Workers for the API, Cloudflare D1 for the database, Cloudflare Email Routing for incoming mail, Resend Pro for outgoing mail, and Spaceship for the domain.