Core types and interfaces for Upyo, a cross-runtime email library that provides a unified, type-safe API for sending emails across Node.js, Deno, Bun, and edge functions.
The @upyo/core package provides the foundational types and interfaces that all
Upyo transport implementations use. It defines the common Message, Address,
Transport, and Receipt types that enable seamless switching between
different email providers while maintaining consistent type safety and
error handling.
- Universal types: Common interfaces for all email transports
- Type-safe messaging: Comprehensive TypeScript definitions for email messages
- Attachment support: File attachment handling
- Cross-runtime compatibility: Works on Node.js, Deno, Bun, and edge functions
- Zero dependencies: Lightweight with no external dependencies
npm add @upyo/core
pnpm add @upyo/core
yarn add @upyo/core
deno add jsr:@upyo/core
bun add @upyo/coreThe createMessage() function provides a convenient way to create email
messages:
import { createMessage } from "@upyo/core";
const message = createMessage({
from: "sender@example.com",
to: ["recipient@example.net", "another@example.org"],
cc: "copy@example.com",
subject: "Hello from Upyo!",
content: {
text: "This is a plain text message.",
html: "<p>This is an <strong>HTML</strong> message.</p>",
},
priority: "high",
});Attachments can be added using the standard File API:
import { createMessage } from "@upyo/core";
const message = createMessage({
from: "sender@example.com",
to: "recipient@example.net",
subject: "Document attached",
content: { text: "Please find the document attached." },
attachments: [
new File(
[await fetch("document.pdf").then(r => r.arrayBuffer())],
"document.pdf",
{ type: "application/pdf" }
),
],
});All transport operations return Receipt objects that use discriminated unions
for type-safe error handling:
import type { Receipt } from "@upyo/core";
function handleReceipt(receipt: Receipt) {
if (receipt.successful) {
console.log("Message sent with ID:", receipt.messageId);
} else {
console.error("Send failed:", receipt.errorMessages.join(", "));
}
}The Transport interface defines the contract for all email providers:
import type { Message, Receipt, Transport, TransportOptions } from "@upyo/core";
class MyCustomTransport implements Transport {
async send(message: Message, options?: TransportOptions): Promise<Receipt> {
// Implementation details...
return { successful: true, messageId: "12345" };
}
async *sendMany(
messages: Iterable<Message> | AsyncIterable<Message>,
options?: TransportOptions,
): AsyncIterable<Receipt> {
for await (const message of messages) {
yield await this.send(message, options);
}
}
}The @upyo/core package is the foundation for all Upyo transport
implementations:
| Package | JSR | npm | Description |
|---|---|---|---|
| @upyo/smtp | JSR | npm | SMTP transport for any mail server |
| @upyo/mailgun | JSR | npm | Mailgun HTTP API transport |
| @upyo/sendgrid | JSR | npm | SendGrid HTTP API transport |
| @upyo/ses | JSR | npm | Amazon SES HTTP API transport |
| @upyo/mock | JSR | npm | Mock transport for testing |
| @upyo/opentelemetry | JSR | npm | OpenTelemetry observability for Upyo transports |
For comprehensive documentation, examples, and guides, visit https://upyo.org/.
API reference documentation is available on JSR: https://jsr.io/@upyo/core.