npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gmail-mime-builder

v1.0.0

Published

Build RFC-compliant MIME email messages and get a Gmail API-ready Base64URL raw string. No SMTP, no OAuth, no sending — just MIME.

Readme

gmail-mime-builder

Build RFC-compliant MIME email messages and get back a Base64URL raw string ready to hand to the Gmail API.

This package only builds the MIME message. It does not send email, connect to SMTP, or talk to Gmail/OAuth — you bring your own authenticated googleapis client and pass the raw string straight to gmail.users.messages.send().

Install

npm install gmail-mime-builder

Quick start

import { MimeBuilder } from "gmail-mime-builder";
import { google } from "googleapis";

const raw = await new MimeBuilder()
  .from("[email protected]")
  .to("[email protected]")
  .subject("Hello")
  .html("<h1>Hello World</h1>")
  .attachment({ path: "./invoice.pdf" })
  .buildRaw();

const gmail = google.gmail({ version: "v1", auth });
await gmail.users.messages.send({
  userId: "me",
  requestBody: { raw },
});

No further encoding, wrapping, or processing is needed — buildRaw() returns exactly what the Gmail API expects.

Plain text emails

const raw = await new MimeBuilder()
  .from("[email protected]")
  .to("[email protected]")
  .subject("Hi")
  .text("Plain text body.")
  .buildRaw();

HTML + inline images (multipart/related)

Reference inline images from your HTML with cid: and attach the matching image with the same cid. The library validates that every cid: reference has a matching image, and vice versa.

const raw = await new MimeBuilder()
  .from("[email protected]")
  .to("[email protected]")
  .subject("Monthly Report")
  .html(`<h2>Hello</h2><p>See the report.</p><img src="cid:companyLogo">`)
  .inlineImage({ cid: "companyLogo", path: "./assets/logo.png" })
  .buildRaw();

Attachments (multipart/mixed)

const raw = await new MimeBuilder()
  .from("[email protected]")
  .to("[email protected]")
  .subject("Invoice")
  .text("See attached invoice.")
  .attachment({ path: "./invoice.pdf" })
  .attachment({ filename: "notes.txt", buffer: Buffer.from("some notes") })
  .buildRaw();

Attachments and inline images each accept exactly one of path, buffer, or base64. filename is inferred from path, otherwise required.

Text + HTML (multipart/alternative)

Provide both .text() and .html() and the library automatically builds a multipart/alternative message so mail clients can choose the best representation.

const raw = await new MimeBuilder()
  .from("[email protected]")
  .to("[email protected]")
  .subject("Hi")
  .text("Plain text fallback.")
  .html("<p>HTML version.</p>")
  .buildRaw();

HTML + inline images + attachments

All three combine automatically into multipart/mixed > multipart/related > multipart/alternative. You never construct or think about boundaries — they're generated for you.

Custom headers

new MimeBuilder()
  .from("[email protected]")
  .to("[email protected]")
  .header("X-Priority", "1")
  .header("X-Mailer", "my-app")
  // ...

API reference

Envelope

| Method | Description | |---|---| | .from(address) | Sender address. Required. "[email protected]" or "Name <[email protected]>". | | .sender(address) | Alias for .from(). | | .to(address) | Recipient(s). String, Address, or array of either. | | .cc(address) | CC recipient(s). | | .bcc(address) | BCC recipient(s). Never written to the output headers. | | .replyTo(address) | Reply-To address(es). | | .subject(text) | Subject line. Non-ASCII is RFC 2047 encoded automatically. | | .date(date) | Overrides the Date header (defaults to now). | | .messageId(id) | Overrides the generated Message-ID. | | .inReplyTo(id) | Sets In-Reply-To for threading. | | .references(ids[]) | Sets References for threading. | | .header(name, value) | Adds an arbitrary custom header. |

Content

| Method | Description | |---|---| | .text(body) | Plain text body. | | .html(body) | HTML body. | | .inlineImage({ cid, path\|buffer\|base64 }) | Image referenced via cid: in HTML. | | .attachment({ path\|buffer\|base64, filename? }) | File attachment. |

Output

| Method | Returns | |---|---| | .buildMime() | The raw MIME message string (useful for debugging). | | .buildBase64() | The MIME message as standard Base64. | | .buildRaw() | The MIME message as Base64URL — pass this to Gmail. | | .build() | { mime, base64, raw, boundaries, size } — everything at once. |

Error handling

All validation failures throw MimeBuilderValidationError:

import { MimeBuilder, MimeBuilderValidationError } from "gmail-mime-builder";

try {
  await new MimeBuilder().to("[email protected]").text("hi").buildRaw(); // missing .from()
} catch (err) {
  if (err instanceof MimeBuilderValidationError) {
    console.error(err.message);
  }
}

Validated conditions include: missing From, no recipients, invalid email addresses, a cid: in HTML with no matching inlineImage() (and vice versa), duplicate Content-IDs, an unreadable attachment/image file path, and a missing body (.text()/.html()).

Troubleshooting

  • "HTML references cid:x but no matching inlineImage was provided" — the cid in your <img src="cid:x"> must exactly match the cid passed to .inlineImage().
  • "could not read file at path" — check the path is correct and readable relative to your process's working directory; prefer absolute paths.
  • Gmail rejects the message — make sure you're passing the string from .buildRaw() (Base64URL), not .buildBase64() (standard Base64) or .buildMime() (raw MIME text).

RFC references

This package follows:

Scope

This package builds MIME messages only. It does not send email, connect to SMTP, handle OAuth, or call the Gmail API — bring your own authenticated client for that.

License

MIT