Stop fightingwebhooks.
The local-first toolkit for capturing, replaying, and shipping type-safe webhook handlers in TypeScript.
Quick Install
1import { github } from "@better-webhook/github";2import { push, pull_request } from "@better-webhook/github/events";3import { toNextJS } from "@better-webhook/nextjs";45const webhook = github()6 .event(push, async (payload) => {7 console.log(payload.repository.name);8 console.log(payload.commits.length);9 })10 .event(pull_request, async (payload) => {11 if (payload.action === "opened") {12 await notifyTeam(payload.pull_request);13 }14 });1516export const POST = toNextJS(webhook);Get started in 60s
Choose how you want to work with webhooks — capture and replay with the CLI, or build type-safe handlers with the SDK.
Install the CLI
$ brew install --cask endalk200/tap/better-webhookStart capture server
$ better-webhook capture --port 3001Stores incoming webhooks locally under ~/.better-webhook/captures
Point webhooks to capture server
http://localhost:3001/webhooks/your-providerUse this URL in your webhook provider settings (e.g., GitHub webhook URL)
Replay captured webhooks
$ better-webhook captures replay <capture-id> http://localhost:3000/api/webhooks/githubReplay to your local development server
Everything you need for webhook dev
A focused toolkit for fast, repeatable webhook development — from local testing to production handlers.
Live Capture
Start a local server to capture incoming webhooks with headers, path, and payload preserved.
Smart Replay
Replay captured webhooks to any endpoint with full header preservation. Test handlers without re-triggering events.
Signature Verification
Automatic signature verification for GitHub, Stripe, Ragie, and Recall.ai with timing-safe comparison.
Type-Safe Handlers
Full TypeScript support with Zod schemas. Get autocomplete for every event payload property.
Fast Native Binary
Install a prebuilt Go binary from Homebrew or GitHub Releases with no Node.js runtime requirement.
Framework Adapters
First-class integrations for Next.js, Hono, Express, NestJS, and GCP Cloud Functions.
Auto Signatures
CLI generates valid signatures when running templates. Test signature verification without manual setup.
Curated Templates
Download and run built-in webhook templates for GitHub, Stripe, Ragie, and Recall.ai with realistic payloads.
Capture. Replay. Test.
A powerful CLI for local webhook development. Capture real webhooks, replay them on demand, and test your handlers.
Capture
Start a local server to intercept and store incoming webhooks
better-webhook captureReplay
Re-send captured webhooks to any endpoint with full headers
better-webhook captures replay <id> <url>Templates
Download and run curated templates for GitHub, Ragie, and Recall.ai
better-webhook templates listInstall with Homebrew
$ brew install --cask endalk200/tap/better-webhookType-safe. Verified. Simple.
Build webhook handlers with full TypeScript support, automatic signature verification, and Zod schema validation.
Signature Verification
Automatic HMAC verification for all providers. Timing-safe comparison prevents attacks.
Type-Safe Handlers
Full TypeScript support with Zod schemas. Autocomplete for every payload property.
Framework Adapters
First-class support for Next.js, Hono, Express, NestJS, and GCP Functions.
import { github } from "@better-webhook/github";
import { push, pull_request } from "@better-webhook/github/events";
import { toNextJS } from "@better-webhook/nextjs";
const webhook = github()
.event(push, async (payload) => {
console.log(`Push to ${payload.repository.name}`);
console.log(`${payload.commits.length} commits`);
})
.event(pull_request, async (payload) => {
if (payload.action === "opened") {
console.log(`New PR: ${payload.pull_request.title}`);
}
})
.onError((error, context) => {
console.error(`Error in ${context.eventType}`, error);
});
export const POST = toNextJS(webhook);Available Providers
GitHub
@better-webhook/githubRagie
@better-webhook/ragieStripe
@better-webhook/stripeRecall.ai
@better-webhook/recallResend
@better-webhook/resendSee the difference
Compare traditional webhook handling with better-webhook. Less boilerplate, more safety.
1// The better-webhook way - type-safe and secure23import { github } from "@better-webhook/github";4import { push } from "@better-webhook/github/events";5import { toExpress } from "@better-webhook/express";67const webhook = github()8 .event(push, async (payload) => {9 // Full autocomplete and type safety!10 console.log(payload.repository.name);11 console.log(payload.commits.length);12 13 for (const commit of payload.commits) {14 console.log(commit.message);15 }16 })17 .onError((error, context) => {18 logger.error(`Failed: ${context.eventType}`, error);19 });2021app.post('/webhooks/github',22 express.raw({ type: 'application/json' }),23 toExpress(webhook)24);What changes
Webhook Providers
Pre-built providers with automatic signature verification and fully typed payloads. Create custom providers for any webhook source.
GitHub
Ragie
Stripe
Recall.ai
Resend
Custom
GitHub
@better-webhook/githubExample Events
Ragie
@better-webhook/ragieExample Events
Stripe
@better-webhook/stripeExample Events
Recall.ai
@better-webhook/recallExample Events
Resend
@better-webhook/resendExample Events
Need a different provider? Create custom webhooks with the core package.