npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

maildev

v3.0.0

Published

SMTP Server and Web Interface for reading and testing emails during development

Readme

MailDev

npm npm downloads Docker Pulls License TypeScript

[!IMPORTANT] MailDev 3.0 release candidate has now been released which includes a complete re-write and re-structuring of the entire project. If you run into any issues, please install the latest v2 release.

MailDev is a simple way to test your project's generated email during development, with an easy to use web interface that runs on your machine built on top of Node.js.

MailDev Screenshot

Install

npm install -g maildev

Docker Run

If you want to use MailDev with Docker, you can use the maildev/maildev image on Docker Hub. For a guide for usage with Docker, checkout the docs.

docker run -p 1080:1080 -p 1025:1025 maildev/maildev

Usage

Usage: maildev [options]

| Options | Environment variable | Description | | -------------------------------- | -------------------------- | ----------------------------------------------------------------------------------------- | | -s, --smtp <port> | MAILDEV_SMTP_PORT | SMTP port to catch mail (default: 1025) | | -w, --web <port> | MAILDEV_WEB_PORT | Port to run the Web GUI (default: 1080) | | --ip <ip address> | MAILDEV_IP | IP Address to bind SMTP service to (default: ::) | | --web-ip <ip address> | MAILDEV_WEB_IP | IP Address to bind HTTP service to (default: 0.0.0.0) | | --mail-directory <path> | MAILDEV_MAIL_DIRECTORY | Directory for persisting mail | | --max-emails <count> | MAILDEV_MAX_EMAILS | Maximum emails to keep; oldest are discarded with their files (default: 0 = unlimited) | | --https | MAILDEV_HTTPS | Switch from http to https protocol | | --https-key <file> | MAILDEV_HTTPS_KEY | The file path to the ssl private key | | --https-cert <file> | MAILDEV_HTTPS_CERT | The file path to the ssl cert file | | --incoming-user <user> | MAILDEV_INCOMING_USER | SMTP user for incoming mail | | --incoming-pass <pass> | MAILDEV_INCOMING_PASS | SMTP password for incoming mail | | --incoming-secure | MAILDEV_INCOMING_SECURE | Use SMTP SSL for incoming emails | | --incoming-cert <path> | MAILDEV_INCOMING_CERT | Cert file location for incoming SSL | | --incoming-key <path> | MAILDEV_INCOMING_KEY | Key file location for incoming SSL | | --outgoing-host <host> | MAILDEV_OUTGOING_HOST | SMTP host for outgoing mail | | --outgoing-port <port> | MAILDEV_OUTGOING_PORT | SMTP port for outgoing mail | | --outgoing-user <user> | MAILDEV_OUTGOING_USER | SMTP user for outgoing mail | | --outgoing-pass <password> | MAILDEV_OUTGOING_PASS | SMTP password for outgoing mail | | --outgoing-secure | MAILDEV_OUTGOING_SECURE | Use SMTP SSL for outgoing mail | | --auto-relay [email] | MAILDEV_AUTO_RELAY | Use auto-relay mode. Optional relay email address | | --auto-relay-rules <file> | MAILDEV_AUTO_RELAY_RULES | Filter rules for auto relay mode | | --web-user <user> | MAILDEV_WEB_USER | HTTP user for GUI | | --web-pass <password> | MAILDEV_WEB_PASS | HTTP password for GUI | | --base-pathname <path> | MAILDEV_BASE_PATHNAME | Base path for URLs | | --disable-web | MAILDEV_DISABLE_WEB | Disable the use of the web interface | | --hide-extensions <extensions> | MAILDEV_HIDE_EXTENSIONS | Comma separated list of SMTP extensions to NOT advertise | | --max-message-size <bytes> | MAILDEV_MAX_MESSAGE_SIZE | Max accepted message size in bytes; larger messages are rejected. 0 disables (default: 52428800) | | --mcp | MAILDEV_MCP | Enable MCP server for Claude integration | | --config <file> | | Path to configuration file | | -v, --verbose | | Enable verbose logging | | --silent | | Disable all output | | --log-mail-contents | | Log a JSON representation of each incoming mail |

Storage limit

MailDev keeps every email by default (--max-emails 0), preserving its historical behaviour and keeping persisted mail durable across restarts. Set a positive limit to cap the store: when a new email arrives and the limit is reached, the oldest is discarded — along with its .eml file and attachments, so a persisted mail directory stays bounded as well. Any backlog left in the mail directory by earlier runs is trimmed to the same limit at startup.

maildev --max-emails 1000     # keep the newest 1000
maildev --max-emails 0        # keep everything (the default)

Leaving the limit unset keeps everything. Be aware that memory use and the mail directory then grow with the inbox; with typical messages, 10,000 emails is around 150 MB of heap, so set a limit for long-running or high-volume use.

