Package detail

postal-mime

postalsys119kMIT-02.4.3

Email parser for browser environments

mime, email

readme

postal-mime

postal-mime is an email parsing library that runs in browser environments (including Web Workers) and serverless functions (like Cloudflare Email Workers). It takes in a raw email message (RFC822 format) and outputs a structured object containing headers, recipients, attachments, and more.

Tip
PostalMime is developed by the makers of EmailEngine—a self-hosted email gateway that provides a REST API for IMAP and SMTP servers and sends webhooks whenever something changes in registered accounts.

Table of Contents


Source

The source code is available on GitHub.

Demo

Try out a live demo using the example page.

Installation

Install the module from npm:

npm install postal-mime

Usage

You can import the PostalMime class differently depending on your environment:

Browser

To use PostalMime in the browser (including Web Workers), import it from the src folder:

import PostalMime from './node_modules/postal-mime/src/postal-mime.js';

const email = await PostalMime.parse(`Subject: My awesome email 🤓
Content-Type: text/html; charset=utf-8

<p>Hello world 😵‍💫</p>`);

console.log(email.subject); // "My awesome email 🤓"

Node.js

In Node.js (including serverless functions), import it directly from postal-mime:

import PostalMime from 'postal-mime';
import util from 'node:util';

const email = await PostalMime.parse(`Subject: My awesome email 🤓
Content-Type: text/html; charset=utf-8

<p>Hello world 😵‍💫</p>`);

// Use 'util.inspect' for pretty-printing
console.log(util.inspect(email, false, 22, true));

Cloudflare Email Workers

Use the message.raw as the raw email data for parsing:

import PostalMime from 'postal-mime';

export default {
    async email(message, env, ctx) {
        const email = await PostalMime.parse(message.raw);

        console.log('Subject:', email.subject);
        console.log('HTML:', email.html);
        console.log('Text:', email.text);
    }
};

API

PostalMime.parse()

PostalMime.parse(email, options) -> Promise<ParsedEmail>
  • email: An RFC822 formatted email. This can be a string, ArrayBuffer/Uint8Array, Blob (browser only), Buffer (Node.js), or a ReadableStream.
  • options: Optional configuration object:
    • rfc822Attachments (boolean, default: false): Treat message/rfc822 attachments without a Content-Disposition as attachments.
    • forceRfc822Attachments (boolean, default: false): Treat all message/rfc822 parts as attachments.
    • attachmentEncoding (string, default: "arraybuffer"): Determines how attachment content is decoded in the parsed email:
      • "base64"
      • "utf8"
      • "arraybuffer" (no decoding, returns ArrayBuffer)

Returns: A Promise that resolves to a structured object with the following properties:

  • headers: An array of header objects, each containing:
    • key: Lowercase header name (e.g., "dkim-signature").
    • value: Unprocessed header value as a string.
  • from, sender: Processed address objects:
    • name: Decoded display name, or an empty string if not set.
    • address: Email address.
  • deliveredTo, returnPath: Single email addresses as strings.
  • to, cc, bcc, replyTo: Arrays of processed address objects (same structure as from).
  • subject: Subject line of the email.
  • messageId, inReplyTo, references: Values from their corresponding headers.
  • date: The email’s sending time in ISO 8601 format (or the original string if parsing fails).
  • html: String containing the HTML content of the email.
  • text: String containing the plain text content of the email.
  • attachments: Array of attachment objects:
    • filename
    • mimeType
    • disposition (e.g., "attachment", "inline", or null)
    • related (boolean, true if it’s an inline image)
    • contentId
    • content (array buffer or string, depending on attachmentEncoding)
    • encoding (e.g., "base64")

Utility Functions

addressParser()

import { addressParser } from 'postal-mime';

addressParser(addressStr, opts) -> Array
  • addressStr: A raw address header string.
  • opts: Optional configuration:
    • flatten (boolean, default: false): If true, ignores address groups and returns a flat array of addresses.

Returns: An array of address objects, which can be nested if address groups are present.

Example:

const addressStr = '=?utf-8?B?44Ko44Od44K544Kr44O844OJ?= <support@example.com>';
console.log(addressParser(addressStr));
// [ { name: 'エポスカード', address: 'support@example.com' } ]

