npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@azizikri/hookpipe

v1.0.3

Published

Self-hosted webhook relay with transform pipelines

Readme

hookpipe

Self-hosted webhook relay with transform pipelines. Receive webhooks, authenticate, filter, transform, and deliver to one or more destinations. Built for self-hosted environments where you control the infrastructure.

Quick Start — Docker

docker build -t hookpipe -f docker/Dockerfile .
docker run -p 3000:3000 -v ./pipelines:/app/pipelines -v ./data:/app/data hookpipe

Quick Start — Bare Metal

npm install
cp .env.example .env
mkdir -p pipelines data
node src/cli/index.js serve

Webhooks are received at POST /hook/:pipeline-id.

Pipeline YAML Schema

Pipelines are YAML files in the pipelines/ directory. Each file defines one pipeline.

Required Fields

| Field | Type | Description | |-------|------|-------------| | id | string | Unique pipeline identifier (must match filename) | | destinations | array | One or more delivery targets |

Each destination requires:

| Field | Type | Description | |-------|------|-------------| | id | string | Unique destination identifier within the pipeline | | type | string | Destination type (http) | | url | string | Target URL |

Optional Fields

| Field | Type | Description | |-------|------|-------------| | name | string | Human-readable pipeline name | | description | string | Pipeline description | | auth | object | Authentication configuration | | filter | string | Filter plugin name | | filter_config | object | Config passed to the filter plugin | | transform | string | Transform plugin name | | retry | object | Retry policy override |

Auth Configuration

| Field | Type | Description | |-------|------|-------------| | type | string | hmac-sha256 or hmac-sha1 | | secret | string | HMAC secret (supports ${ENV_VAR} interpolation) | | header | string | Header containing the signature |

Destination Options

| Field | Type | Description | |-------|------|-------------| | method | string | HTTP method (default: POST) | | headers | object | Additional headers to send | | body_template | string | Handlebars template for the request body | | timeout_ms | number | Request timeout in milliseconds | | on_failure | string | Failure behavior (retry or log) |

Complete Example

id: github-deploy
name: GitHub Deploy Notifications
description: Forward GitHub push events to deploy service

auth:
  type: hmac-sha256
  secret: ${GITHUB_WEBHOOK_SECRET}
  header: x-hub-signature-256

filter: github-event-filter
filter_config:
  events:
    - push
    - release

transform: extract-commit-info

destinations:
  - id: deploy-service
    type: http
    url: https://deploy.internal/api/trigger
    method: POST
    headers:
      authorization: Bearer ${DEPLOY_TOKEN}
    timeout_ms: 10000
    on_failure: retry

  - id: slack-notify
    type: http
    url: https://hooks.slack.com/services/T00/B00/xxx
    body_template: |
      {"text": "Deploy triggered by {{payload.pusher.name}} on {{payload.ref}}"}
    on_failure: log

retry:
  maxAttempts: 5
  backoff: exponential
  initialDelayMs: 2000
  maxDelayMs: 300000

Plugin API

Plugins are CommonJS modules loaded via createRequire (the project itself is ESM). Place them in the plugins/ directory.

Transform Plugin

// plugins/extract-commit-info.cjs
module.exports.transform = function (payload, headers, config) {
  // Return transformed payload object
  // Return null to drop the webhook entirely
  return {
    ref: payload.ref,
    commits: payload.commits.map(c => c.message),
    pusher: payload.pusher.name,
  };
};

Signature: transform(payload, headers, config) → object | null

  • payload — parsed JSON body of the incoming webhook
  • headers — request headers (lowercased keys)
  • config — the pipeline's filter_config object (shared namespace)
  • Returns the transformed payload, or null to drop the webhook

Filter Plugin

// plugins/github-event-filter.cjs
module.exports.filter = function (payload, headers, config) {
  const event = headers['x-github-event'];
  if (config.events.includes(event)) {
    return { pass: true };
  }
  return { pass: false, reason: `Event '${event}' not in allowed list` };
};

Signature: filter(payload, headers, config) → { pass: boolean, reason?: string }

  • Return { pass: true } to continue processing
  • Return { pass: false, reason: "..." } to reject the webhook

CLI Reference

hookpipe <command> [options]

hookpipe serve

Start the webhook server.

| Flag | Description | |------|-------------| | -p, --port <number> | Port to listen on | | -H, --host <string> | Host to bind to | | -c, --config <path> | Config file path | | --pipelines <dir> | Pipelines directory | | --plugins <dir> | Plugins directory |

