You shouldn't have to build a notification system.
Self-hosted notification infrastructure for product notifications. One API call handles push, email, SMS, chat, and webhooks, with preferences, quiet hours, retries, fallback, scheduling, workflows, an admin dashboard, and delivery logs built in.
Documentation · Quickstart · Examples · Production support · notifkit.dev
brag.mp4
(note: this video is generated using claude)
Like Knock or Courier, except it runs on the PostgreSQL and Redis you already have, your workflows live in your code, and there is no per-message bill.
await notifkit.notify({
user: "usr_123",
template: "order-shipped",
channels: ["push", "email"],
fallback: true,
});That call tries push, then email if push fails. Preferences, consent, quiet hours, retries, deduplication, throttling, template rendering, and delivery tracking all happen behind it.
- Doesn't lose messages. Redis Streams consumer groups, 24-hour idempotency, retries, circuit breakers and a replayable dead-letter queue. Chaos-tested: workers killed with
SIGKILLmid-stream, Redis and PostgreSQL restarted under load, Redis wiped, and 100k messages with flat memory. - Runs on a small box. 200 notifications/sec sustained on 2 vCPUs, over a 15-minute soak with provider failures, retries and webhooks. Method and numbers →
- Runs in production. About 260K notifications a day (8M a month) of email, push and OTPs at our own company.
- Your stack, your data. PostgreSQL and Redis you already run, provider accounts you already have, and nothing that bills per send. Trust me it will save you $$$
- Workflows in code. Multi-step sequences that wait days, block on events and survive restarts, written in TypeScript and kept in git.
You need Node 22+ and Docker running. In development notifkit starts throwaway PostgreSQL and Redis containers for you.
npm create notifkit@latest my-app # or: npx notifkit create my-app
cd my-app
npm run dev # leave it runningIn a second terminal:
npm run setup # create a project, save its API key to .env
npm run send # send a test notificationThe default provider prints notifications to the server terminal, so you need no provider account to try it. Pass --provider resend, twilio or fcm to start with a real one. See create-notifkit for the options.
To add notifkit to an app you already have, or to see what each generated file does, follow the full quickstart. For production, see Deployment.
| notifkit | Novu | |
|---|---|---|
| Self-hosted | Yes | Yes |
| Storage | PostgreSQL + Redis | MongoDB + Redis |
| Workflows | TypeScript in your codebase | Code via a bridge endpoint, or a visual editor |
| Channel fallback | Built in: fallback: true |
Built from workflow step conditions |
| In-app inbox UI | No | Yes |
| Admin dashboard | Yes | Yes |
| MCP server | Yes | Yes |
| License | MIT, no paid edition | MIT core, commercial enterprise modules |
Knock and Courier are hosted SaaS. Both have a free tier of about 10k notifications a month; past that, Knock's Starter plan is $250/month for 50k plus $5 per extra 1,000, and Courier bills per send. notifkit costs whatever your Postgres and Redis cost. (Pricing checked October 2026. See their pricing pages for current numbers.)
If you need an in-app inbox or 75 provider adapters today, Novu is the more complete choice. Choose notifkit if you want reliability features like provider fallback without a commercial license, a small codebase you can read, and published failure testing.
Longer comparisons: Novu · Knock · Courier
| The question | What notifkit does |
|---|---|
| "What happens when a provider goes down?" | Circuit breakers, exponential backoff, DLQ replay |
| "What if a worker dies mid-send?" | Consumer groups reclaim and replay in-flight messages |
| "Will a retried request send twice?" | Same X-Idempotency-Key within 24 hours is delivered once |
| "What if push fails?" | Falls back to the next channel you listed: SMS, then email |
| "What if the user is asleep?" | Quiet hours in the user's timezone; the send waits for the window |
| "What about OTPs during a marketing blast?" | critical runs on its own lane and skips quiet hours |
| "What if they unsubscribed?" | RFC 8058 one-click unsubscribe; bounces and complaints suppress too |
| "Can several apps share one deployment?" | Projects, each with its own API keys, data and rate limit |
| "Can my Python or Go service use it?" | Yes. It is a REST API; the TypeScript SDK is optional |
Bring your own provider accounts. First-party packages:
@notifkit/provider-resend: transactional email via Resend@notifkit/provider-fcm: push notifications via Firebase Cloud Messaging@notifkit/provider-twilio: SMS via Twilio, with signature-verified delivery status callbacks@notifkit/provider-slack: Slack messages via Incoming Webhooks or the Web API@notifkit/provider-telegram: messages via a Telegram bot@notifkit/provider-discord: messages via a Discord webhook@notifkit/provider-whatsapp: messages via Meta's WhatsApp Cloud API@notifkit/provider-console: prints instead of sending, for development and tests
For anything else, implement a Transport:
class MyTransport implements Transport {
async send(message) {
// Send through SES, Postmark, APNs,
// SendGrid, a custom webhook, or anything else.
}
}Connect the notifkit MCP server to Claude Code, Cursor, or any MCP client:
claude mcp add notifkit \
--env NOTIFKIT_URL=http://localhost:3000 \
--env NOTIFKIT_API_KEY=nk_live_... \
-- npx -y @notifkit/mcpThen ask things like "why didn't usr_9182 get their password reset?" or "how did yesterday's spring-sale campaign do?". MCP docs →
Already have notification code scattered across your app? Point your coding agent at https://notifkit.dev/llms-full.txt and ask it to refactor that code into notifkit calls.
Templates, workflows, and routing live in your code. The dashboard at /admin is an optional ops console: a live activity feed, delivery logs, queue depth per priority lane, workflow runs step by step, dead-letter replay, scheduled-send cancellation, and project and API key management.
To sign in, set ADMIN_EMAIL and ADMIN_PASSWORD before starting the server, then open http://localhost:3000/admin.
Everything lives at notifkit.dev/docs: concepts, routing and fallback, preferences, workflows, architecture, operations and the API reference.
Need help running notifkit in production? We can deploy it on your infrastructure, migrate your templates from Knock, Courier, Novu or your custom engine, and give you priority support. Email contact.devkitshq@gmail.com.
Issues and pull requests are welcome.
npm install
npm run build
npm run build:dashboard
npm testThe test suite starts its own PostgreSQL and Redis containers, so Docker is the only thing you need running.
Questions, bugs, or ideas: contact.devkitshq@gmail.com, or open an issue. If notifkit saved you from building notification plumbing, a star helps other developers find it.
MIT. Use it for anything, including commercially. Every feature is in this repository: there is no paid edition and no hosted tier.