Skip to content

Getting started

Terminal window
npm install verihook

verihook has no runtime dependencies. It uses the Web Crypto API, with a Node.js fallback, so it runs on Node.js 18.17+, Deno, Bun, Cloudflare Workers and Vercel Edge.

Pass the provider, the incoming request and your webhook secret:

import { verifyWebhook } from 'verihook';
export async function POST(request: Request) {
const result = await verifyWebhook('github', request, process.env.GITHUB_WEBHOOK_SECRET!);
if (!result.valid) {
// result.code says what failed; result.hint often says why
return new Response('Invalid signature', { status: 401 });
}
console.log(result.eventType); // "push", "issues", ...
return Response.json({ received: true });
}

request can be:

  • a Fetch Request (Next.js route handlers, Hono, Cloudflare Workers, Deno, Bun);
  • an object { headers, body, url? }, where body is the raw body as a string or bytes.

Signatures are computed over the exact bytes the provider sent. If a body parser has already turned the body into an object, verification fails. Why the raw body matters explains how to keep it in each framework.

The adapters read the raw body, verify it and answer failed requests for you:

app/api/webhooks/stripe/route.ts
import { createWebhookHandler } from 'verihook/next';
export const POST = createWebhookHandler('stripe', process.env.STRIPE_WEBHOOK_SECRET!, async (payload, result) => {
// Runs only when the signature is valid
});

See the Frameworks section for Express, Fastify, Hono, NestJS, Nuxt, SvelteKit, Remix, Astro and AWS Lambda.