Configuration File

MailDev supports configuration files. Create a maildev.config.js, maildev.config.ts, or .maildevrc.json file:

// maildev.config.js
export default {
  smtp: 1025,
  web: 1080,
  verbose: true,
  mcp: true,
}
// .maildevrc.json
{
  "smtp": 1025,
  "web": 1080,
  "verbose": true
}

Configuration priority: CLI args > Environment variables > Config file > Defaults

API

MailDev can be used in your Node.js application. For more info view the API docs.

import { MailDev } from 'maildev'

const maildev = new MailDev({
  smtp: 1025,
  web: 1080,
})

const { smtp } = await maildev.start()

smtp.on('new', (email) => {
  console.log('New email:', email.subject)
})

// When done
await maildev.stop()

MailDev also has a REST API. For more info view the docs.

AI Agent Integration (MCP)

MailDev includes a Model Context Protocol (MCP) server so AI agents can work with your dev inbox. It works with any MCP client — Claude (Desktop and Code), Cursor, Codex, Windsurf, and more. Enable it with --mcp:

maildev --mcp

This exposes an MCP endpoint at /mcp that lets an agent:

  • Search and retrieve emails
  • Extract verification links and tokens
  • Analyze email content
  • Monitor email delivery

For detailed setup instructions — both transports, client config, and the available tools, resources, and prompts — see the MCP docs.

Outgoing Email

MailDev optionally supports selectively relaying emails to an outgoing SMTP server. If you configure outgoing email with the --outgoing-* options you can click "Relay" on an individual email to relay through MailDev out to a real SMTP service that will actually send the email to the recipient.

Example:

maildev --outgoing-host smtp.gmail.com \
        --outgoing-secure \
        --outgoing-user '[email protected]' \
        --outgoing-pass '<pass>'

Auto Relay Mode

Enabling the auto relay mode will automatically send each email to its recipient without the need to click the "Relay" button mentioned above. The outgoing email options are required to enable this feature.

Optionally, you can specify a single email address to which MailDev will forward all emails instead of the original recipient. For example, using --auto-relay [email protected] will forward all emails to that address automatically.

Additionally, you can pass a valid json file with additional configuration for which email addresses you would like to allow or deny. The last matching rule in the array will be the rule MailDev will follow.

Example:

maildev --outgoing-host smtp.gmail.com \
        --outgoing-secure \
        --outgoing-user '[email protected]' \
        --outgoing-pass '<pass>' \
        --auto-relay \
        --auto-relay-rules file.json

Rules example file:

[
  { "allow": "*" },
  { "deny": "*@test.com" },
  { "allow": "[email protected]" },
  { "deny": "*@utah.com" },
  { "allow": "[email protected]" }
]

This would allow [email protected], [email protected], [email protected], but deny [email protected].

Configure Your Project

Configure your application to send emails via port 1025 and open localhost:1080 in your browser.

Nodemailer (Node.js)

const nodemailer = require('nodemailer')

const transport = nodemailer.createTransport({
  host: 'localhost',
  port: 1025,
})

transport.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Test Email',
  text: 'Hello from MailDev!',
})

Django -- Add EMAIL_PORT = 1025 in your settings file [source]

Rails -- config settings:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: "localhost",
  port: 1025,
  enable_starttls_auto: false
}

Spring Boot -- in application.properties:

spring.mail.host=localhost
spring.mail.port=1025

Features

  • Modern React-based web interface
  • Toggle between HTML, plain text views and email headers
  • Test responsive emails with resizable preview pane
  • Receive and view email attachments
  • Real-time updates via WebSocket
  • Relay email to an upstream SMTP server
  • MCP integration for Claude AI assistant
  • Configuration file support
  • Full TypeScript support

Ideas

If you're using MailDev and you have a great idea, I'd love to hear it. If you're not using MailDev because it lacks a feature, I'd love to hear that too. Add an issue to the repo here.

Contributing

Any help on MailDev would be awesome. There is plenty of room for improvement. Feel free to create a Pull Request.

MailDev v3 is a TypeScript monorepo using pnpm workspaces:

packages/
  core/     # Storage and shared types
  smtp/     # SMTP server
  api/      # REST API and WebSocket server
  ui/       # React web interface
  mcp/      # MCP server for Claude
  cli/      # CLI and orchestration

To run MailDev during development:

pnpm install
pnpm dev

To send test emails:

node scripts/send.js

To run the test suite:

pnpm test

Changelog

Thanks

MailDev is built using great open source projects including React, Fastify, Tailwind CSS, and two great projects from Andris Reinman: smtp-server and mailparser. Many thanks to Andris as his projects are the backbone of this app and to MailCatcher for the inspiration.

Additionally, thanks to all the awesome contributors to the project.

License

MIT