hookpipe test <pipeline-id>

Dry-run a webhook through a pipeline without delivering.

| Flag | Description | |------|-------------| | -f, --file <path> | JSON file to use as payload | | -d, --data <json> | Inline JSON payload | | --header <header> | Custom header (repeatable, format: Key: Value) | | --skip-auth | Skip HMAC authentication check | | -c, --config <path> | Config file path |

hookpipe logs

Query delivery logs.

| Flag | Description | |------|-------------| | --pipeline <id> | Filter by pipeline ID | | --status <status> | Filter by status (success, failed, pending) | | --since <duration> | Show logs since duration (e.g. 1h, 7d) | | --limit <n> | Max number of entries (default: 50) | | --json | Output as JSON |

hookpipe replay <delivery-id>

Re-enqueue a previous delivery for reprocessing.

| Flag | Description | |------|-------------| | --dry-run | Show what would be replayed without enqueuing | | -c, --config <path> | Config file path |

Configuration

hookpipe loads configuration from a YAML file, environment variables, and CLI flags.

Precedence (highest wins): CLI flags > environment variables > YAML file > defaults

Config File

By default, hookpipe looks for hookpipe.yaml in the working directory. Override with --config or HOOKPIPE_CONFIG.

host: 0.0.0.0
port: 3000

db:
  path: ./data/hookpipe.db

log:
  level: info

pipelines:
  dir: ./pipelines

plugins:
  dir: ./plugins

retry:
  maxAttempts: 3
  backoff: exponential
  initialDelayMs: 1000
  maxDelayMs: 300000

queue:
  pollIntervalMs: 1000
  concurrency: 5

Environment Variables

| Variable | Maps to | Default | |----------|---------|---------| | HOOKPIPE_PORT | port | 3000 | | HOOKPIPE_HOST | host | 0.0.0.0 | | HOOKPIPE_DB_PATH | db.path | ./data/hookpipe.db | | HOOKPIPE_LOG_LEVEL | log.level | info | | HOOKPIPE_PIPELINES_DIR | pipelines.dir | ./pipelines | | HOOKPIPE_PLUGINS_DIR | plugins.dir | ./plugins | | HOOKPIPE_CONFIG | config file path | hookpipe.yaml |

Pipeline YAML values support ${ENV_VAR} interpolation for secrets.

Trust Model

hookpipe v1.0 has no sandbox. Plugins are loaded as plain Node.js modules with full access to the process, filesystem, and network.

This is by design for self-hosted environments where you control what code runs on your infrastructure. The tradeoff is simplicity and zero overhead in exchange for requiring trust in your plugins.

Guidelines:

  • Only load plugins you wrote or audited
  • Do not accept plugin uploads from untrusted sources
  • Run hookpipe with least-privilege OS permissions
  • Use Docker to limit blast radius if needed

v1.1 will add optional isolation for plugins.

Tech Stack

| Component | Role | |-----------|------| | Node.js 22+ | Runtime | | Fastify | HTTP server | | better-sqlite3 | Delivery queue and log storage | | Commander.js | CLI framework | | Pino | Structured logging | | Handlebars | Body templates | | chokidar | Pipeline hot-reload (file watching) |

Roadmap

v1.0 — Core (current)

  • Fastify HTTP server, YAML pipelines, env var interpolation
  • HMAC-SHA256/SHA1/Stripe authentication
  • JS transform + filter plugins (CJS, no sandbox)
  • HTTP destination adapter with Handlebars templates
  • SQLite delivery log, retry with exponential backoff, dead letter queue
  • Pipeline hot-reload via chokidar
  • CLI: serve, test, logs, replay
  • Docker image

v1.1 — Agent Layer

  • REST Admin API (CRUD pipelines, query logs, replay)
  • Agent registration + scoped API keys
  • Agent event queue (subscribe, poll, acknowledge)
  • SSE real-time event stream
  • Agent-writable transforms (runtime upload, sandboxed)
  • Plugin sandbox (isolated-vm)
  • Skills distribution via skills.sh

v1.2 — Polish

  • Destinations: Telegram, Discord, Slack, SMTP, File
  • Prometheus metrics endpoint
  • Rate limiting per pipeline
  • hookpipe init scaffolding
  • hookpipe validate pipeline linting

v1.3 — Scale

  • Redis/BullMQ queue backend
  • Horizontal scaling (multiple workers)
  • Pipeline chaining
  • TypeScript plugin support

License

MIT