decodeWords()

import { decodeWords } from 'postal-mime';

decodeWords(encodedStr) -> string
  • encodedStr: A string that may contain MIME encoded-words.

Returns: A Unicode string with all encoded-words decoded.

Example:

const encodedStr = 'Hello, =?utf-8?B?44Ko44Od44K544Kr44O844OJ?=';
console.log(decodeWords(encodedStr));
// Hello, エポスカード

License

© 2021–2025 Andris Reinman

postal-mime is licensed under the MIT No Attribution license.

changelog

Changelog

2.4.3 (2025-01-24)

Bug Fixes

  • TextDecoder: Do not reuse text decoders to avoid spilling data from one instance to another (8b1013e)

2.4.2 (2025-01-24)

Bug Fixes

  • decodeWords: Better handling of decoded words (e0f0047)

2.4.1 (2025-01-05)

Bug Fixes

2.4.0 (2025-01-05)

Features

  • attachments: Added new option 'attachmentEncoding' to return attachment content as a string, not arraybuffer (0f7e9df)

2.3.2 (2024-09-23)

Bug Fixes

  • Modified README to trigger a new release (previous npm publish failed) (f975ef4)

2.3.1 (2024-09-23)

Bug Fixes

  • message/rfc822: Added option 'forceRfc822Attachments' to handle all message/rfc822 nodes as attachments instead of inline content (bf47621)

2.3.0 (2024-09-23)

Features

  • Treat message/rfc822 as an attachment for delivery-status and feedback-report (21e6224)

2.2.9 (2024-09-16)

Bug Fixes

  • exports: Define 'default' exports as last for legacy compatibility (a9518c8)

2.2.8 (2024-09-14)

Bug Fixes

  • module: add default to module exports (#56) (4f99ebe)

2.2.7 (2024-07-31)

Bug Fixes

  • rfc822: Only inline message/rfc822 messages if Content-Disposition is (53024de)

2.2.6 (2024-07-09)

Bug Fixes

  • types: Updated type for attachment.content to ArrayBuffer (191524f)

2.2.5 (2024-04-11)

Bug Fixes

  • types: Fixed Address type (57908e4)

2.2.4 (2024-04-11)

Bug Fixes

  • exports: Export addressParser and decodeWords functions (43d3187)

2.2.3 (2024-04-11)

Bug Fixes

  • attachments: Added description key from Content-Description attachment header (6e29de9)
  • calendar-attachments: treat text/calendar as an attachment (2196b49)

2.2.2 (2024-04-10)

Bug Fixes

  • parse: Do not throw on empty input when initializing an array buffer object (ddae5b4)

2.2.1 (2024-03-31)

Bug Fixes

  • parser: Reply-To value must be an array, not a single address object (280bd8d)

2.2.0 (2024-03-26)

Features

  • interface: Added statis parse() method to simplify usage (await PostalMime.parse(email)) (c2faa27)

2.1.2 (2024-02-29)

Bug Fixes

  • git: re-renamed git repo (29d235e)
  • git: Renamed git repository (829e537)

2.1.1 (2024-02-26)

Bug Fixes

  • types: Updated types for PostalMime (bc90f6d)

2.1.0 (2024-02-22)

Features

  • workers: Support Cloudflare Email Workers out of the box (4904708)

Bug Fixes

  • module: add types to module exports (#23) (1ee4a42)

2.0.2 (2023-12-08)

Bug Fixes

  • test: Added a tests runner and some tests (8c6f7fb)
  • test: Added test action (c43c086)

2.0.1 (2023-11-05)

Bug Fixes

  • npm: DO not ignore src folder when publishing to npm (ef8a2df)

2.0.0 (2023-11-03)

⚠ BREAKING CHANGES

  • module: Use as an ES module, do not build with webpack

Features

  • module: Use as an ES module, do not build with webpack (70df152)

1.1.0 (2023-11-02)

Features

  • deploy: automatic publishing (64f9a81)
  • license: changed license from AGPL to MIT-0 (d0ca0dc)

Bug Fixes