go-smtp

An ESMTP client and server library for Go, implementing RFC 5321 plus AUTH, LMTP, and modern mail extensions.

Library
Go
vv0.25.0
2,043stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
68/100Good
Development Activity60
Maintenance40
Community72
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture82
Code Quality85
Innovation78
Learning Curve65

go-smtp is a Go library that implements the Simple Mail Transfer Protocol end to end: an ESMTP client for sending mail and a full ESMTP/LMTP server implementation for receiving it. It exists because the Go standard library’s net/smtp is frozen and client-only, so any project that needs a real SMTP server, or client features beyond the basics, has to look elsewhere.

On the server side, consumers implement a small Backend/Session interface pair to plug in their own mail storage or routing logic, while go-smtp handles the protocol state machine, line parsing, error codes, and optional extensions (STARTTLS, AUTH via SASL, DSN, CHUNKING/BINARYMIME, SMTPUTF8, and more). The client mirrors this with a Dial/Client API for connecting, authenticating, and streaming a message body without buffering it entirely in memory.

It is maintained by emersion, the author of several widely used Go mail and IMAP libraries, and is used as the SMTP layer inside real mail servers and mail-handling tools rather than as a toy example implementation.

What You Get

  • An ESMTP client (Client, Dial, DialTLS, DialStartTLS) for connecting, authenticating via SASL, and streaming message bodies to a remote server
  • A pluggable ESMTP server (Server, Backend, Session) where you implement mail handling and go-smtp handles the RFC 5321 command loop
  • LMTP (RFC 2033) support via the same server, for per-recipient delivery status reporting through the optional LMTPSession/StatusCollector interfaces
  • Extension support for AUTH, STARTTLS, PIPELINING, 8BITMIME, BINARYMIME/CHUNKING, DSN, SMTPUTF8, DELIVERBY, MT-PRIORITY, and RRVS, each toggled independently on Server
  • Structured SMTP error values (SMTPError with numeric code, enhanced code, and message) instead of opaque strings, usable from both client and server code

Common Use Cases

  • Building a custom mail server or mail-relay component that needs full control over how incoming messages are accepted, validated, and stored
  • Implementing LMTP delivery between a mail transfer agent and a local delivery agent, with per-recipient status reporting
  • Adding outbound SMTP submission with SASL authentication to a Go application, beyond what the frozen net/smtp package supports
  • Prototyping or testing SMTP-speaking services locally, including the bundled smtp-debug-server command for inspecting raw client traffic

Under The Hood

Architecture go-smtp separates cleanly into a server half and a client half that share only low-level plumbing (net/textproto, SASL, error types). On the server side, Server owns the listener accept loop and per-connection bookkeeping (server.go), handing each connection to a Conn (conn.go) that runs the RFC 5321 command state machine: it wraps the raw connection in a line-limited reader, parses commands via parse.go, and dispatches them to a library-supplied Backend/Session implementation (backend.go). Extension behavior (LMTP status collection, BDAT chunking via an io.Pipe, dot-stuffed DATA streaming through a custom dataReader in data.go) is layered on top of this core loop rather than baked into it, so a minimal backend only needs to implement Reset/Logout/Mail/Rcpt/Data, while optional interfaces (LMTPSession, AuthSession) add capability without forcing every implementer to support it. The client (client.go) is a largely independent RFC 5321 implementation reusing the same textproto and SMTPError types, decoupled from the server’s Conn/Backend machinery.

Tech Stack The library has a single external dependency, github.com/emersion/go-sasl, for SASL authentication mechanisms; everything else is Go standard library (net, crypto/tls, net/textproto, bufio, encoding/base64). go.mod targets Go 1.13, favoring broad compatibility over newer language features. There is no web framework, database, or build tooling beyond go build/go test; CI runs on sourcehut (.build.yml) rather than GitHub Actions, executing race-detector builds and tests with coverage reporting plus a gofmt formatting check. A small cmd/smtp-debug-server binary ships alongside the library for manual protocol inspection.

