Upyo is a simple and cross-runtime library for sending email messages using SMTP and various email providers. It works on Node.js, Deno, Bun, and edge functions.
571
stars
416
commits
TypeScript
primary language
Sep 9, 2026
updated
Upyo is a cross-runtime email library that provides a unified, type-safe API for sending emails across Node.js, Deno, Bun, and edge functions. Switch between SMTP and HTTP-based providers (Lettermint, Maileroo, Mailgun, Mailtrap, Resend, SendGrid, Amazon SES) without changing your application code, while enjoying full TypeScript support, consistent error handling, and built-in testing capabilities with mock transports across all runtimes.
Here's a quick demo of sending an email using the Mailgun transport:
import { createMessage } from "@upyo/core";
import { MailgunTransport } from "@upyo/mailgun";
import fs from "node:fs/promises";
import process from "node:process";
const message = createMessage({
from: "sender@example.com",
to: "recipient@example.net",
subject: "Hello from Upyo!",
content: { text: "This is a test email." },
attachments: [
new File(
[await fs.readFile("image.jpg"), "image.jpg", { type: "image/jpeg" }]
)
],
});
const transport = new MailgunTransport({
apiKey: process.env.MAILGUN_KEY!,
domain: process.env.MAILGUN_DOMAIN!,
region: process.env.MAILGUN_REGION as "us" | "eu",
});
const receipt = await transport.send(message);
if (receipt.successful) {
console.log("Message sent with ID:", receipt.messageId);
} else {
console.error("Send failed:", receipt.errorMessages.join(", "));
}
Upyo provides comprehensive documentation to help you get started quickly: https://upyo.org/.
API reference documentation for each package is available on JSR (see below).
Upyo is a monorepo which contains several packages. The main package is @upyo/core, which provides the shared types and common interfaces for sending email messages. Other packages implement specific transports for sending messages. The following is a list of the available packages:
| Package | JSR | npm | Description |
|---|---|---|---|
| @upyo/core | JSR | npm | Shared types and interfaces for email messages |
| @upyo/mime | JSR | npm | Portable MIME composition and DKIM signing |
| @upyo/smtp | JSR | npm | SMTP transport |
| @upyo/jmap | JSR | npm | JMAP transport (RFC 8620/8621) |
| @upyo/lettermint | JSR | npm | Lettermint transport |
| @upyo/logtape | JSR | npm | LogTape observability transport |
| @upyo/maileroo | JSR | npm | Maileroo transport |
| @upyo/mailtrap | JSR | npm | Mailtrap transport |
| @upyo/mailgun | JSR | npm | Mailgun transport |
| @upyo/plunk | JSR | npm | Plunk transport |
| @upyo/resend | JSR | npm | Resend transport |
| @upyo/sendgrid | JSR | npm | SendGrid transport |
| @upyo/ses | JSR | npm | Amazon SES transport |
| @upyo/retry | JSR | npm | Retry and backoff decorator for transports |
| @upyo/opentelemetry | JSR | npm | OpenTelemetry observability for Upyo transports |
| @upyo/mock | JSR | npm | Mock transport for testing |
The name Upyo
(pronounced /oo-pee-oh/) is derived from the Korean word
郵票
(upyo), which means postage stamp. It reflects the library's
purpose of sending email messages, similar to how a postage stamp is used to
send physical mail.
TypeScript
99.6%
Upyo is a simple and cross-runtime library for sending email messages using SMTP and various email providers. It works on Node.js, Deno, Bun, and edge functions.
571
stars
416
commits
TypeScript
primary language
Sep 9, 2026
updated
Upyo is a cross-runtime email library that provides a unified, type-safe API for sending emails across Node.js, Deno, Bun, and edge functions. Switch between SMTP and HTTP-based providers (Lettermint, Maileroo, Mailgun, Mailtrap, Resend, SendGrid, Amazon SES) without changing your application code, while enjoying full TypeScript support, consistent error handling, and built-in testing capabilities with mock transports across all runtimes.
Here's a quick demo of sending an email using the Mailgun transport:
import { createMessage } from "@upyo/core";
import { MailgunTransport } from "@upyo/mailgun";
import fs from "node:fs/promises";
import process from "node:process";
const message = createMessage({
from: "sender@example.com",
to: "recipient@example.net",
subject: "Hello from Upyo!",
content: { text: "This is a test email." },
attachments: [
new File(
[await fs.readFile("image.jpg"), "image.jpg", { type: "image/jpeg" }]
)
],
});
const transport = new MailgunTransport({
apiKey: process.env.MAILGUN_KEY!,
domain: process.env.MAILGUN_DOMAIN!,
region: process.env.MAILGUN_REGION as "us" | "eu",
});
const receipt = await transport.send(message);
if (receipt.successful) {
console.log("Message sent with ID:", receipt.messageId);
} else {
console.error("Send failed:", receipt.errorMessages.join(", "));
}
Upyo provides comprehensive documentation to help you get started quickly: https://upyo.org/.
API reference documentation for each package is available on JSR (see below).
Upyo is a monorepo which contains several packages. The main package is @upyo/core, which provides the shared types and common interfaces for sending email messages. Other packages implement specific transports for sending messages. The following is a list of the available packages:
| Package | JSR | npm | Description |
|---|---|---|---|
| @upyo/core | JSR | npm | Shared types and interfaces for email messages |
| @upyo/mime | JSR | npm | Portable MIME composition and DKIM signing |
| @upyo/smtp | JSR | npm | SMTP transport |
| @upyo/jmap | JSR | npm | JMAP transport (RFC 8620/8621) |
| @upyo/lettermint | JSR | npm | Lettermint transport |
| @upyo/logtape | JSR | npm | LogTape observability transport |
| @upyo/maileroo | JSR | npm | Maileroo transport |
| @upyo/mailtrap | JSR | npm | Mailtrap transport |
| @upyo/mailgun | JSR | npm | Mailgun transport |
| @upyo/plunk | JSR | npm | Plunk transport |
| @upyo/resend | JSR | npm | Resend transport |
| @upyo/sendgrid | JSR | npm | SendGrid transport |
| @upyo/ses | JSR | npm | Amazon SES transport |
| @upyo/retry | JSR | npm | Retry and backoff decorator for transports |
| @upyo/opentelemetry | JSR | npm | OpenTelemetry observability for Upyo transports |
| @upyo/mock | JSR | npm | Mock transport for testing |
The name Upyo
(pronounced /oo-pee-oh/) is derived from the Korean word
郵票
(upyo), which means postage stamp. It reflects the library's
purpose of sending email messages, similar to how a postage stamp is used to
send physical mail.
TypeScript
99.6%