{"id":17662,"library":"github-webhook-handler","title":"GitHub Webhook Handler","description":"github-webhook-handler is a Node.js library providing a minimalist handler or middleware for processing GitHub Webhooks. It simplifies the process of receiving and verifying webhook requests, acting as an EventEmitter for various GitHub events such as `push` or `issues`. The current stable version is 2.1.1, released in April 2026, following a major v2.0.0 release in January 2026 that introduced ESM support, promises, and updated Node.js requirements (>=20). This package differentiates itself by focusing specifically on GitHub webhooks, handling SHA-1 HMAC signature verification and event parsing, allowing developers to quickly integrate webhook processing into their Node.js applications without dealing with low-level HTTP request body parsing and security checks. It features a straightforward API for creating a handler function that can be integrated into standard Node.js HTTP servers, designed for developers who need a robust, event-driven way to react to GitHub repository activity.","status":"active","version":"2.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/rvagg/github-webhook-handler","tags":["javascript","github","webhooks","typescript"],"install":[{"cmd":"npm install github-webhook-handler","lang":"bash","label":"npm"},{"cmd":"yarn add github-webhook-handler","lang":"bash","label":"yarn"},{"cmd":"pnpm add github-webhook-handler","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Since v2.0.0, this package is ESM-only and exports `createHandler` as a default export. CommonJS `require` will not work.","wrong":"const createHandler = require('github-webhook-handler')","symbol":"createHandler","correct":"import createHandler from 'github-webhook-handler'"},{"note":"Type import for configuring the handler options, useful for TypeScript projects.","symbol":"HandlerOptions","correct":"import type { HandlerOptions } from 'github-webhook-handler'"},{"note":"Accesses the bundled JSON file containing GitHub event descriptions. Requires Node.js's JSON modules support (with { type: 'json' } assertion) for ESM.","wrong":"const events = require('github-webhook-handler/events.json')","symbol":"events","correct":"import events from 'github-webhook-handler/events.json' with { type: 'json' }"}],"quickstart":{"code":"import http from 'node:http'\nimport createHandler from 'github-webhook-handler'\n\n// Ensure these are secure in a production environment\nconst GITHUB_WEBHOOK_PATH = process.env.GITHUB_WEBHOOK_PATH ?? '/webhook'\nconst GITHUB_WEBHOOK_SECRET = process.env.GITHUB_WEBHOOK_SECRET ?? 'myhashsecret'\nconst LISTEN_PORT = parseInt(process.env.PORT ?? '7777', 10)\n\nconst handler = createHandler({ \n  path: GITHUB_WEBHOOK_PATH,\n  secret: GITHUB_WEBHOOK_SECRET \n})\n\nhttp.createServer((req, res) => {\n  handler(req, res, (err) => {\n    res.statusCode = 404\n    res.end('no such location')\n  })\n}).listen(LISTEN_PORT, () => {\n  console.log(`Server listening on port ${LISTEN_PORT} for GitHub webhooks at path ${GITHUB_WEBHOOK_PATH}`)\n})\n\nhandler.on('error', (err) => {\n  console.error('Error handling webhook:', err.message)\n})\n\nhandler.on('push', (event) => {\n  console.log('Received a push event for %s to %s', \n    event.payload.repository.name,\n    event.payload.ref)\n  // Add your logic here to react to a push event\n})\n\nhandler.on('issues', (event) => {\n  console.log('Received an issue event for %s action=%s: #%d %s', \n    event.payload.repository.name,\n    event.payload.action,\n    event.payload.issue.number,\n    event.payload.issue.title)\n  // Add your logic here to react to an issue event\n})\n\nconsole.log('GitHub webhook handler initialized.')","lang":"javascript","description":"This example demonstrates how to set up a basic Node.js HTTP server to listen for GitHub webhooks, create a handler, and respond to 'push' and 'issues' events, including error handling."},"warnings":[{"fix":"Migrate your project to use ES Modules (e.g., `\"type\": \"module\"` in `package.json`) and update your Node.js environment to version 20 or higher. Change `require()` statements to `import`.","message":"Version 2.0.0 introduced significant breaking changes: it switched to ESM-only (removing CommonJS support), updated its internal dependencies, and raised the minimum required Node.js version to 20. Applications using `require()` or older Node.js runtimes will fail.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Ensure the `secret` string provided to `createHandler({ secret: '...' })` exactly matches the 'Secret' configured in your GitHub repository's webhook settings. For security, retrieve secrets from environment variables rather than hardcoding.","message":"The `secret` option passed to `createHandler` is critical for verifying the `X-Hub-Signature` HMAC sent by GitHub. If the secret is missing, incorrect, or doesn't match the one configured in GitHub, all webhook requests will be rejected.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"In your GitHub repository's webhook settings, under 'Content type', select 'application/json'.","message":"GitHub webhook settings must be configured to send payloads as `application/json`. The library does not support `application/x-www-form-urlencoded` content types, and requests with this type will not be processed correctly.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always register an error handler: `handler.on('error', (err) => console.error('Webhook error:', err))`.","message":"The handler is an `EventEmitter` and will emit an `'error'` event for various issues (e.g., signature mismatch, invalid path). If no listener is registered for this event, Node.js will throw an unhandled `Error` and potentially crash the application.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Update your project to use ES Modules with `import createHandler from 'github-webhook-handler'` and ensure your `package.json` has `\"type\": \"module\"` if running in Node.js >=12, or use a `.mjs` file extension.","cause":"Attempting to use `require()` to import `github-webhook-handler` after v2.0.0, or using a named import `import { createHandler } from ...` when it's a default export.","error":"TypeError: createHandler is not a function"},{"fix":"Provide a non-empty string for the `secret` option: `createHandler({ path: '/webhook', secret: 'your_github_secret' })`. This secret must match the one configured in GitHub.","cause":"The `secret` option was omitted or passed as an empty string when creating the handler.","error":"Error: secret must be given"},{"fix":"Double-check that the `secret` value in your code precisely matches the 'Secret' configured in your GitHub webhook settings. Also, ensure the content type in GitHub is `application/json`.","cause":"The SHA-1 HMAC signature in the `X-Hub-Signature` header from GitHub does not match the signature calculated by the handler using the provided `secret`. This often indicates a mismatch in the secret key or a modified payload.","error":"Error: signature does not match"},{"fix":"Ensure your event listeners or the `next` callback only handle the response once. For instance, if an event listener processes the request, it should handle `res.end()`, and the `next` callback should be designed not to interfere if the request was successfully handled by the webhook.","cause":"This error occurs if you attempt to send headers or a response body after they have already been sent, often due to incorrect asynchronous flow or multiple `res.end()` calls.","error":"ERR_HTTP_HEADERS_SENT"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}