<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jose</title>
    <description>The latest articles on DEV Community by Jose (@agentburner).</description>
    <link>https://dev.to/agentburner</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3833309%2F2778ec64-de4a-4785-8f8a-aa1b83dea6ae.png</url>
      <title>DEV Community: Jose</title>
      <link>https://dev.to/agentburner</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/agentburner"/>
    <language>en</language>
    <item>
      <title>The History of Disposable Email</title>
      <dc:creator>Jose</dc:creator>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/agentburner/the-history-of-disposable-email-559</link>
      <guid>https://dev.to/agentburner/the-history-of-disposable-email-559</guid>
      <description>&lt;p&gt;The first disposable email service launched in 2000. A developer named Josh built Spamgourmet — you created addresses like &lt;code&gt;something.3.username@spamgourmet.com&lt;/code&gt;, where the &lt;code&gt;3&lt;/code&gt; meant "accept three emails then stop forwarding." The counter was baked into the address itself. No web UI needed. Josh maintained it until he died of brain cancer in 2020. His son Josiah runs it now.&lt;/p&gt;

&lt;p&gt;Twenty-six years later, AI agents are creating their own email inboxes without human intervention. The throughline between these two things is shorter than you'd think.&lt;/p&gt;

&lt;h2&gt;
  
  
  Era 1: Anti-Spam (2000-2010)
&lt;/h2&gt;

&lt;p&gt;By the late 1990s, every website wanted your email to register. Every registration meant more spam. The CAN-SPAM Act wouldn't arrive until 2003. People needed a way to give out email addresses that worked but didn't matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mailinator (2003)&lt;/strong&gt; defined the category. Paul Tyma, a Google engineer, got the idea from his drunk roommate. The first version took three days to code. The concept: any email sent to &lt;code&gt;anything@mailinator.com&lt;/code&gt; creates an inbox. No signup. No password. Just visit the site, type the address, and read whatever arrived.&lt;/p&gt;

&lt;p&gt;The original ran on a single server — AMD 2GHz Athlon, 1GB RAM, 80GB IDE hard drive. It processed 4.5 million emails a day. Tyma's architecture blog post went viral on Hacker News: keep everything in RAM, delete oldest first, never touch disk. The entire stack — web app, SMTP server, storage — ran in a single JVM. The Washington Post and New York Times wrote about it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10 Minute Mail (2006)&lt;/strong&gt; added the countdown timer. Devon Hillard built it as a weekend project to learn JBoss Seam. The UX innovation was the constraint — your address self-destructs in 10 minutes. No choices to make. Visit the site, get an address, use it, walk away. It spawned an entire genre: 20 Minute Mail, 30 Minute Mail, Minute Inbox.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Guerrilla Mail (2006)&lt;/strong&gt; came out of Chicago and quietly became a machine. Twenty billion emails processed over its lifetime. A hundred and thirty thousand emails per hour, currently. The team built their own SMTP server in Go — open-sourced as Go-Guerrilla — because existing mail servers were too bloated. Guerrilla Mail was also the first to let you send from a disposable address, not just receive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;YOPmail (2004)&lt;/strong&gt; won France. &lt;strong&gt;TrashMail (2002)&lt;/strong&gt; won Germany. &lt;strong&gt;Discardmail (2004)&lt;/strong&gt; survived two decades under four different names. Each served the same purpose: a real email address for a task you didn't care about keeping.&lt;/p&gt;

&lt;p&gt;The users were humans. The interface was a browser. The business model was free. The enemy was spam.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Blocklist Wars
&lt;/h2&gt;

&lt;p&gt;As disposable email services multiplied, websites fought back.&lt;/p&gt;

&lt;p&gt;Websites built blocklists of known disposable domains. Services created alternate domains — Mailinator alone has hundreds, including gems like &lt;code&gt;thisisnotmyrealemail.com&lt;/code&gt;. Open-source blocklists appeared on GitHub around 2014, community-maintained and updated daily. By 2025, they tracked over 110,000 disposable email domains.&lt;/p&gt;

&lt;p&gt;The cat-and-mouse game escalated. Services rotated domains. Users pointed their own custom MX records at Mailinator — completely undetectable by blocklists. Detection APIs emerged — IPQualityScore, UserCheck — offering real-time disposable email identification as a service.&lt;/p&gt;

&lt;p&gt;Temp-mail.org won this war through distribution, not technology. The domain was nearly perfect for search intent. Available in 29 languages. Chrome extension. Android app. 56% of their 15 million monthly visits come from organic search. They didn't build the best disposable email service. They built the most findable one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Era 2: Software Testing (2011-2024)
&lt;/h2&gt;

&lt;p&gt;Around 2011, the use case shifted. Disposable email stopped being about avoiding spam and started being about testing software.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Guerrilla Mail's API (April 2011)&lt;/strong&gt; was the first. Free, public, no registration — developers could create and check disposable inboxes programmatically. This was the moment disposable email became infrastructure instead of a consumer tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mailsac (2012)&lt;/strong&gt; and &lt;strong&gt;Mailosaur (2013)&lt;/strong&gt; were built specifically for QA teams. The founders needed to test their own email workflows, built their own tools, and opened them up. These integrated with Selenium, Playwright, Cypress — the browser automation frameworks that QA teams were already using.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mailinator pivoted.&lt;/strong&gt; What started as a free consumer tool became an enterprise email testing platform. Private domains, REST API, webhooks, SMS testing (added in 2018), email load testing. Pricing went from free to $79-$459 per month. Revenue hit $126K with 300 enterprise customers by 2017, bootstrapped.&lt;/p&gt;

&lt;p&gt;The customer was no longer a person avoiding spam. It was a QA team running email tests in CI/CD pipelines. The interface was an API, not a browser. The business model was SaaS.&lt;/p&gt;

&lt;p&gt;Meanwhile, Big Tech legitimized email aliasing for consumers. Apple launched &lt;strong&gt;Hide My Email&lt;/strong&gt; in 2021 — unlimited random addresses forwarding to your real inbox, $0.99/month with iCloud+. Mozilla launched &lt;strong&gt;Firefox Relay&lt;/strong&gt;. Proton acquired &lt;strong&gt;SimpleLogin&lt;/strong&gt; in 2022. The concept Spamgourmet pioneered in 2000 became a first-party feature in every major ecosystem.&lt;/p&gt;

&lt;p&gt;By 2024, the disposable email market was valued at $1.36 billion, growing at 11% annually, projected to hit $3.53 billion by 2033.&lt;/p&gt;

&lt;h2&gt;
  
  
  Era 3: AI Agents (2025-present)
&lt;/h2&gt;

&lt;p&gt;The user changed again. It's no longer a human avoiding spam or a QA team testing workflows. It's an autonomous AI agent that needs an email address to complete a task.&lt;/p&gt;

&lt;p&gt;The trigger was OpenClaw launching in late January 2026. Suddenly, hundreds of thousands of persistent AI agents were running on VPSes, browsing the web, signing up for services, and hitting the same wall: registration forms that require email verification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AgentMail&lt;/strong&gt; raised $6 million in March 2026 to build persistent email identities for agents. Founded by an ex-Optiver quant, an ex-NVIDIA autonomous vehicles engineer, and an ex-Accel investor. General Catalyst led the round. Paul Graham and Dharmesh Shah (HubSpot CTO) are angels. Their user count tripled when OpenClaw launched, quadrupled in February.&lt;/p&gt;

&lt;p&gt;The defining moment from their blog: autonomous agents started signing up for AgentMail on their own — finding it through web search, navigating to the site, and creating inboxes without a developer in the loop. AgentMail built &lt;code&gt;agent.email&lt;/code&gt; — a landing page designed not for humans but for agents to self-provision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KeyID&lt;/strong&gt; took a different approach — free email, phone, and SMS infrastructure for agents. Ed25519 keypair auth instead of API keys. MCP server with 47 tools. Free at 1,000 accounts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://agentburner.com" rel="noopener noreferrer"&gt;Agent Burner&lt;/a&gt; is essentially temp-mail.org for agents — no account, no API key, just HTTP. A single POST creates a disposable inbox that auto-expires in an hour. URLs are pre-extracted from incoming emails so the agent doesn't parse HTML. The same need Mailinator solved for humans in 2003, but now the user types &lt;code&gt;curl&lt;/code&gt; instead of visiting a website.&lt;/p&gt;

