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.
Maintainers
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-builderQuick 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
cidin your<img src="cid:x">must exactly match thecidpassed 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:
- RFC 5322 — Internet Message Format
- RFC 2045 — MIME Part One (encoding, line wrapping)
- RFC 2046 — Multipart MIME
- RFC 2387 — multipart/related
- RFC 2392 — Content-ID /
cid:URLs
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
