You are browsing as a guest. Sign up (or log in) to start making projects!

mail.swrg

  • 7 Devlogs
  • 21 Total hours

A fast, disposable email service built on Cloudflare.

Ship #1 Changes requested

mail.swrg · a fast, minimal, disposable inbox

Every sketchy site wants your email before showing you anything. That used to mean either handing over your real inbox to the spam pipeline or juggling slow, ad-infested temp-mail sites with clutter everywhere.

I built mail.swrg: a fast, minimal disposable email service.

What it does:

  • One click → instant random address like [email protected]
  • Incoming mail shows up automatically
  • Clean inbox UI: dark, distraction-free, zero ads, zero trackers
  • Keep / reuse your address across sessions with one-click export & import (save the session file, load it anywhere later)
  • Wipe — delete the entire mailbox anytime, nothing lingers
  • Everything runs on Cloudflare edge: Workers, D1, Email Routing

Why I’m being honest about “fast”: mail takes about ~10 seconds to appear. Most mail clients hold outgoing messages in a queue for ~5s before actually sending them, and the inbox refreshes every ~5s after that. So if you test it and nothing shows instantly, give it a second. It’s on them, not us.

  • 7 devlogs
  • 21h
Try project → See source code →
Open comments for this post

2h 37m 16s logged

#7 - it’s done

the inbox now says “Pulling Emails” until the first fetch is done. way less confusing.

added a small note in the footer that mail takes ~10s to show up bc most mail clients hold ur email in a queue for 5s before sending.

and i spent way too long on scrollbar-gutter not working in chrome. works in firefox.

anyway the project is actually finished now. it opens fast, it doesn’t freeze, and im not touching it anymore. thanks for reading i guess, this is the last one. gg

0
0
17
Open comments for this post

1h 20m logged

6th - Another cleanup session. moved message fetching to tanstack query so i could delete like 50 lines of manual polling code. fixed the notification sound not playing (browser autoplay policy is annoying). fixed delete mailbox clearing localStorage even when the server request fails. added error handling in a bunch of places where it was missing. removed dead code.

tanstack query is really nice once you set it up but the default behavior around networkMode: "online" and staleTime can bite you. the query just silently skips if youre offline which is confusing

thats it

0
0
24
Open comments for this post

1h 12m 3s logged

#5 - Did a lot of cleanup. first thing, the refresh system was kinda broken? so i had to refactor the whole countdown logic in use-refresh.tsx to use a ref flag instead.
also figured out that messages were being fetched TWICE. like useMessages had its own refetchInterval: 5000 AND useRefresh was doing the same thing with its own interval. so now useRefresh is the single source of truth for polling and i removed the redundant one from useMessages.

also cleaned up a bunch of stuff that was just… messy:

  • extracted validateSession, exportSession, and STORAGE_KEY to lib/utils.ts because they were duplicated across files
  • the delete button had no confirmation dialog, now it has
  • useCopyToClipboard had a timeout leak where if you copied twice fast the old timeout would still fire. fixed that with a ref
  • the delete handler now reloads the page after success so it auto-creates a new mailbox

also the countdown was ticking even when there was no session (like after deleting) which made no sense so now it checks if a session exists before counting down

anyway thats pretty much it. next up i actually need to get the inbox working

0
0
49
Open comments for this post

2h 1m 7s logged

#4 - To add a way to export and import mail sessions, i added two buttons in the header. one for export, one for import. export was pretty simple. to import, we read the file, parse the JSON, and then validate it. validateSession function checks if the object has address and key and that theyre both non-empty strings.

now i wanted two different states:

  1. if the file is valid -> show a warning “this will overwrite your current session, u sure?”
  2. if the file is invalid -> just show an error with the Alert component

used AlertDialog from cossui for both. the valid one has a Cancel and Continue button, and the invalid one just shows the error in a red Alert and an OK button to close
also had to make sure the dialog state is controlled with open and onOpenChange because otherwise it wouldnt close properly after importing.

next up i wanna work on the inbox and make it actually look good when theres no emails

0
0
41
Open comments for this post

2h 21m 47s logged

#3 - Now i needed rate limiting because without it anyone could just spam the API and create like a million mailboxes which would be really bad. so i started looking into how to do this with cloudflare workers because thats what im using and they have this fancy Rate Limiting Binding that looked really clean. you just add some config to wrangler.toml, add the binding to your code, and boom - rate limiting.

so i added the bindings, deployed, tested… and nothing. like the binding was there, wrangler showed it in the deploy output, i could even see it in the cloudflare dashboard. but when i actually hit the API with like 8 requests in a row, every single one went through. no 429s, nothing.

i spent way too long on this. i was reading the docs, checking if my plan supported it, checking if the binding was actually being called, trying different keys… nothing worked. the binding just silently does nothing. like it deploys fine but then just… doesnt do anything? i dont even know whats wrong at this point.

so after giving up on the official way, i just went with D1. yeah the database. im literally storing rate limit counters in a sql table which is… not great for performance obviously because now every single request has to do a database query just to check if youre rate limited. but hey at least it actually works.

so right now every POST to /mailboxes does a SELECT on the rate_limits table, checks the count, either increments it or creates a new row, and THEN does the actual mailbox creation. so youre looking at like 2 extra database queries per request just for rate limiting. its not ideal but its what i got.

hopefully i figure out the cloudflare one someday because this is genuinely a worse solution in every way except that it works. but for now it prevents abuse so whatever.
anyway thats where im at. rate limiting works but its slow.

0
0
30
Open comments for this post

1h 44m 7s logged

#2 - For the ui i went with shadcn but not the default one, im using the coss ui variant which has nicer colors and the components feel more polished. the buttons and inputs have this subtle shadow thing that looks clean in dark mode.

for state management im keeping it simple, just storing the address and recovery key in localStorage. on first load if theres nothing in storage it auto creates a mailbox. the key is needed for every request so without it you cant read any messages. when you delete the mailbox it clears storage and resets everything.

right now the ui has a header with refresh and delete buttons, an input group showing the address with a copy button. gonna add the inbox next…

0
0
70
Open comments for this post

9h 18m 12s logged

#1 - Had a domain lying around, so I thought, why not put it to some use?

so basically i wanted a temp mail service. nothing crazy, just something that works fast and especially no ads. been sitting on the idea for a while and finally started it this week.

first 2 days were basically me fighting cloudflare email routing. had no idea how workers could intercept emails before this. like the concept is simple but actually getting it to work took way longer than i expected.

the worker handles everything now. creating mailboxes, storing incoming emails, serving them through the api. used hono for routing which is surprisingly nice for workers. postal-mime for parsing the raw email content. d1 for the database. pretty straightforward stack honestly.

Still need to build the frontend properly but the backend is solid.

0
0
59

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…