Streaming, memory-efficient, fully-typed MIME email parser — byte chunks in, structured email out, with a declarative middleware seam.
The open-source parser behind MailKite's inbound pipeline.
Docs · Libraries · Python port · mailkite.dev
Maintained in the MailKite monorepo; this is the public home + npm distribution for
@mailkite/mail-parse. Issues and PRs welcome here.
- Streaming + low memory — never buffers the whole message; the splitter holds at most one part in flight and attachments arrive part-by-part. (Contrast: most JS parsers buffer the entire message + every attachment.)
- Fully typed — strict TypeScript; the parsed
Messageshape is a single source of truth that ports across languages (see the Python port). - Extensible by middleware, not forks — a declarative-match registry handles unknown / malformed / special content (attachments, charsets, languages) per part, without editing the core.
- Tolerant — malformed input never throws; degradations surface as typed
diagnostics. - Self-improving — a deterministic, PII-free failure-signature primitive can auto-file deduplicated GitHub issues so the parser improves over time.
npm install @mailkite/mail-parseimport { parse } from "@mailkite/mail-parse";
// From a Buffer/Uint8Array, a string, or any (async) iterable of byte chunks (a stream).
const msg = await parse(rawMimeBytes);
msg.from; // { address, name? }
msg.subject; // RFC 2047 decoded
msg.text; // decoded text/plain
msg.html; // decoded text/html
msg.attachments; // [{ filename, mimeType, content: Uint8Array, size, ... }]
msg.diagnostics; // typed, non-fatal degradationsimport { parse, charsetRepair, languageDetect, winmailDetect } from "@mailkite/mail-parse";
const msg = await parse(rawMimeBytes, {
middleware: [charsetRepair(), languageDetect(), winmailDetect()],
});
msg.annotations.language; // e.g. "ja"import { splitMime } from "@mailkite/mail-parse";
await splitMime(readableStream, {
onNodeStart(meta) {/* PartMeta computed before any per-part handling */},
onBody(meta, chunk) {/* raw body bytes, part-by-part — pipe to R2/disk */},
onNodeEnd(meta) {/* part finished */},
});import { parseWithPostalMime } from "@mailkite/mail-parse/postal";
const msg = await parseWithPostalMime(rawMimeBytes); // same Message shape, Workers-nativenpm install
npm test # vitest over the gold-standard corpus
npm run typecheck
npm run buildmail-parse is part of the MailKite ecosystem. The API SDKs (same contract, every language) live separately — full list: https://mailkite.dev/docs/libraries.
| Library | Repo | Distribution |
|---|---|---|
| mail-parse (this repo) | mail-parse |
npm |
| mail-parse (Python port) | mail-parse-py |
PyPI |
| MailKite for Node.js | mailkite-node |
npm |
| MailKite for Python | mailkite-python |
PyPI |
| MailKite for Go | mailkite-go |
Go modules |
| @mailkite/cli | mailkite-cli |
npm |
| @mailkite/mcp | mailkite-mcp |
npm |
- 📚 Documentation: https://mailkite.dev/docs
- 🧩 Libraries: https://mailkite.dev/docs/libraries
- 🐍 Python port: https://github.com/mailkite/mail-parse-py
- 🌐 Website: https://mailkite.dev
MIT licensed. © MailKite.