One TypeScript client for transactional email. Pick the providers you actually send through, add retries and fallback routes, catch unsupported fields before they are silently dropped, and keep every send observable.
- 🔌 Adapters for 20+ providers behind one normalized message
- 🔁 Retries within an adapter, plus fallback routes across adapters
- 🛟 Fail-fast field-support checks before a provider drops data
- 🔭 Observability hooks for logs, metrics, and traces
- 🧪 Test adapters that never call real providers
- ⌨️ CLI for adapter discovery, doctor checks, and dry-run sends
Install
npm install @opencoredev/email-sdkServer-side only (Node 20+ or Bun) — never expose provider API keys in client code.
Usage
import { createEmailClient } from "@opencoredev/email-sdk";
import { resend } from "@opencoredev/email-sdk/resend";
const email = createEmailClient({
adapters: [resend({ apiKey: process.env.RESEND_API_KEY! })],
});
await email.send({
from: "Acme <hello@acme.com>",
to: "user@example.com",
subject: "Welcome",
html: "<p>It works.</p>",
});Adapters
Resend, Postmark, SendGrid, Mailgun, Brevo, MailerSend, SparkPost, Mailchimp, Iterable, Loops, Plunk, Mailtrap, Cloudflare, Unosend, Scaleway, ZeptoMail, MailPace, Sequenzy, JetEmail, Primitive, SMTP, and a testing adapter — each imported from its own entry point. New here? Start with resend for the fastest first send.
CLI
npx email-sdk doctor --adapter resendDiscover adapters, validate setup, and run dry-run smoke sends from any environment.
Documentation
Full docs live at email-sdk.dev/docs. Good places to start:
Sponsors
Email SDK is supported by companies that help keep provider integrations practical and maintained. Want your logo here? Become a sponsor →

Also sponsored by Sequenzy · adapter docs
Star History
AGPL-3.0 License · Built by @leodev