← back
Packages

Packages

notifkit ships first-party transports for every major channel alongside the core engine: email, push, SMS, Slack, WhatsApp, Telegram, and Discord, plus a development transport and an AI agent MCP server.

PackageChannelWrapsUse it for
@notifkit/provider-resendemailResend + svixProduction email, with engagement webhooks & bounce suppression.
@notifkit/provider-fcmpushFirebase AdminProduction push to iOS and Android devices.
@notifkit/provider-twiliosmsTwilio Messages APIProduction SMS with status callbacks & STOP reply suppression.
@notifkit/provider-slackslackSlack Web API & WebhooksDirect messages, public/private channels, Block Kit layouts.
@notifkit/provider-whatsappwhatsappMeta Cloud APIDirect messaging to recipient phone numbers with zero SaaS markup.
@notifkit/provider-telegramtelegramTelegram Bot APIBot notifications to chat IDs with HTML/Markdown and silent alerts.
@notifkit/provider-discorddiscordDiscord WebhooksChannel alerts with custom avatars, usernames, and embeds.
@notifkit/provider-consoleconfigurablenothingDevelopment and tests. Prints and reports success.
@notifkit/mcp—MCP SDKDriving notifkit from an AI agent. Not a transport.

SMS has first-party support via @notifkit/provider-twilio, or you can write your own custom SMS transport for providers like Vonage, AWS SNS, or Infobip using the same standard Transport interface.

all of them are optional

Nothing here is required to run notifkit: the core has no provider dependency, which is why firebase-admin and resend are not in its dependency tree. Each package declares notifkit as a peer dependency and is registered by you at boot, so an install that only sends email never pulls in the Firebase SDK.

By channel

Writing your own

Everything above implements the same Transport interface, and nothing about the first-party packages is privileged. A transport you write registers the same way and is picked up by the same registry. Register more than one for a channel and the highest priority is tried first, with the rest as failover.

import { registerTransport } from "notifkit";

registerTransport(new ResendTransport({ /* … */ }), 10);  // tried first
registerTransport(new PostmarkTransport({ /* … */ }), 5); // only if Resend fails
priority is failover, not routing

Two transports on one channel give you provider failover. They do not let you choose between them per send. The registry keys on channel alone, so the second is reached only when the first fails. Anything that varies per message, a sender address included, belongs in the template and is read by a single transport.

The full interface, including the webhook hooks and what DeliveryResult.invalidToken does, is in the reference, and Channels & fallback walks through a worked example.