A comprehensive messaging library for Email, SMS, and Push notifications with support for multiple service providers.
v2 highlights: Bun-only runtime · ESM-only · zero runtime dependencies (JWT via native WebCrypto, phone parsing via built-in calling-code table) · typed MessagingError · consistent per-recipient delivery results · FCM OAuth token caching · HTTPS-only transport with header-injection protection · fully mocked test suite (no real credentials needed).
- Mailgun - Email delivery service
- SendGrid - Email delivery platform
- SMTP - Generic SMTP support (optional
nodemailerpeer dependency)
- Twilio - SMS and communication APIs
- Vonage (formerly Nexmo) - Global communications platform
- Msg91 - SMS and communication platform
- Telesign - Customer verification platform
- TextMagic - SMS marketing platform
- FCM (Firebase Cloud Messaging) - Google's messaging solution
- APNS (Apple Push Notification Service) - Apple's push notification service
- Bun >= 1.1
- Node.js is not supported in v2.
bun add @nuvix/messagingimport { Mailgun } from "@nuvix/messaging";
import { Email } from "@nuvix/messaging";
const adapter = new Mailgun("api-key", "domain.com");
const email = new Email({
to: ["user@example.com"],
subject: "Hello World",
content: "This is a test email",
fromName: "Your App",
fromEmail: "noreply@yourdomain.com",
});
const result = await adapter.send(email);
console.log(`Delivered to ${result.deliveredTo} recipients`);import { Twilio } from "@nuvix/messaging";
import { SMS } from "@nuvix/messaging";
const adapter = new Twilio("account-sid", "auth-token", "+1234567890");
const sms = new SMS({
to: ["+1987654321"],
content: "Hello from your app!",
});
const result = await adapter.send(sms);import { FCM } from "@nuvix/messaging";
import { Push } from "@nuvix/messaging";
const adapter = new FCM("service-account-json");
const push = new Push({
to: ["device-token"],
title: "New Message",
body: "You have a new notification",
data: { type: "message", id: "123" },
});
const result = await adapter.send(push);import { MessagingError, MessagingErrorCode } from "@nuvix/messaging";
try {
await adapter.send(sms);
} catch (error) {
if (error instanceof MessagingError) {
switch (error.code) {
case MessagingErrorCode.BATCH_LIMIT_EXCEEDED:
// split the batch and retry
break;
case MessagingErrorCode.NO_RECIPIENTS:
// fix the message
break;
}
}
}The default test suite is fully mocked — no provider credentials required:
bun install
bun test # run all tests
bun test --coverage # with coverage
bun test --watch # watch modeOptional live integration tests hit real provider APIs. They are excluded by default; enable them with credentials from .env:
cp .env.example .env # fill in credentials
bun run test:live # RUN_LIVE_TESTS=true bun test tests/livesrc/
├── adapter.ts # Base adapter class (HTTP engine, retries, validation)
├── response.ts # Delivery result accumulator
├── types.ts # Type definitions
├── errors.ts # MessagingError + error codes
├── adapter/ # Adapter implementations
│ ├── Email.ts # Email base class
│ ├── SMS.ts # SMS base class
│ ├── Push.ts # Push base class
│ ├── Email/ # Mailgun, Sendgrid, SMTP
│ ├── SMS/ # Twilio, Vonage, Msg91, Telesign, TextMagic
│ └── Push/ # FCM, APNS
├── messages/ # Message classes (Email, SMS, Push, Attachment)
└── helpers/
└── jwt.ts # Native WebCrypto JWT signing (RS256 / ES256)
tests/
├── helpers/mock-fetch.ts # fetch mocking utilities
├── adapters/ # Adapter tests (mocked HTTP)
├── live/ # Optional live integration tests
├── adapter.test.ts # Base engine tests (retry, security, validation)
├── jwt.test.ts # WebCrypto JWT signing tests
├── messages.test.ts # Message class tests
└── response.test.ts # Response tests
bun run build # bun build (ESM, target=bun) + tsc declarations
bun run typecheck # tsc --noEmitbun run lint
bun run lint:fix- All outbound requests are restricted to
https:// - Header values are sanitized against CRLF injection
- Provider errors are surfaced per recipient without leaking credentials
- SMTP's insecure TLS-bypass option (
rejectUnauthorized: false) was removed in v2
See MIGRATION.md.
This project is licensed under the MIT License.
- Fork the repository
- Create a feature branch
- Add tests (mocked — no real credentials in CI)
- Ensure
bun test,bun run lint, andbun run buildpass - Submit a pull request