&lt;h2&gt;
  
  
  The throughline
&lt;/h2&gt;

&lt;p&gt;Every era of disposable email solves the same problem for a different user.&lt;/p&gt;

&lt;p&gt;2003: A human needs to register for a website without getting spammed. They visit Mailinator in a browser and type an address.&lt;/p&gt;

&lt;p&gt;2013: A QA team needs to test a signup flow in CI. They call an API to create an inbox, run the test, and check for the verification email programmatically.&lt;/p&gt;

&lt;p&gt;2026: An autonomous agent needs to sign up for a service at 3am without human intervention. It creates an inbox via HTTP, fills a registration form in Turkish, receives a verification email, extracts the link, and deletes the inbox. The address existed for four minutes.&lt;/p&gt;

&lt;p&gt;The throughline: something needs a real email address for a task, but doesn't want to keep it. The technology barely changed. A disposable email service in 2026 does the same thing Mailinator did in 2003 — receive an email and let someone read it. What changed is who's reading it, and why.&lt;/p&gt;

&lt;p&gt;Paul Tyma built Mailinator because his drunk roommate had an idea. Josh built Spamgourmet and maintained it until he couldn't anymore. Devon Hillard built 10 Minute Mail to learn a framework. The Go-Guerrilla team built their own SMTP server because Sendmail was too bloated. Guerrilla Mail has processed twenty billion emails without venture funding.&lt;/p&gt;

&lt;p&gt;Disposable email is a category that keeps getting reinvented because the problem never goes away. Someone always needs an address they don't plan to keep.&lt;/p&gt;

</description>
      <category>email</category>
      <category>ai</category>
      <category>agents</category>
    </item>
    <item>
      <title>The 6,000-Line Email Parser</title>
      <dc:creator>Jose</dc:creator>
      <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/agentburner/the-6000-line-email-parser-3lj3</link>
      <guid>https://dev.to/agentburner/the-6000-line-email-parser-3lj3</guid>
      <description>&lt;p&gt;There's a developer in Tallinn, Estonia named Andris Reinman who, over the course of a decade, built the entire Node.js email ecosystem. Nodemailer for sending. Mailparser for parsing. WildDuck for IMAP. ZoneMTA for outbound delivery. Plus the half-dozen libraries underneath them — libmime, libqp, libbase64, mailsplit — each handling one piece of what turns out to be an insanely complex problem.&lt;/p&gt;

&lt;p&gt;Mailparser alone gets 75 million downloads a year. 56,000 repositories depend on it. And most developers who use it have no idea what's actually happening inside.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why email parsing is hard
&lt;/h2&gt;

&lt;p&gt;Email looks simple from the outside. A sender, a subject, a body. Maybe an attachment. How hard can it be to parse that?&lt;/p&gt;

&lt;p&gt;The answer is: email is not a format. It's an archaeological dig through 40 years of overlapping RFCs, vendor extensions, and broken implementations that all somehow still need to work together.&lt;/p&gt;

&lt;p&gt;A single email can contain multiple nested content types. A &lt;code&gt;multipart/mixed&lt;/code&gt; wrapping a &lt;code&gt;multipart/alternative&lt;/code&gt; wrapping a &lt;code&gt;multipart/related&lt;/code&gt; wrapping a &lt;code&gt;message/rfc822&lt;/code&gt; — which is an email inside an email, with its own multipart structure. The parser has to maintain a tree with arbitrary nesting depth.&lt;/p&gt;

