Haraka
High-performance, pluggable SMTP server in Node.js
Haraka is a fast, highly extensible SMTP server written in Node.js. Its event-driven plugin architecture makes it well suited for custom mail handling and high-volume delivery.
Key features
- Event-driven plugin system
- Very high throughput
- Inbound and outbound handling
- JavaScript plugin development
Pros & cons
Strengths
- Highly customizable
- Excellent performance
Trade-offs
- SMTP only, no mailbox access
- Requires coding for advanced features
Haraka replaces
Last reviewed Sep 13, 2026 · 881 words
The people who run Haraka are running a mail pipeline, not a mail server. A transactional email service that needs to sign, rate-limit and route 50 messages a second per node. A SaaS that accepts inbound mail on a wildcard domain and turns each message into a ticket. A spam-filtering front door in front of an old Exchange or Postfix box. In each case somebody needed to write the logic in JavaScript and run it on every connection, and that is what Haraka is for. It has no IMAP, no mailboxes, no webmail and no user database; the catalogue's con "SMTP only" is the product description.
How it handles mail: hooks on a state machine
An SMTP session is a sequence of events (connect, helo, mail, rcpt, data, data_post, queue), and every Haraka plugin registers functions on the hooks it cares about. Each plugin returns OK, DENY, DENYSOFT or CONT to accept, reject permanently, reject temporarily or pass to the next plugin. Because everything is non-blocking, a slow DNS lookup for one connection does not stall the other 2,000, which is where the throughput reputation comes from; Haraka was written for Craigslist's inbound volume, and the architecture still shows it.
The plugins you enable, in order, are listed one per line in config/plugins. A sensible inbound edge is roughly:
dnsbl
spf
dkim_verify
rcpt_to.in_host_list
data.headers
spamassassin
queue/smtp_forward
Read top to bottom: block known-bad IPs, check SPF and DKIM, only accept recipients on domains we handle, sanity-check headers, score with SpamAssassin, then hand accepted mail to the real mailbox server over SMTP. Each plugin has a config file under config/ and most are 10 to 30 lines of plain text.
Install is npm, then a directory
npm install -g Haraka
haraka -i /opt/haraka # writes a config/ and plugins/ skeleton
haraka -c /opt/haraka # run in the foreground
Set listen=0.0.0.0:25 in config/smtp.ini, and add 587 with tls and auth plugins if clients will submit mail. Port 25 needs root or a capability grant, and a Docker container publishing 25:25 is the simplest way to get that without running Node as root. A systemd unit with Restart=always is the whole process supervision story; Haraka forks a configurable number of workers via nodes= in smtp.ini and reloads config files on change without a restart.
Outbound is a second mode: enable queue/outbound or route to it from your app, and Haraka manages a disk queue, retries with backoff, per-domain concurrency, and bounce handling. The dkim_sign plugin signs with a per-domain key from config/dkim/. This is the mode the SendGrid-replacement crowd cares about, and it works, with the usual caveat that IP reputation is the hard part of sending and no software solves it.
Writing a plugin is the reason you chose this
A plugin is a JavaScript file in plugins/ that exports functions named after hooks. Tagging every inbound message from one sender and pushing it to a webhook is about 15 lines:
exports.register = function () {
this.register_hook('data_post', 'flag_vendor');
};
exports.flag_vendor = function (next, connection) {
const txn = connection.transaction;
const from = txn.mail_from.address();
if (from.endsWith('@vendor.example.com')) {
txn.add_header('X-Vendor-Mail', 'yes');
txn.notes.forward_to_webhook = true;
}
next();
};
Anything Node can do, a plugin can do at any point in the session: look up a recipient in your Postgres, reject on a per-customer quota, rewrite addresses, or mirror the raw message to S3. Postfix can be extended too, but through milters and policy daemons in separate processes; Haraka's advantage is that the extension point is the same language and process as the server.
What Haraka is not, and what to run alongside it
For a personal mail domain you want a whole mail system: SMTP in and out, IMAP, spam filtering, DKIM, DMARC reports, a webmail, and an admin UI. Stalwart does all of that in one binary and is the bigger, safer pick in the email category for anyone whose goal is "my own mailbox"; the honest self-hosted email post covers whether that goal is wise. Haraka in that setup is either absent or a smart edge in front of Dovecot, handing accepted mail off over LMTP or SMTP.
Choose Haraka when the mail is data, not correspondence: inbound parsing at volume, outbound sending with custom rules, or a filtering edge with logic no Postfix config file can express. Choose it over a SendGrid subscription only if you can also own IP warmup, feedback loops and blocklist monitoring, because those are the services you are actually paying them for.
What I'd do
Personal mailbox: Stalwart, not Haraka. Inbound-mail-as-data pipeline or a custom outbound sender with a developer on staff: Haraka on a 512 MB VPS with the plugin list above, a systemd unit, a separate server for anything with a mailbox, and an afternoon reading the plugin docs before writing your first hook. Start it in the foreground with haraka -c, watch the log for one real message end to end, and only then put it on port 25 for a domain you care about.
Compare Haraka
3 head-to-head comparisons.
Similar mail servers apps
listmonk
Mail ServersSelf-hosted newsletter and mailing list manager
Replaces Mailchimp, Sendinblue
Docker Mailserver
Mail ServersProduction-ready, config-driven mail server in a container
Replaces Google Workspace, Microsoft 365
Mailspring
Mail ServersCross-platform desktop email client
Replaces Outlook, Apple Mail
Postal
Mail ServersComplete mail delivery platform for outgoing email
Replaces SendGrid, Mailgun
MailHog
Mail ServersEmail testing tool with a fake SMTP server
Replaces Mailtrap
Mail-in-a-Box
Mail ServersTurn a fresh server into a working mail server
Replaces Google Workspace, Microsoft 365