by devkitshq
The notification infra of your business
# Add to your Claude Code skills
git clone https://github.com/devkitshq/notifkitLast scanned: 8/29/2026
{
"issues": [
{
"type": "npm-audit",
"message": "@esbuild-kit/core-utils: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "@esbuild-kit/esm-loader: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "@google-cloud/firestore: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "@google-cloud/storage: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "@vitest/coverage-v8: Vulnerability found",
"severity": "critical"
},
{
"type": "npm-audit",
"message": "@vitest/mocker: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "brace-expansion: brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash",
"severity": "high"
},
{
"type": "npm-audit",
"message": "drizzle-kit: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "esbuild: esbuild enables any website to send any requests to the development server and read the response",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "fast-uri: fast-uri vulnerable to host confusion via literal backslash authority delimiter",
"severity": "high"
},
{
"type": "npm-audit",
"message": "firebase-admin: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "gaxios: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "google-gax: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "js-yaml: JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) — CVE-2026-59870 fix not backported",
"severity": "high"
},
{
"type": "npm-audit",
"message": "nanoid: nanoid: custom generators can loop indefinitely when size is zero",
"severity": "high"
},
{
"type": "npm-audit",
"message": "postcss: PostCSS: incomplete fix of GHSA-6g55-p6wh-862q — attacker-controlled sourceMappingURL reads arbitrary .map files when `from` is unset",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "retry-request: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "teeny-request: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "undici: undici vulnerable to downstream response desynchronization via retry interceptor",
"severity": "high"
},
{
"type": "npm-audit",
"message": "uuid: uuid: Missing buffer bounds check in v3/v5/v6 when buf is provided",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "vite: Vite Vulnerable to Path Traversal in Optimized Deps `.map` Handling",
"severity": "high"
},
{
"type": "npm-audit",
"message": "vite-node: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "vitest: Vulnerability found",
"severity": "critical"
}
],
"status": "FAILED",
"scannedAt": "2026-08-29T10:50:17.836Z",
"npmAuditRan": true,
"pipAuditRan": true,
"promptInjectionRan": true
}notifkit is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by devkitshq. The notification infra of your business. It has 101 GitHub stars.
notifkit failed SkillsLLM's automated security scan, which flagged one or more high-severity issues. Review the Security Report section carefully before using it.
Clone the repository with "git clone https://github.com/devkitshq/notifkit" and add it to your Claude Code skills directory (see the Installation section above).
notifkit is primarily written in TypeScript. It is open-source under devkitshq on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh notifkit against similar tools.
No comments yet. Be the first to share your thoughts!
Requires a passing catalog security scan. Resolve the flagged issues and resubmit to enable featuring.
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
You shouldn't have to build a notification system.
Self-hosted notification infrastructure for product notifications. One API call handles email, SMS, push, and webhooks — with preferences, quiet hours, retries, fallback, scheduling, workflows, and delivery logs built in.
Documentation · Quickstart · Examples · notifkit.dev
await sendEmail({
to: user.email,
subject: "Order Shipped",
...
});
Users opt out. People are asleep. Push tokens die. Providers throw 503s. Some channels fail and need fallback. You need timezone-aware quiet hours, future scheduling, deduplication, multi-channel templates, delivery logs, unsubscribe handling, multi-step workflows, and a dead-letter queue nobody wants to maintain.
notifkit is that machinery, already built.
Your app makes one typed call. notifkit handles the rest — who gets it, which channel to use, when to send it, whether they're allowed to receive it, and what happens when delivery fails.
import { notifkit } from "notifkit";
await notifkit.notify({
user: "usr_123",
template: "order-shipped",
channels: ["push", "email"],
fallback: true,
});
Push first. If it fails, email.
Preferences, consent, quiet hours, retries, deduplication, throttling, template rendering, and delivery tracking happen behind that single call.
notifkit is both an orchestration engine and a typed SDK.
flowchart TD
App["Your Application / AI Agent<br/>Typed SDK · REST API · MCP Server"]
App -->|"HTTP POST /v1/notify"| API
API["Notifkit API Server<br/>Schema Validation · Auth · Multi-Tenancy<br/>Idempotency Gate · Priority Queue Ingestion"]
API --> PG
API --> REDIS
PG[("PostgreSQL — Storage<br/>Users · Preferences<br/>Templates · Workflows<br/>Delivery Logs · DLQ")]
REDIS[("Redis — Streams / ZSET<br/>Priority Queues<br/>Scheduled Sends<br/>Sliding Rate Limits")]
subgraph WORKERS["Background Workers Pipeline"]
direction LR
ENRICH["Enricher<br/>(Resolve)"] --> ENGINE["Engine<br/>(Quiet Hours)"] --> DELIVER["Delivery<br/>(Rate Limits / CB)"]
ENGINE --> SCHED["Scheduler<br/>(sendAt / QH)"]
SCHED --> DELIVER
end
REDIS -->|"consume"| ENRICH
ENRICH -.->|"read / write state"| PG
DELIVER -.->|"delivery logs"| PG
DELIVER -->|"Dispatch"| PROVIDERS
PROVIDERS["Provider Transports<br/>Email: Resend, SES, Postmark · Push: Firebase (FCM)<br/>SMS: Twilio, MessageBird · Webhooks: Custom HTTP"]
classDef entry stroke:#6366f1,stroke-width:2px
classDef store stroke:#0ea5e9,stroke-width:2px
classDef work stroke:#22c55e,stroke-width:2px
class App,API,PROVIDERS entry
class PG,REDIS store
class ENRICH,ENGINE,DELIVER,SCHED work
NotifkitServer: Runs the HTTP REST API router (/v1/notify, /health, /metrics) and the background worker pipelines (enricher, decision engine, scheduler, delivery).NotifkitClient: The lightweight client your application uses to trigger notifications, sync templates, and manage users over HTTP.services: ["all"]). Perfect for small-to-medium apps, side projects, and staging.services: ["api"]) behind a load balancer and scale worker pools (services: ["enricher", "engine", "delivery", "scheduler"]) horizontally across Redis Streams consumer groups.Battle-tested in production: notifkit powers production notification pipelines handling thousands of emails, push notifications, and OTPs every day.
It is the infrastructure we built because we needed it ourselves — rather than spending months reinventing distributed notification plumbing or paying SaaS tolls per alert.
Your servers. Your providers. Your data. Zero notification SaaS markups.
Because notification delivery is mission-critical, every pipeline component is tested against extreme failure conditions:
flowchart LR
S1["Redis Streams"] -->|"Kill Worker (SIGKILL)"| M1["Auto-Claim and Replay"] --> O1["Zero Lost Messages"]
S2["Connection Loss"] -->|"Drop DB / Redis"| M2["Auto-Reconnect / Retry"] --> O2["In-Flight State Intact"]
S3["10k+ Messages"] -->|"Burst"| M3["Concurrency and Limits"] --> O3["Flat Memory, No Leaks"]
classDef fault stroke:#ef4444,stroke-width:2px
classDef guard stroke:#6366f1,stroke-width:2px
classDef result stroke:#22c55e,stroke-width:2px
class S1,S2,S3 fault
class M1,M2,M3 guard
class O1,O2,O3 result
tests/chaos/crash.test.ts): Background worker processes are randomly terminated with SIGKILL during active, high-throughput message streaming. Consumer group Pending Entries List (PEL) re-claims guarantee zero lost messages and seamless failover.tests/chaos/recovery.test.ts): PostgreSQL and Redis connections are forcefully severed and restored under live traffic. Verifies automatic client reconnection, worker backpressure, and durable state resumption.tests/chaos/load.test.ts): Stressed with bursts of 10,000+ notifications across parallel worker pools, verifying queue drain velocity, sliding-window rate limiters, and flat memory profiles without leaks.tests/race-conditions.test.ts, tests/idempotency.test.ts): Hardened against concurrent duplicate dispatches, overlapping quiet-hour boundary evaluations, atomic user updates, and 24-hour idempotency key deduplication.| The problem you don't want to build | How notifkit solves it |
|---|---|
| “Should this user receive it?” | User preferences, topic opt-outs, and consent gates |
| “Is this a bad time to send?” | Timezone-aware quiet hours that defer non-urgent sends |
| “What if push fails?” | Automatic ordered multi-channel fallback (push → email → sms) |
| “What if my worker crashes?” | Redis Streams consumer groups, retries, and durable idempotency |
| “What if an event fires twice?” | 24-hour deduplication via idempotency keys |
| “Can I send this later?” | Priority scheduling with sendAt and cancellation before dispatch |
| “Can I send this 3 days after signup?” | Stateful multi-step workflows with wait and waitForEvent |
| “How do I know what happened?” | Queryable delivery logs, Prometheus metrics, and campaign reporting |
| “What happens when a provider goes down?” | Circuit breakers, exponential backoff, and DLQ replay |
| “What about bounces and spam complaints?” | RFC 8058 one-click unsubscribe and automatic hard-bounce suppression |
| “What if I don't want another SaaS holding my data?” | 100% self-hosted on your PostgreSQL and Redis |
The idea is simple: You decide what to say. notifkit handles getting it there reliably.
What it is: the durable notification infrastructure layer running directly inside your own stack.
What it isn't: a marketing automation suite.
notifkit is not Customer.io, OneSignal, or SendGrid. You bring your own provider accounts — your keys, your billing, your deliverability.
First-party providers ship for Resend and Firebase Cloud Messaging. Anything else is a simple Transport class with a send() method.
npm install notifkit @notifkit/provider-resend
import { NotifkitServer, NotifkitClient } from "notifkit";
import { ResendTransport } from "@notifkit/provider-resend";
// 1. Start the server (runs API + workers; auto-starts Postgres & Redis in dev)
const server = new NotifkitServer({
services: ["all"],
port: 3000,
providers: [new ResendTransport({ apiKey: process.env.RESEND_API_KEY! })],
});
await server.start();
// 2. Instantiate client and register a template
const notifkit = new NotifkitClient({ baseUrl: "http://localhost:3000" });
await notifkit.syncTemplates({