{"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,"search_vec":"'-1':85 '2.1.1':50 '20':72 '2026':54,62 'act':32 'activ':151 'allow':92 'api':120 'applic':102 'april':53 'bodi':111 'check':115 'creat':122 'current':46 'deal':104 'design':135 'develop':93,137 'differenti':75 'driven':144 'esm':65 'event':39,90,143 'event-driven':142 'eventemitt':35 'featur':117 'focus':78 'follow':55 'function':125 'github':1,5,20,38,81,149,153 'github-webhook-handl':4 'handl':83 'handler':3,7,15,124 'hmac':86 'http':109,133 'integr':96,129 'introduc':64 'issu':44 'januari':61 'javascript':152 'level':108 'librari':11 'low':107 'low-level':106 'major':57 'middlewar':17 'minimalist':14 'need':139 'node.js':10,70,101,132 'packag':74 'pars':91,112 'process':19,25,98 'promis':67 'provid':12 'push':42 'quick':95 'react':147 'receiv':27 'releas':51,59 'repositori':150 'request':31,110 'requir':71 'robust':141 'secur':114 'server':134 'sha':84 'signatur':87 'simplifi':23 'specif':79 'stabl':47 'standard':131 'straightforward':119 'support':66 'typescript':155 'updat':69 'v2.0.0':58 'various':37 'verif':88 'verifi':29 'version':48 'way':145 'webhook':2,6,21,30,82,97,154 'without':103","created_at":"2026-04-23T17:47:27.387529+00:00","updated_at":"2026-04-23T17:47:27.387529+00:00","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,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/rvagg/github-webhook-handler","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/github-webhook-handler","openapi_spec":null,"status_page":null,"smithery":null,"categories":["http-networking","devops","auth-security"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-22","install_tag":null}}