GreenMail
Local SMTP+IMAP email server for Elixir dev/test environments. Wraps GreenMail — catches all outbound email at the SMTP level. No emails leave your machine. Ever.
Why not Swoosh.Adapters.Local?
Because it only catches emails sent through Swoosh. If your app talks SMTP directly (a SmtpClient, a background mailer, a third-party library), Swoosh.Local never sees those messages. GreenMail catches everything — it's a real SMTP server listening on localhost.
Setup
1. Add dependency
# mix.exs
defp deps do
[
{:greenmail, "~> 0.1", only: :dev}
]
end
2. Install the JAR
mix greenmail.install
Downloads greenmail-standalone.jar to ~/.greenmail/. One download, shared by all projects.
Requires: Java 17+ (brew install openjdk on macOS)
3. Add to supervision tree (dev only)
# application.ex
def start(_type, _args) do
children = [
# ... your children ...
] ++ greenmail_children()
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
defp greenmail_children do
if Application.get_env(:my_app, :greenmail, false) do
[{GreenMail.Server, [supervisor: MyApp.Supervisor]}]
else
[]
end
end
# config/dev.exs
config :my_app, greenmail: true
4. Point SMTP at GreenMail
Any SMTP config pointing at localhost:3025 will be caught. For IMAP ingestion, use localhost:3143.
Auth is disabled — any username/password works and auto-provisions a mailbox for that address.
API
GreenMail.running?() # => true
GreenMail.status() # => {:ok, %{smtp_port: 3025, imap_port: 3143, os_pid: 12345, ...}}
GreenMail.stop() # Stop server, free ports
GreenMail.start() # Restart after stop
GreenMail.restart() # Flush all mailboxes
Ports
| Protocol | Port |
|---|---|
| SMTP | 3025 |
| IMAP | 3143 |
How it works
- GenServer starts GreenMail JAR as an Erlang port process
- Java process dies when your app dies — no orphans
- Per-address mailboxes: email to
alice@example.comlands in that IMAP inbox - In-memory only: emails vanish on restart
- If ports are already in use, assumes external mail server and skips startup
Reading caught emails
Use any IMAP client. From Elixir, you can use :gen_smtp or Mail:
# The email sent to alice@example.com is in that address's IMAP inbox
# Login: alice@example.com / any-password
# Host: localhost, Port: 3143, SSL: off
Or just use a mail client (Thunderbird, etc.) pointed at localhost:3143.
License
MIT