ngrok made “give my localhost a public URL” a one-liner, which is handy for showing work to a client, testing webhooks from Stripe or GitHub, or debugging a mobile app against a local API. But free-tier limits, changing URLs and the third-party relay lead many developers to look for alternatives. Here are the main options, from zero-setup hosted services to fully self-hosted tunnels on your own VPS.

Quick comparison

Tool Hosting Custom domain Best for
Cloudflare Tunnel Cloudflare Yes (domain on Cloudflare) Stable URLs, longer-running services, SSO via Access
Cloudflare quick tunnels Cloudflare Random trycloudflare.com URL Instant, throwaway testing
Tailscale Funnel Tailscale *.ts.net name Users already on Tailscale
localtunnel Public relay (or self-host) Subdomain request Quick npm-based sharing
SSH reverse tunnel Your VPS Yes, with Nginx No extra software
frp Your VPS Yes Full self-hosted control, many protocols
zrok Hosted or self-hosted (OpenZiti) Yes Private and public sharing, open source
Expose / sish / bore Self-hosted Varies Lightweight self-hosted tunnels

Cloudflare quick tunnel (no account needed)

cloudflared tunnel --url http://localhost:3000
# → https://random-words.trycloudflare.com

That gives you an instant HTTPS URL. It changes each run, so it’s for testing only. For a stable hostname on your domain, create a named tunnel. See Cloudflare Tunnel.

Tailscale Funnel

If your machine is on Tailscale:

tailscale funnel 3000
# → https://machine-name.tailnet-name.ts.net

Use tailscale serve to share only inside your tailnet, which is ideal for teammates. See Tailscale.

localtunnel

npx localtunnel --port 3000 --subdomain myproject

It’s simple, but public relays can be slow or unavailable, and visitors may see an interstitial page. You can self-host its server.

SSH reverse tunnel: zero extra software

If you have a VPS, OpenSSH alone can publish a local port:

ssh -N -R 8080:localhost:3000 user@your-vps

Port 8080 on the VPS now forwards to port 3000 on your laptop. By default it listens only on the VPS’s localhost. Put Nginx in front for a domain and HTTPS:

server {
    server_name dev.example.com;
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    # listen 443 ssl + certificate via certbot
}

Use autossh to keep the tunnel up automatically. See SSH tunnels and Nginx reverse proxy for WebSockets.

To expose the forwarded port publicly without Nginx, set GatewayPorts clientspecified in the VPS’s sshd_config and use -R 0.0.0.0:8080:localhost:3000, but HTTPS through Nginx is the better setup.

frp on your VPS

For many services, multiple developers, TCP and UDP, and custom domains with authentication, run frp on a small VPS. See frp reverse proxy.

Webhook development tips

  • Most webhook providers (Stripe, GitHub, Shopify) also offer CLI forwarding (e.g. stripe listen --forward-to localhost:3000/webhook) that doesn’t need a public URL at all.
  • Verify webhook signatures, even in development. See webhooks explained.
  • A stable URL (named tunnel, frp or SSH plus your domain) saves you from re-registering webhook endpoints every time.

Security notes

Anything you expose is reachable by the whole internet, including bots that scan new hostnames within minutes:

  • Don’t expose admin panels, databases or debug endpoints. Development servers often have debug modes that leak secrets.
  • Add authentication: basic auth in Nginx, Cloudflare Access, or the tunnel’s built-in auth.
  • Stop the tunnel when you’re done.
  • Watch out for company policy. Tunnelling out of a corporate network may violate it.

Which should you pick?

Situation Choice
Quick demo, nothing installed Cloudflare quick tunnel, or ngrok’s free tier
Stable URL on your own domain, no VPS Cloudflare Tunnel
Team already on Tailscale Tailscale Funnel / Serve
You have a VPS and want full control SSH reverse tunnel (simple) or frp (feature-rich)
Receiving webhooks in development The provider’s CLI forwarding

Related: port forwarding explained and NAT explained.

  • Networking
  • Web Development
  • Tunnels