TEST EVERY EMAIL WITHOUT SENDING ONE.
Build, inspect and test email workflows locally, then stream large attachments without buffering the complete file in memory.
HOW MAILPORT WORKS
A stream-first workflow that converts email payloads into deterministic MIME pipelines and streams chunks straight to network sockets or local test inboxes.
SEND
Construct email payloads with type-safe interfaces (`from`, `to`, `subject`, `attachments`). Payloads bypass disk temporary buffering.
ROUTE
The RFC 5322 engine streams base64 and quoted-printable chunks iteratively through
AsyncIterable<Uint8Array> bounds.
DELIVER
Clean single-connection lifecycle delivers message bytes into remote SMTP sockets or traps them in `InMemoryInbox` for testing.
TYPE-SAFE & DEPLOYMENT READY
Designed for Node.js 22+, TypeScript strict mode, Vitest, Jest, Express, Fastify, and Next.js Route Handlers with zero runtime dependencies in `@mailport/core`.
import { createMailer, smtp } from 'mailport';
// Initialize MailPort SMTP Transport
const mailer = createMailer({
transport: smtp({
host: 'smtp.example.com',
port: 587,
tls: 'starttls',
auth: { user: 'app@internal', pass: 'secret' },
}),
});
// Send Email with Bounded Attachment Streaming
const result = await mailer.send({
from: 'App <noreply@domain.com>',
to: 'user@domain.com',
subject: 'Quarterly Analytics Report',
text: 'Attached is your generated report.',
attachments: [{ filename: 'report.pdf', path: './report.pdf' }],
});
console.log(result.status); // 'accepted'
BOUNDED-MEMORY ATTACHMENT STREAMING
Conventional email engines buffer full attachment files into Node ArrayBuffers, causing severe heap spikes. MailPort streams chunks progressively, keeping peak heap memory under sublinear bounds even on 500 MB attachments.
LEARN STREAMING ARCHITECTUREMedian peak heap memory consumed during continuous 500 MB attachment MIME processing in benchmark tests.
ZERO-NETWORK VITEST & JEST TESTING
Stop wrestling with flaky SMTP test mocks or local Docker containers. MailPort provides built-in `InMemoryTransport` and `TestMailer` to inspect sent messages synchronously in Vitest or Jest at 0ms socket latency.
EXPLORE TESTING UTILITIESSynchronous in-memory inbox trapping with helper matchers like `expect(inbox).toHaveSentEmail()`.
TEST MAILPORT IN YOUR BROWSER
Simulate MIME creation, inbox trapping, and executable TypeScript code generation in real time.
Date: Tue, 11 Aug 2026 08:00:00 GMT
Message-ID: <msg_99812@relay.internal>
From: sender@example.com
To: recipient@example.com
Subject: Welcome to MailPort
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_Part_MailPort_88912"
------=_Part_MailPort_88912
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
Hello from MailPort streaming engine!
------=_Part_MailPort_88912
Content-Type: application/pdf; name="sample.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="sample.pdf"
JVBERi0xLjQKJ... [128 KB Streamed Chunk Data Base64]
------=_Part_MailPort_88912--
{
"id": "<msg_99812@relay.internal>",
"status": "accepted",
"from": "sender@example.com",
"to": ["recipient@example.com"],
"subject": "Welcome to MailPort",
"text": "Hello from MailPort streaming engine!",
"attachmentsCount": 1,
"deliveredAt": "2026-08-11T08:00:00.000Z"
}
import { createMailer, smtp } from 'mailport';
const mailer = createMailer({
transport: smtp({ host: 'smtp.example.com' }),
});
const result = await mailer.send({
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'Welcome to MailPort',
text: 'Hello from MailPort streaming engine!',
attachments: [{ filename: 'sample.pdf', path: './sample.pdf' }],
});
MODULAR ECOSYSTEM PACKAGES
Use the umbrella `mailport` wrapper or import standalone modular packages for core, MIME, SMTP, or testing primitives.
mailport
Main umbrella entry point combining core mailer, SMTP transport, and testing matchers.
pnpm add mailport
@mailport/core
Core interfaces, clock provider, ID generators, and message validation rules.
pnpm add @mailport/core
@mailport/mime
RFC 5322 MIME builder with base64 and quoted-printable streaming encoders.
pnpm add @mailport/mime
@mailport/smtp
Single-connection SMTP transport client with STARTTLS, AUTH PLAIN/LOGIN, and dot-stuffing.
pnpm add @mailport/smtp
MEMORY PROFICIENCY & THROUGHPUT
Multi-pass memory delta sampling measured across 3 passes per payload size in Node.js 24 with garbage collection flags.
| TARGET PAYLOAD | EMITTED PAYLOAD | MEDIAN THROUGHPUT | MEDIAN HEAP Δ | WORST HEAP Δ | MEDIAN RSS Δ | MEDIAN ARRAYBUFFER Δ |
|---|---|---|---|---|---|---|
| 10 MB | 13.7 MB | 540.1 MB/s | 15.7 MB | 17.8 MB | 14.6 MB | 10.8 MB |
| 100 MB | 136.8 MB | 589.4 MB/s | 48.1 MB | 74.6 MB | 68.2 MB | 34.9 MB |
| 500 MB | 684.2 MB | 597.6 MB/s | 74.6 MB | 74.6 MB | 70.7 MB | 49.7 MB |