Code Quality Testing is extensive relative to the library’s size: client_test.go and server_test.go are each larger than the production code they cover, with additional dedicated coverage for LMTP (lmtp_server_test.go) and command parsing (parse_test.go), plus runnable Example* functions that double as documentation. CI runs the full suite with the race detector and tracks coverage, and enforces gofmt formatting on every build. Errors are consistently typed via SMTPError (numeric code, RFC 2034 enhanced code, message) rather than ad hoc strings, used uniformly across client and server. There is no separate linter configuration beyond gofmt, and the test suite relies on the standard library’s testing package without an assertion framework, which is idiomatic for Go but means less structured failure output than table-driven frameworks with custom matchers.

API Design The Backend/Session split is the core design decision: it lets applications own mail storage and routing while go-smtp owns protocol correctness, and optional interfaces (AuthSession for AUTH, LMTPSession for per-recipient LMTP status) are additive so simple backends stay simple. The extension surface is unusually broad for a Go SMTP library — most alternatives cover only basic ESMTP, while go-smtp also implements LMTP, DELIVERBY, MT-PRIORITY, and RRVS, extensions rarely found outside MTA-grade software. Combined with the frozen, client-only state of the standard library’s net/smtp, this makes go-smtp one of the few Go options for building a real SMTP server rather than only a client.

Used by 8 apps in this directory

Go
75%
AGPL 3.0

Coder

Devops · Developer Tools · Code Editors

14,299

Self-hosted cloud development environments and AI coding agents — defined in Terraform, connected via WireGuard, automatically shut down when idle.

View details
93
Repo Health
90
Technical
69
Dependency
Built with
Go75%
TypeScript23%
Updated today
Go
43%
Apache 2.0

e2a

AI Agents · Automation

184

Give your AI agents a real, authenticated email address — with SPF/DKIM-verified inbound, HMAC-signed delivery, WebSocket fan-out, and human-in-the-loop approval built in.

View details
78
Repo Health
80
Technical
74
Dependency
Built with
Go43%
TypeScript28%
Python14%
Updated today
Go
84%
MIT

Hatchet

AI Development · Developer Tools · Automation

7,812

A Postgres-backed orchestration engine for background tasks, AI agents, and durable workflows that replaces Redis queues and multi-datastore durable execution platforms with a single self-hostable service.

View details
88
Repo Health
83
Technical
68
Dependency
Built with
Go84%
PLpgSQL11%
Updated today
PHP
63%
AGPL 3.0

Hyvor Relay

Devops · AI Development · Monitoring

879

Self-hosted, open-source email API that automates DNS, manages SMTP delivery, and provides deep observability — replacing SES, Mailgun, and SendGrid with infrastructure you fully own.

View details
67
Repo Health
79
Technical
70
Dependency
Built with
PHP63%
Svelte23%
Go12%
Updated 4 days ago
Go
74%
Other

Notifuse

Marketing

2,089

Open-source, self-hosted alternative to Mailchimp, Brevo, and Klaviyo — send newsletters and transactional emails without per-email pricing or vendor lock-in.

View details
83
Repo Health
80
Technical
66
Dependency
Built with
Go74%
TypeScript23%
Updated yesterday
Go
73%
Apache 2.0

ntfy

Developer Tools · Marketing

33,850

Send push notifications to your phone or desktop from any script or service using a single HTTP PUT or POST—no sign-up required.

View details
89
Repo Health
89
Technical
76
Dependency
Built with
Go73%
JavaScript26%
Updated 3 days ago
TypeScript
52%
Other

SigNoz

Monitoring · Analytics

31,972

Self-host your entire observability stack — logs, metrics, traces, and LLM monitoring — in one OpenTelemetry-native platform, without the Datadog bill.

View details
92
Repo Health
83
Technical
69
Dependency
Built with
TypeScript52%
Go37%
Updated today
Go
78%
MIT

Wakapi

Developer Tools · Analytics

4,413

Self-hosted WakaTime-compatible coding statistics backend that gives developers full control over their coding activity data.

View details
89
Repo Health
77
Technical
73
Dependency
Built with
Go78%
HTML12%
Updated 3 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search