&lt;p&gt;Each part can be encoded differently. Base64, quoted-printable, 7bit, 8bit. And each part can be in a different character set. UTF-8, ISO-8859-1, Windows-1252, Shift_JIS, EUC-JP, ISO-2022-JP, KS_C_5601-1987, Big5. A base64-encoded Shift_JIS body part requires two sequential decoding steps — first strip the base64, then convert the charset. The order matters.&lt;/p&gt;

&lt;p&gt;Headers use their own encoding scheme. RFC 2047 encoded-words let you stick any charset and encoding into a header value: &lt;code&gt;=?charset?encoding?text?=&lt;/code&gt;. The charset and encoding can vary word-by-word within a single header line. Some senders put encoded email addresses inside the display name field. Some encode the address itself. Some do both wrong.&lt;/p&gt;

&lt;p&gt;And then there's the stuff that isn't in any RFC. Priority headers come in four different non-standard flavors (&lt;code&gt;X-Priority&lt;/code&gt;, &lt;code&gt;X-MSMail-Priority&lt;/code&gt;, &lt;code&gt;Importance&lt;/code&gt;, &lt;code&gt;Priority&lt;/code&gt;) with both numeric and text values. Date formats vary wildly, and invalid dates are common. Missing Content-Type headers are supposed to default to &lt;code&gt;text/plain&lt;/code&gt;, unless there's a Content-Disposition header saying it's an attachment, in which case it's &lt;code&gt;application/octet-stream&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is what Andris Reinman's parser handles. All of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture
&lt;/h2&gt;

&lt;p&gt;Mailparser is built as a pipeline of Node.js Transform streams. Raw bytes go in one end, structured objects come out the other.&lt;/p&gt;

&lt;p&gt;The first stage is &lt;code&gt;mailsplit&lt;/code&gt; — a state machine that detects MIME boundary lines and splits the email into a tree of nodes. It tracks parent boundaries so it knows when a child multipart ends versus when a parent ends. The boundary detection is done byte-by-byte, not string-by-string, to avoid charset issues.&lt;/p&gt;

&lt;p&gt;Each node gets its own decoder pipeline. If the content is base64-encoded, it flows through a base64 decoder. If it's quoted-printable, through a QP decoder. Then through a charset decoder — iconv-lite for most encodings, but a dedicated Japanese decoder for ISO-2022-JP because that encoding is stateful and can't be decoded in a streaming fashion. The Japanese decoder has to buffer the entire body before converting.&lt;/p&gt;

&lt;p&gt;If the content uses &lt;code&gt;format=flowed&lt;/code&gt; (RFC 3676), there's another Transform stream in the chain that unwraps soft line breaks. Each concern is a separate stream, composed together only when needed. The main parser stays clean.&lt;/p&gt;

&lt;p&gt;The header parsing happens in &lt;code&gt;libmime&lt;/code&gt; — a library that's essentially a collection of RFC implementations. RFC 2047 for encoded-word decoding. RFC 2231 for parameter continuation (when a filename is too long for one header line). A state machine for parsing &lt;code&gt;key=value&lt;/code&gt; pairs out of Content-Type and Content-Disposition headers. Line folding and unfolding. MIME type to file extension mapping.&lt;/p&gt;

&lt;p&gt;The whole thing is about 2,500 lines across the core parser and mailsplit, plus another 1,000 in libmime, plus the streaming decoders. The total across all sub-libraries is roughly 6,000 lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  The clever bits
&lt;/h2&gt;

&lt;p&gt;A few things in the codebase that I found genuinely elegant.&lt;/p&gt;

&lt;p&gt;When the parser encounters an attachment, it emits the attachment as an event and then &lt;em&gt;pauses&lt;/em&gt;. The consumer has to explicitly call &lt;code&gt;attachment.release()&lt;/code&gt; when it's done reading the attachment stream. Only then does the parser continue. This is cooperative scheduling — it prevents the parser from racing ahead and mixing up node contexts while the consumer is still reading attachment bytes. Simple and correct.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;StreamHash&lt;/code&gt; class is a Transform stream that computes an MD5 hash and byte count as data flows through it. The attachment's &lt;code&gt;content&lt;/code&gt; property IS the StreamHash instance — consumers read decoded content from it while it silently computes the checksum. No extra buffering, no second pass.&lt;/p&gt;

