Back to Resources Resource

ngrok & Cloudflare Tunnel - Expose Localhost to the World

Share your local development server with anyone. Perfect for webhook testing, mobile testing, client demos, and collaboration.

You're developing locally and need to test a webhook from Stripe. Or show a client your work-in-progress. Or test on your actual phone. Localhost tunneling gives your local server a public URL instantly - no deployment required.

🌐

Public URL in Seconds

Turn localhost:3000 into a public HTTPS URL. Share with anyone, anywhere - no configuration, no deployment, no firewall headaches.

How Tunneling Works

Tunneling creates a secure connection between your local machine and a public server, forwarding requests to your localhost:

YOUR MACHINE localhost:3000 TUNNEL SERVICE ngrok / Cloudflare abc123.ngrok.io myapp.trycloudflare.com INTERNET Webhooks, Mobile, Clients, Testers USERS Webhook Secure Tunnel Public HTTPS Requests forwarded to your localhost - responses sent back through tunnel

Traffic flows from the internet through the tunnel service directly to your local development server

Key Features

Instant URLs

One command gives you a public URL. No signup required for basic use. Start sharing in under 10 seconds

🔒

HTTPS by Default

All tunnel URLs are HTTPS with valid certificates. Test OAuth callbacks, secure webhooks, and more

🔍

Webhook Inspection

See every request in real-time. Inspect headers, body, replay requests. Debug webhooks without console.log

📱

Mobile Testing

Test on real devices without deploying. Open the tunnel URL on your phone and see your local app

Practical Examples

ngrok is the most popular tunneling tool. Here's how to expose your local server:

Terminal - Basic ngrok usage
# Install ngrok (macOS)
brew install ngrok

# Or download from ngrok.com and add to PATH

# Expose your local server on port 3000
ngrok http 3000

# Output:
# Forwarding    https://abc123.ngrok.io -> http://localhost:3000
#
# Web Interface http://127.0.0.1:4040  (inspect requests here!)

# Expose with custom subdomain (requires paid plan)
ngrok http 3000 --subdomain=myapp

# Expose with basic auth protection
ngrok http 3000 --basic-auth="user:password"

# Expose a specific host header (for virtual hosts)
ngrok http 3000 --host-header=myapp.local

Cloudflare Tunnel is a free alternative with no rate limits:

Terminal - Cloudflare Tunnel
# Install cloudflared (macOS)
brew install cloudflared

# Quick tunnel - no account needed!
cloudflared tunnel --url http://localhost:3000

# Output:
# Your quick Tunnel has been created!
# https://random-words.trycloudflare.com

# For permanent tunnels, authenticate first
cloudflared tunnel login

# Create a named tunnel
cloudflared tunnel create my-tunnel

# Run the tunnel
cloudflared tunnel run --url http://localhost:3000 my-tunnel

Inspecting webhook requests with ngrok's web interface:

Webhook debugging workflow
# 1. Start your local server
npm run dev  # Running on localhost:3000

# 2. Start ngrok in another terminal
ngrok http 3000

# 3. Copy the HTTPS URL (e.g., https://abc123.ngrok.io)

# 4. Configure the webhook provider (Stripe, GitHub, etc.)
#    Use: https://abc123.ngrok.io/webhooks/stripe

# 5. Open the inspection interface
#    http://127.0.0.1:4040

# 6. Trigger a webhook event (e.g., make a test purchase)

# 7. See the request in the ngrok inspector:
#    - Full request headers
#    - Request body (JSON formatted)
#    - Response from your server
#    - Timing information

# 8. Click "Replay" to resend any request for debugging

Why Developers Love It

  • Test Webhooks Locally - Stripe, GitHub, Twilio - receive webhooks on localhost without deploying
  • Real Device Testing - Test your responsive design on actual phones, not emulators
  • Client Demos - Show work-in-progress to clients without deploying to staging
  • OAuth Callbacks - Test OAuth flows that require HTTPS redirect URLs
  • Team Collaboration - Share your branch with teammates for testing before PR
  • Debug External Services - See exactly what third-party services send you

Common Use Cases

Use Case Problem Tunnel Solution
Webhook Testing Services can't reach localhost Public URL receives webhooks, forwards to local
Mobile Testing Phone can't access laptop's localhost Open tunnel URL on phone to test real device
OAuth Callbacks OAuth requires HTTPS callback URL Tunnel provides valid HTTPS certificate
Client Demos Client can't see local work Share tunnel URL - instant preview
QA Testing QA team can't access dev machine Share URL for pre-deployment testing
API Development Frontend dev needs your local API They hit tunnel URL, you see requests

Cheatsheet

Quick reference for ngrok and Cloudflare Tunnel commands:

Task ngrok Cloudflare Tunnel
Basic tunnel ngrok http 3000 cloudflared tunnel --url localhost:3000
HTTPS only ngrok http https://localhost:3000 Default behavior
Custom subdomain ngrok http 3000 --subdomain=myapp Requires DNS setup
Password protect ngrok http 3000 --basic-auth="u:p" Use Cloudflare Access
TCP tunnel ngrok tcp 22 cloudflared tunnel --url tcp://localhost:22
Inspect UI http://127.0.0.1:4040 Cloudflare dashboard
Pricing Free tier + paid plans Free (unlimited)

Pro Tips

🔄

Replay Failed Webhooks

In ngrok's web interface at 127.0.0.1:4040, click "Replay" on any request. Perfect for debugging webhook handlers without triggering real events again.

📋

Use ngrok.yml for Config

Create ~/.ngrok2/ngrok.yml to save your settings. Define tunnels, auth, regions - then just run ngrok start myapi.

💰

Cloudflare for Free Production Tunnels

Unlike ngrok, Cloudflare tunnels are completely free with no rate limits. Great for self-hosting or exposing home lab services permanently.

🚧

Integrate with npm Scripts

Add to package.json: "tunnel": "ngrok http 3000". Run npm run tunnel alongside your dev server with concurrently.

🔒

Secure Sensitive Demos

Use --basic-auth to password-protect tunnel URLs. Share credentials only with intended viewers. Remember: anyone with the URL can access your local server!

Getting Started

  1. 1

    Install Your Preferred Tool

    ngrok: brew install ngrok or download from ngrok.com. Cloudflare: brew install cloudflared

  2. 2

    Start Your Local Server

    Run your development server as usual (e.g., npm run dev on port 3000)

  3. 3

    Create the Tunnel

    Run ngrok http 3000 or cloudflared tunnel --url localhost:3000 in another terminal

  4. 4

    Share the Public URL

    Copy the HTTPS URL from the output. Anyone can now access your local server through this URL!

Start Tunneling Today

Stop deploying just to test webhooks. Expose your localhost in seconds with ngrok or Cloudflare Tunnel.

Explore More Resources