Webhooks for Next.js, done right
Verified, typed, idempotent webhook receivers for the App Router. Zero dependencies, runs on Node and Edge.
pnpm add next-webhooksapp/api/webhooks/stripe/route.ts
import { webhook, stripe } from "next-webhooks";
import { z } from "zod";
export const POST = webhook({
provider: stripe({ secret: process.env.STRIPE_WEBHOOK_SECRET! }),
events: {
"invoice.paid": z.object({ id: z.string(), amount_due: z.number() }),
},
on: {
"invoice.paid": async (event) => {
// event.payload is validated and typed from the schema
},
},
});Verified signatures
Every delivery is checked before your handler runs. Forged requests get a 401 with the reason.
Duplicates skipped
The same event id is acknowledged once. A failed handler releases it, so the retry is processed. Ready-made Upstash store for serverless.
Validated, typed events
Declare payloads with zod, valibot, or arktype schemas. Validated at runtime, types inferred, handlers routed per event.
Zero dependencies
About 2 kB gzipped. Web Crypto only, no provider SDKs, nothing added to your lockfile.
Node and Edge
The same route handler runs on a server, on serverless, or on the Edge runtime.
Dev tools
Scaffold routes, fire signed events at localhost, capture and replay real deliveries, and check your setup with the CLI.