&lt;p&gt;The address decoder handles a real-world edge case where an email's display name is actually a base64-encoded string containing an email address. The parser detects this, decodes it, re-parses it with the address parser, and splices the corrected entries back into the address list. It uses a WeakSet to track already-processed entries and prevent infinite loops from the same array being modified during iteration.&lt;/p&gt;

&lt;p&gt;The charset normalizer strips all non-alphanumeric characters before comparison — so &lt;code&gt;UTF-8&lt;/code&gt;, &lt;code&gt;utf8&lt;/code&gt;, &lt;code&gt;UTF-8&lt;/code&gt;, and &lt;code&gt;utf-8&lt;/code&gt; all resolve to the same thing. And &lt;code&gt;KS_C_5601-1987&lt;/code&gt; silently remaps to CP949, because that's what Korean email clients actually mean when they say &lt;code&gt;KS_C_5601-1987&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it's streaming
&lt;/h2&gt;

&lt;p&gt;The most obvious question: why not just load the whole email into memory and parse it?&lt;/p&gt;

&lt;p&gt;Memory. A production email server processes millions of messages. An email with large attachments can be 100MB+. The streaming architecture processes chunks as they arrive — attachment content flows through the pipeline and out to consumers without ever being fully buffered.&lt;/p&gt;

&lt;p&gt;There's also a &lt;code&gt;setImmediate()&lt;/code&gt; between processing lines to yield to the event loop. This prevents a large email from blocking the event loop for extended periods. On a server handling thousands of concurrent connections, this is the difference between responsive and frozen.&lt;/p&gt;

&lt;p&gt;The pipeline also respects Node.js backpressure throughout. When any stage returns &lt;code&gt;false&lt;/code&gt; from &lt;code&gt;write()&lt;/code&gt;, the previous stage waits for &lt;code&gt;drain&lt;/code&gt;. This propagates all the way back to the network socket. The parser processes data exactly as fast as the slowest consumer can handle it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The maintainer
&lt;/h2&gt;

&lt;p&gt;Andris Reinman is the sole npm maintainer of mailparser, nodemailer, and all the sub-libraries. He built the commercial product EmailEngine on top of this stack. The mailparser README now says it's in maintenance mode — security updates and critical bug fixes only. He recommends PostalMime for new projects, which works in both Node.js and browsers.&lt;/p&gt;

&lt;p&gt;62 contributors over the library's lifetime, but the architecture and the bulk of the code is one person's work. 2 million weekly downloads. The latest release is from March 2026.&lt;/p&gt;

&lt;p&gt;There's something worth sitting with about the fact that a single developer in Estonia built the email parsing infrastructure that tens of thousands of Node.js applications rely on. Not a team. Not a company. One person who understood the problem deeply enough to decompose it into composable stream transforms and got every edge case right.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;If you parse email in Node.js, you're almost certainly using Andris Reinman's code, directly or transitively. The next time you call &lt;code&gt;simpleParser()&lt;/code&gt; and get back a clean object with &lt;code&gt;text&lt;/code&gt;, &lt;code&gt;html&lt;/code&gt;, and &lt;code&gt;attachments&lt;/code&gt;, remember that underneath it, a state machine is splitting MIME boundaries byte-by-byte, a charset decoder is converting KS_C_5601-1987 to CP949, a base64 decoder is managing 3-byte alignment at chunk boundaries, and a WeakSet is preventing infinite loops in re-parsed address fields.&lt;/p&gt;

&lt;p&gt;It's 6,000 lines because email is 6,000 lines of edge cases. And one person wrote them all. You can read the source at &lt;a href="https://github.com/nodemailer/mailparser" rel="noopener noreferrer"&gt;nodemailer/mailparser&lt;/a&gt; and follow Andris Reinman's work on &lt;a href="https://github.com/andris9" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>node</category>
      <category>email</category>
      <category>parsing</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
