Skip to content

Repository files navigation

sently — One API. Four channels. Every runtime.

npm JSR MIT Bun stars CI

npm downloads

Start with email, add SMS and push later — one sender shape, one error model, one retry path. Swap the transport; keep your call sites. Node, Bun, Deno, Workers.

Docs · Handbook · llms.txt · sently

Install

bun add sently                                     # npm / Bun / yarn / pnpm
bunx jsr add @omqkhafi/sently                      # JSR

JSR consumers on @alialnaghmoush/sently: switch to @omqkhafi/sently. The old scope will not receive new versions. npm sently is unchanged.

Optional peers (React Email only): react, @react-email/render.

Quick start

import { createMailer } from "sently/mailer";
import { ResendTransport } from "sently/transports/resend";

const mailer = await createMailer({
  transport: new ResendTransport({ apiKey: process.env.RESEND_API_KEY! }),
});

await mailer.send({
  from: "hello@example.com",
  to: "you@example.com",
  subject: "Welcome",
  html: "<p>Sent with sently.</p>",
});

Same shape for every channel — apps use sently senders, not vendor SDKs:

Channel Sender Example transport
Email createMailer / createSMTPMailer sently/transports/resend, sently/smtp
SMS createSmsSender sently/transports/twilio-sms, unifonic, taqnyat-sms
WhatsApp createWhatsAppSender sently/transports/whatsapp-cloud
Push createPushSender sently/transports/webpush, fcm

Full walkthrough: Get started.

Why sently?

Teams usually start on one channel (often email), then add SMS and push. Each vendor SDK brings its own auth, retries, and error shapes. sently keeps one sender shape, one SentlyError model, and one retry/fallback path as you add channels.

Library, not platform. sently is the channel-delivery layer. Preference centers, digests, workflow builders, and in-app inboxes — custom logic or tools like Novu, Knock, or Courier — sit on top of sently, not instead of it.

Compared with email-only stacks (e.g. Nodemailer) and a pile of vendor clients:

Typical stack sently
As channels grow New SDK per channel Same sender factories
Failures Per-vendor exceptions Stable SentlyError codes
Reliability Ad-hoc per client RetryTransport + FallbackTransport
Providers Vendor clients in app code Pluggable transports
Runtimes Often Node only Node, Bun, Deno, CF Workers
Edge / Workers Fat SDKs hurt cold start Tree-shakeable (~6.3 KB HTTP · ~14.9 KB SMTP)
Module format Often CJS ESM only
Dependencies Varies 0 runtime deps

More detail: Compare · Stability · Support matrix.

Entrypoints

Import Use when
sently/mailer HTTP / custom email transports (smallest)
sently/smtp SMTP host, pool, adapters, DKIM
sently/sms SMS
sently/whatsapp WhatsApp
sently/push Push (Web Push or FCM)
sently/channel-result Shared { messageId, provider, accepted }
sently/transports/* One provider or decorator per subpath
sently/webhooks/* Email / SMS / WhatsApp delivery parsers

Documentation

Resource Link
Docs site sently.omqkhafi.dev
Handbook /docs
Get started /docs/get-started
Channels /docs/channels
Transports /docs/transports
Compare /docs/guides/compare
Agents index /llms.txt
Changelog CHANGELOG.md
Security SECURITY.md
Agents AGENTS.md

Local docs: bun run site:dev. Verify: bun run verify.

Semver-stable channel contracts. Published on npm (provenance + Trusted Publishing) and JSR. MIT.

About

Open-source TypeScript messaging infrastructure for Email, SMS, WhatsApp & Push with interchangeable providers.

Topics

Resources

Security policy

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages