<?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: Enes</title>
    <description>The latest articles on DEV Community by Enes (@erkenes).</description>
    <link>https://dev.to/erkenes</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%2F596340%2F4e89fee6-0813-4967-8a8c-846df03ea422.jpeg</url>
      <title>DEV Community: Enes</title>
      <link>https://dev.to/erkenes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/erkenes"/>
    <language>en</language>
    <item>
      <title>Testing Emails in 2026: Why I Built a Better Mailcatcher (And Why You Should Switch)</title>
      <dc:creator>Enes</dc:creator>
      <pubDate>Sun, 26 Apr 2026 10:46:48 +0000</pubDate>
      <link>https://dev.to/erkenes/testing-emails-in-2026-why-i-built-a-better-mailcatcher-and-why-you-should-switch-5gan</link>
      <guid>https://dev.to/erkenes/testing-emails-in-2026-why-i-built-a-better-mailcatcher-and-why-you-should-switch-5gan</guid>
      <description>&lt;p&gt;We've all been there: you're developing a new feature—like a registration flow or a "forgot password" function—and you need to verify that the emails look right and contain the correct links. Using real SMTP servers during development is a hassle and comes with the constant risk of accidentally emailing real users.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with the Current Landscape
&lt;/h2&gt;

&lt;p&gt;I spent a lot of time using tools like &lt;strong&gt;MailHog&lt;/strong&gt;, &lt;strong&gt;MailCatcher&lt;/strong&gt; (dockerge/mailcatcher), and &lt;strong&gt;MailDev&lt;/strong&gt; (maildev/maildev). They were lifesavers back in the day, but they haven't kept up with modern development needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MailHog&lt;/strong&gt;: The UI feels like a relic from 2010. Plus, the project was recently abandoned - something I only realized while writing this post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MailCatcher&lt;/strong&gt;: The UI feels like a relic from 2010. Plus, The project was abandoned just a few days ago which I only recognized by writing this post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MailDev&lt;/strong&gt;: A solid Node alternative, but it often lacks the snappiness and robust disk persistence that complex local workflows require. Furthermore, the RAM usage becomes heavy when collecting a large volume of emails on testing or staging servers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I found myself wanting something &lt;strong&gt;lightweight, modern, container-friendly&lt;/strong&gt;, and - most importantly - &lt;strong&gt;persistent by default&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing: A New Mailcatcher based on Node.js
&lt;/h2&gt;

&lt;p&gt;I decided to build a fresh alternative that focuses on what actually matters to developers today. It's a Node.js-based SMTP simulator designed to be a "set it and forget it" tool for your Docker Compose stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this version is different:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Disk Persistence That Actually Works&lt;/strong&gt;: Unlike many tools that keep emails in memory (and lose them on every container restart), this project stores incoming emails directly on disk as structured files. They are automatically reloaded when the server starts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean &amp;amp; Modern UI&lt;/strong&gt;: A responsive Web UI that supports both English and German (additional languages can be added easily). It displays headers, HTML/Text content, and handles attachments properly, including downloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built for Containers&lt;/strong&gt;: Optimized for Docker and Docker Compose. No complicated setup - just a single service in your &lt;code&gt;yaml&lt;/code&gt; file. However, it can still be run standalone without Docker.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-Retention&lt;/strong&gt;: You don't have to worry about your disk filling up. You can set a &lt;code&gt;MAIL_RETENTION_DAYS&lt;/code&gt; variable, and old emails are automatically purged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI &amp;amp; API Integration&lt;/strong&gt;: Need to reload emails or check the status via the command line? There's a dedicated CLI command and a simple GET endpoint for that.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Getting Started in 60 Seconds
&lt;/h2&gt;

&lt;p&gt;The easiest way to use it is via Docker Compose. Just add this to your &lt;code&gt;docker-compose.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mailcatcher&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;erkenes/mailcatcher&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2525:2525"&lt;/span&gt; &lt;span class="c1"&gt;# SMTP Port&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt; &lt;span class="c1"&gt;# Web UI Port&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mail-data:/data/mails&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;MAIL_RETENTION_DAYS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mail-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simply point your application's SMTP settings to &lt;code&gt;localhost:2525&lt;/code&gt; (no auth required), and open &lt;code&gt;http://localhost:3000&lt;/code&gt; to see your emails arriving in real-time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features at a glance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SMTP Server&lt;/strong&gt;: Fast and reliable, no TLS/Auth hurdles for local development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attachment Support&lt;/strong&gt;: View and download files sent via email.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistent Storage&lt;/strong&gt;: Uses a UUID-based directory structure for every email.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable&lt;/strong&gt;: Change the app title, ports, and polling intervals via Environment Variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;We deserve tools that look good and work reliably. If you're tired of clunky UIs or losing your test emails every time you stop your Docker containers, give this new Mailcatcher a try.&lt;/p&gt;

&lt;p&gt;I'd love to hear your feedback! What features are you missing in your current email testing workflow?&lt;/p&gt;

&lt;p&gt;Check it out on GitHub: &lt;a href="https://github.com/erkenes/mailcatcher" rel="noopener noreferrer"&gt;https://github.com/erkenes/mailcatcher&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Docker Hub: &lt;code&gt;erkenes/mailcatcher&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;GitHub Container Registry: &lt;code&gt;ghcr.io/erkenes/mailcatcher&lt;/code&gt;&lt;/p&gt;

</description>
      <category>smtp</category>
      <category>mailcatcher</category>
      <category>docker</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
