TEST EVERY EMAIL WITHOUT SENDING ONE.

Build, inspect and test email workflows locally, then stream large attachments without buffering the complete file in memory.

$ pnpm add mailport
TRANSPORT PIPELINE ACTIVE · 0ms NETWORK LATENCY
EMAIL SHOULDN'T NEED AN INFRASTRUCTURE TEAM. MAILPORT GIVES YOU DETERMINISTIC TESTING AND BOUNDED MEMORY STREAMING OUT OF THE BOX.

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.

STEP 01 // IN-MEMORY ROUTING

SEND

Construct email payloads with type-safe interfaces (`from`, `to`, `subject`, `attachments`). Payloads bypass disk temporary buffering.

STEP 02 // MIME CHUNK ENCODING

ROUTE

The RFC 5322 engine streams base64 and quoted-printable chunks iteratively through AsyncIterable<Uint8Array> bounds.

STEP 03 // SINGLE-CONNECTION SMTP

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`.

mailer.ts — MailPort SDK
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 ARCHITECTURE
[EMPIRICAL PEAK MEMORY]
< 80 MB

Median 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 UTILITIES
[TEST LATENCY]
0 ms

Synchronous 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.

[UMBRELLA SDK]

mailport

Main umbrella entry point combining core mailer, SMTP transport, and testing matchers.

pnpm add mailport
[0 DEPENDENCIES]

@mailport/core

Core interfaces, clock provider, ID generators, and message validation rules.

pnpm add @mailport/core
[STREAM ENGINE]

@mailport/mime

RFC 5322 MIME builder with base64 and quoted-printable streaming encoders.

pnpm add @mailport/mime
[NETWORK CLIENT]

@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
Note: Throughput figures represent local synthetic loopback processing under --expose-gc. VIEW FULL METHODOLOGY