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

@cmer/localhook

v1.3.0

Published

Webhook interceptor and testing tool. Capture and inspect HTTP requests locally with a real-time dashboard. Test Stripe, GitHub, Shopify, Twilio, SendGrid, and any other webhooks without third-party services. Zero config

Downloads

452

Readme

LocalHook

Local webhook testing tool. Like webhook.site, but on your machine.

Send webhooks to localhost instead of a third-party service. Inspect request details, headers, and body in a real-time dashboard. Optionally forward the incoming webhook to your application.

LocalHook Dashboard

Features

  • Public HTTPS Tunnel -- built-in support for HTTPS tunnel via Tailscale or Cloudflare
  • Real-time -- requests appear instantly via Server-Sent Events, no refresh needed
  • All HTTP methods -- GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
  • Request inspection -- method, URL, headers, query parameters, body
  • Request forwarding -- optionally forward incoming requests to your own application
  • JSON formatting -- auto-detects and pretty-prints JSON with syntax highlighting
  • Zero config -- no database, no build step, no accounts
  • Terminal logging -- see requests in your terminal without opening the dashboard

Quick Start

npx @cmer/localhook

Then send requests to http://localhost:3000/any-path (or the public URL) and watch them appear in the dashboard.

Usage

# Default port 3000
npx @cmer/localhook

# Custom port
npx @cmer/localhook --port 8080

# Expose via Tailscale Funnel
npx @cmer/localhook --tailscale

# Expose via Cloudflare Quick Tunnel (no account required)
npx @cmer/localhook --cloudflare

# Custom port with Tailscale
npx @cmer/localhook --port 8080 --tailscale

# Allow dashboard access from the public URL (password-protected)
npx @cmer/localhook --tailscale --allow-remote-access --password mysecret

# Forward webhooks to your local app
npx @cmer/localhook --forward-to http://localhost:4444

# Forward with a base path
npx @cmer/localhook --forward-to http://localhost:4444/api/webhooks

| Flag | Short | Description | |---|---|---| | --port <port> | -p | Port to listen on (default: 3000) | | --tailscale | | Start Tailscale Funnel for a public HTTPS URL | | --cloudflare | | Start Cloudflare Quick Tunnel for a public HTTPS URL | | --allow-remote-access | | Allow dashboard/API access from non-localhost (e.g. via tunnel) | | --password <value> | | Require HTTP Basic Auth for remote dashboard/API access (localhost is never challenged) | | --data-file <path> | | Path to data file (default: ~/.localhook/data.json) | | --forward-to <url> | | Forward incoming webhooks to a local app (preserves method, path, headers, body) | | --help | -h | Show help |

Open http://localhost:3000 in your browser to see the dashboard.

Any HTTP request to any path (except /) gets captured:

curl -X POST http://localhost:3000/webhook \
  -H "Content-Type: application/json" \
  -d '{"event": "user.created", "user_id": "123"}'

Webhook Forwarding

Use --forward-to to forward incoming webhooks to your local application while still capturing them in the dashboard:

npx @cmer/localhook --forward-to http://localhost:4444

Every captured webhook is forwarded synchronously — your app receives the original HTTP method, path, query string, headers (including signature headers like x-stripe-signature), and body. The caller (e.g. Stripe) receives your app's actual response, so retries work correctly on 5xx errors.

You can also specify a base path that gets prepended to the webhook path:

# Webhook to /events → forwarded to http://localhost:4444/api/webhooks/events
npx @cmer/localhook --forward-to http://localhost:4444/api/webhooks

The dashboard shows forwarding results: status code, duration, and response body for each request. If the target is unreachable, the caller receives a 502 and the error is displayed in the dashboard.

Combine with a tunnel for end-to-end webhook testing:

npx @cmer/localhook --cloudflare --forward-to http://localhost:4444

Testing with External Services

If you need to receive webhooks from external services like Stripe, GitHub, or Shopify, they need a public URL to send requests to.

Tailscale Funnel (built-in)

My favorite. Use the --tailscale flag to automatically start Tailscale Funnel alongside LocalHook:

npx @cmer/localhook --tailscale

This gives you a public HTTPS URL like https://myhost.tail1234.ts.net. Use that as your webhook URL in Stripe, GitHub, etc.

Requires Tailscale to be installed with Funnel enabled.

Cloudflare Quick Tunnel (built-in)

Use the --cloudflare flag to start a Cloudflare Quick Tunnel — no account or login required:

npx @cmer/localhook --cloudflare

This gives you a public HTTPS URL like https://random-words.trycloudflare.com. Use that as your webhook URL in Stripe, GitHub, etc.

Requires cloudflared to be installed. The URL changes each time you restart.

Note: --tailscale and --cloudflare are mutually exclusive — use one or the other.

Note: The dashboard is always restricted to localhost by default. Requests through reverse proxies (Tailscale Funnel, ngrok, Cloudflare Tunnel, etc.) are automatically detected and blocked from accessing the dashboard. Use --allow-remote-access to override this, and --password to require authentication for remote access.

Other tunneling services

You can also use any other tunneling service manually, such as ngrok.

REST API

LocalHook has a REST API for programmatic access to captured webhooks. See API.md for full documentation with example requests.

How It Works

LocalHook runs a single Express server. GET / serves the dashboard. Every other request is captured as a webhook and broadcast to the dashboard via SSE.

Data is stored in ~/.localhook/data.json by default (max 500 entries). Use --data-file to override.

License

MIT