If you're developing webhook integrations locally, you've probably used ngrok or a similar tunneling tool. It's the default recommendation in almost every webhook provider's documentation. But is it always the best approach?
In this post, we'll compare two fundamentally different approaches to local webhook development:
- Tunneling (ngrok, Cloudflare Tunnel, localtunnel) — Exposes your localhost to the internet
- Capture-and-Replay (HookReplay) — Captures webhooks and lets you replay them on demand
Spoiler: they're not mutually exclusive. The best approach depends on what you're trying to do.
How Tunneling Works
Tools like ngrok create a secure tunnel from the public internet to your local machine. When Stripe (or any webhook provider) sends a request to your ngrok URL, it gets forwarded to your localhost.
Stripe --> ngrok.io --> ngrok client --> localhost:3000
Pros:
- Real-time webhook delivery
- Works with any webhook provider
- No code changes needed
- Great for demos and testing with external collaborators
Cons:
- Free tier gives you a new URL on every restart
- You need to re-trigger webhooks every time you want to test
- Can't easily test the same payload multiple times
- Debugging with breakpoints is tricky (webhook times out while you're stepping through code)
- Requires internet connection
How Capture-and-Replay Works
HookReplay takes a different approach. Instead of tunneling, it captures webhooks at a stable URL and lets you replay them to localhost whenever you want.
Stripe --> HookReplay (captures & stores)
Later, on demand:
HookReplay --> CLI --> localhost:3000
Pros:
- Replay the same webhook as many times as you need
- Debug with breakpoints at your own pace
- Edit payloads to test edge cases
- Stable URL that never changes
- Works offline (once captured)
- Full history of all webhooks received
Cons:
- Not real-time (you trigger replays manually)
- Requires initial setup of CLI
- Not suitable for demos where external parties need to see live updates
When to Use ngrok
Tunneling is the right choice when:
- You're doing a live demo and need real-time updates
- You're setting up a new integration and want to see what payloads look like
- External collaborators need to access your local server
- You're testing OAuth callbacks or other redirect flows
When to Use HookReplay
Capture-and-replay is the right choice when:
- You're debugging a specific webhook handler
- You need to set breakpoints and step through code
- You want to test the same payload multiple times
- You need to test edge cases by modifying payloads
- You're reproducing a production bug with a specific payload
- You're working offline or have an unstable connection
Side-by-Side Comparison
| Feature | ngrok | HookReplay |
|---|---|---|
| Real-time delivery | Yes | No (on-demand) |
| Stable URL (free tier) | No (changes on restart) | Yes |
| Replay same webhook | No (must re-trigger) | Yes (unlimited) |
| Edit payload before sending | No | Yes |
| Breakpoint debugging | Difficult (timeouts) | Easy (you control timing) |
| Webhook history | Limited (paid plans) | Yes (all plans) |
| Works offline | No | Yes (replay cached webhooks) |
| Good for demos | Yes | No |
| Good for debugging | Okay | Excellent |
The Best of Both Worlds
Here's a secret: you don't have to choose. Many developers use both tools for different purposes:
- Use ngrok for initial integration setup — When you're first connecting to a webhook provider and want to see what payloads look like
- Switch to HookReplay for debugging — Once you have real payloads captured, use HookReplay to debug your handler code
You can even use them together: point your webhook provider at HookReplay, which captures everything, and only use ngrok when you specifically need real-time delivery.
Real-World Workflow
Here's how a typical development session might look:
Day 1: Setting up Stripe integration
You're integrating Stripe payments for the first time. You use ngrok to expose your local server and configure Stripe to send webhooks there. You trigger test payments and see what events arrive.
Day 2: Building the webhook handler
Now you're writing the actual handler code. You switch to HookReplay, capture a
payment_intent.succeeded event, and replay it 50 times while you debug your code.
No need to create 50 test payments.
Week 3: Production bug
A customer reports that their subscription wasn't created after payment. You look at your HookReplay dashboard, find the exact webhook that failed, and replay it locally with breakpoints to find the bug. Fixed in 10 minutes instead of 3 hours.
Pricing Comparison
| Plan | ngrok | HookReplay |
|---|---|---|
| Free | Random URLs, 1 agent, limited requests | 1 endpoint, 50 webhooks/month, unlimited replays |
| Paid (starting) | $8/month (stable domains) | $9/month (unlimited endpoints) |
Both tools offer generous free tiers that are suitable for individual developers. The paid tiers become valuable when you need stable URLs, more endpoints, or team features.
Summary
ngrok is great for real-time tunneling, demos, and initial integration setup. It's the Swiss Army knife of local development.
HookReplay is purpose-built for webhook debugging. When you need to replay the same webhook 100 times, edit payloads, or debug with breakpoints, it's the right tool.
The best developers use both — ngrok for exposure, HookReplay for debugging. Pick the right tool for the job.