Welcome to EmitMail
Self-hosted email sending and inbound mailbox software for engineering teams.
1. What is EmitMail?
EmitMail is self-hosted software for sending email and receiving messages into mailboxes you manage. It uses Node.js, TypeScript, PostgreSQL, Redis, and BullMQ. You operate the server, DNS, IP reputation, and mail delivery configuration.
┌────────────────────────────────────────────────────────┐
│ EmitMail ESP │
├────────────────────────────┬───────────────────────────┤
│ Outbound Engine │ Inbound Engine │
├────────────────────────────┼───────────────────────────┤
│ • 2048-bit RSA DKIM Keys │ • ESMTP Port 25 Receiver │
│ • SPF / Return-Path Setup │ • Alias & Catch-all Mail │
│ • BullMQ Worker Pipeline │ • Real-time Webhooks │
│ • Resend SDK Drop-In │ • In-Dashboard Reader/Sent│
└────────────────────────────┴───────────────────────────┘Resend SDK support
The official resend Node.js package can be configured to send requests to EmitMail. Check the SDK guide for the required base URL option and review the API features you use before migrating.
2. Core Architecture & Processing Flow
EmitMail queues accepted API requests in Redis so background workers can perform DNS lookup, DKIM signing, and SMTP delivery. Queue acceptance does not mean the receiving mail server has accepted or delivered the message.
Outbound Dispatch Pipeline
[ Client App / SDK ]
│
▼ (POST /emails with Bearer em_live_...)
[ EmitMail Express API ] ──► Return a queued email ID
│
▼ (Enqueue Job: email-delivery-queue)
[ Redis 7 + BullMQ ]
│
▼ (Distributed Job Consumption)
[ EmitMail Worker Engine ]
│
├─► [ PostgreSQL ] : Tenant suppression list check & domain verification
├─► [ Crypto Subsystem ] : Signs raw MIME payload with 2048-bit RSA DKIM private key
├─► [ DNS Resolver ] : Queries remote MX records for recipient domain
▼
[ Direct MX Dispatch ] ──(SMTP / Port 25)──► [ Recipient's mail server ]
│
▼ (Delivery or Bounce Event)
[ Webhook Dispatcher ] ──► [ Your Backend Server ]Inbound Ingestion Pipeline
[ External Sender (e.g. Gmail) ]
│
▼ (Port 25 TCP Connection)
[ Docker Compose host-port mapping: 25 -> container 2525 ]
│
▼
[ EmitMail Inbound SMTP Server (smtp-server) ]
│
├─► [ onRcptTo Hook ] : Validates active mailbox (exact alias or catch-all *)
▼
[ Redis Queue (inbound-email) ]
│
▼
[ Inbound BullMQ Worker ]
│
├─► [ mailparser ] : Parses MIME body, extracts HTML/text & attachments
├─► [ PostgreSQL ] : Stores thread in Inbox for dashboard viewing
▼
[ Webhook Dispatcher ] ──► HTTP POST webhook event (inbound.email.received)3. Key Features
Resend Node.js SDK
Configure the official Node.js SDK to use your EmitMail server. Review supported API behavior before migrating.
Email DNS setup
Review the DKIM, SPF, MX, and DMARC records required by your server configuration. DNS records do not guarantee inbox placement.
Inbound Mailbox Engine (/inbox)
Configure mailbox aliases, receive messages, and reply from the dashboard.
Cryptographic Webhook Telemetry
Receive signed HMAC-SHA256 webhooks for email.delivered, email.bounced, email.complaint, and inbound.email.received.