ngrok alternatives for sharing localhost
Thirteen tools that replace ngrok for sharing a local app, what each is best for, and what you give up.
For a public URL with no account, use a Cloudflare quick tunnel. To show one person or a coding agent your app without a public URL or an account, use qURL™: each link works once and expires within 24 hours. Inside a tailnet, use Tailscale Serve. Keep ngrok for webhooks and request replay.
Facts checked October 1, 2026, each value linked to its source. Full dataset.
Why people look for ngrok alternatives
- An account and authtoken before the first URL. ngrok’s quickstart starts with signing up, and the agent will not start an endpoint without the token.
- A warning page for your visitors. On the free plan, browser traffic sees ngrok’s ERR_NGROK_6024 page before it reaches your app.
- Free-plan limits: 3 endpoints, 1 GB a month out, and 20,000 HTTP requests a month, on one assigned dev domain.
- A public URL. Anyone who has the address can request your app unless you add a Traffic Policy, and the URL has no built-in expiry.
The alternatives at a glance
| Tool | Best for | Account needed before the first URL | Who can reach it | Link expiry |
|---|---|---|---|---|
| qURL CLI | Showing your app to a person or a coding agent with no account and no public URL | No. The first publish creates the device identity our test | No one until a link is opened; then the opener’s public IP for that session, including other devices behind that IP layerv.ai | Yes. qurl share returned a 24-hour link in our no-account test; no-account links are capped at 24 hours our test |
| Cloudflare Quick Tunnel (trycloudflare.com) | A throwaway public URL with no account | No developers.cloudflare.com | Public, unless --allowed-mail is set developers.cloudflare.com | No; the URL works until cloudflared stops developers.cloudflare.com |
| Microsoft dev tunnels | VS Code users who want a tunnel that is private by default | Yes: GitHub, Microsoft, or Entra ID learn.microsoft.com | Private by default; anonymous access is opt-in learn.microsoft.com | Temporary tunnels end when the host disconnects; persistent tunnels are deleted after 30 days idle; anonymous access can be time-limited learn.microsoft.com |
| Tailscale Serve | Sharing with people whose devices are already on your tailnet | Yes: a tailnet with HTTPS certificates enabled tailscale.com | Authorized Tailscale users, including accepted machine-share recipients tailscale.com | No; a foreground session runs until stopped, and --bg keeps it running across reboots tailscale.com |
| Tailscale Funnel | A stable public HTTPS address for a machine already on a tailnet | Yes: a tailnet with MagicDNS, HTTPS certificates, and the funnel node attribute tailscale.com | Public: anyone on the internet tailscale.com | No; runs until you turn it off tailscale.com |
| zrok (free) | Private shares to other zrok accounts, including raw TCP and UDP | Yes: a free account, no card zrok.io | Your choice per share: public shares are open to anyone with the URL; private shares only to zrok accounts you grant netfoundry.io | Ephemeral shares end with the process netfoundry.io |
| Pinggy (free) | Nothing to install beyond SSH, with basic auth or an IP allowlist | No, to start pinggy.io | Public: anyone with the URL pinggy.io | Free tunnels time out after 60 minutes pinggy.io |
| localtunnel | A one-line npx command in a Node.js project | No github.com | Public: anyone with the URL github.com | Active while the lt client stays connected; no expiry setting github.com |
| Cloudflare Tunnel (named) | A stable hostname on your own domain with Cloudflare Access in front | Yes: account plus a domain on Cloudflare developers.cloudflare.com | Public unless you add a Cloudflare Access application developers.cloudflare.com | No per-link expiry; Access session settings apply developers.cloudflare.com |
| localhost.run (free) | An SSH one-liner with no account | No account for free domains (SSH key or the nokey user) localhost.run | Public: anyone with the URL localhost.run | No expiry setting; the free domain rotates localhost.run |
| Serveo (free) | An SSH one-liner with a custom subdomain | No serveo.net | Public: anyone with the URL serveo.net | None documented for HTTP; anonymous public TCP ports last 10 minutes (30 with a registered key) serveo.net |
| bore (bore.pub) | Forwarding a raw TCP port | No, for the public bore.pub server github.com | Public: anyone who connects to the port github.com | bore.pub connections time out after 24 hours, per the maintainer github.com, unofficial |
| Expose (free) | PHP developers who already use Composer | Yes: a free account for the auth token expose.dev | Public: anyone with the URL expose.dev | Free connections are time-limited (length not documented) expose.dev |
Each alternative
qURL CLIMade by LayerV
Best for: Showing your app to a person or a coding agent with no account and no public URL.
Trade-off vs ngrok: Not for webhooks or public APIs; no raw TCP.
Command to the first shareable URLqurl publish http://127.0.0.1:3000 qurl share <CRID>Cloudflare Quick Tunnel (trycloudflare.com)
Best for: A throwaway public URL with no account.
Trade-off vs ngrok: Public unless you set --allowed-mail; the hostname changes each run; no Server-Sent Events.
Command to the first shareable URLcloudflared tunnel --url http://localhost:8080Microsoft dev tunnels
Best for: VS Code users who want a tunnel that is private by default.
Trade-off vs ngrok: Needs a GitHub or Microsoft sign-in; visitors see an anti-phishing page first.
Command to the first shareable URLdevtunnel user login devtunnel host -p 8080 --allow-anonymousTailscale Serve
Best for: Sharing with people whose devices are already on your tailnet.
Trade-off vs ngrok: Viewers need a Tailscale account and client.
Command to the first shareable URLtailscale serve 3000Tailscale Funnel
Best for: A stable public HTTPS address for a machine already on a tailnet.
Trade-off vs ngrok: Needs a tailnet; ports 443, 8443, and 10000 only; machine names appear in Certificate Transparency logs.
Command to the first shareable URLtailscale funnel 3000zrok (free)
Best for: Private shares to other zrok accounts, including raw TCP and UDP.
Trade-off vs ngrok: Needs an account; public shares from unverified free accounts show a warning page.
Command to the first shareable URLzrok2 enable <TOKEN> zrok2 share public 8080Pinggy (free)
Best for: Nothing to install beyond SSH, with basic auth or an IP allowlist.
Trade-off vs ngrok: Free tunnels time out after 60 minutes and show a screening page.
Command to the first shareable URLssh -p 443 -R0:localhost:8000 qr@free.pinggy.iolocaltunnel
Best for: A one-line npx command in a Node.js project.
Trade-off vs ngrok: Public; visitors are asked for a tunnel password, per the maintainer.
Command to the first shareable URLnpx localtunnel --port 8000Cloudflare Tunnel (named)
Best for: A stable hostname on your own domain with Cloudflare Access in front.
Trade-off vs ngrok: Needs a Cloudflare account and a domain on Cloudflare.
Command to the first shareable URLCreate the tunnel in the dashboard, run the cloudflared install command it shows, then add a published application routelocalhost.run (free)
Best for: An SSH one-liner with no account.
Trade-off vs ngrok: Public; the free domain changes after a few hours.
Command to the first shareable URLssh -R 80:localhost:8080 localhost.runServeo (free)
Best for: An SSH one-liner with a custom subdomain.
Trade-off vs ngrok: Public; a warning page on the free tier.
Command to the first shareable URLssh -R 80:localhost:3000 serveo.netbore (bore.pub)
Best for: Forwarding a raw TCP port.
Trade-off vs ngrok: TCP only, with no TLS; anyone who connects to the port reaches it.
Command to the first shareable URLbore local 8000 --to bore.pubExpose (free)
Best for: PHP developers who already use Composer.
Trade-off vs ngrok: Needs an account; free connections are time-limited.
Command to the first shareable URLexpose token <TOKEN> expose share http://localhost:3000
When to keep ngrok
Keep ngrok when something other than a person must reach your app: a webhook from Stripe or GitHub, a public API, or raw TCP. Its web inspection interface on localhost:4040 shows every request and response and replays a request with one click, which none of the tools above match for webhook debugging.
Frequently Asked Questions
What is the best free ngrok alternative?
It depends on who must reach the app. For a public URL with no account, a Cloudflare quick tunnel. For one person or agent, with no account and no public URL, qURL. For people on your tailnet, Tailscale Serve. For webhooks, any tool that gives a public URL; qURL is not built for them.
Which ngrok alternatives work without an account?
Cloudflare quick tunnels, localtunnel, Pinggy, Serveo, localhost.run, and bore.pub start without one, and so does the qURL CLI. Of these, qURL is the only one that does not give the app a public URL.
Is there an ngrok alternative without a warning page?
A one-time qURL link opens the app without a tunnel warning page. bore has none because it forwards raw TCP. Microsoft dev tunnels, zrok public shares from unverified free accounts, Pinggy and Serveo free tunnels, and localtunnel all show one.
Can my coding agent share my app instead of me running ngrok?
Yes. Point Claude Code, Cursor, or Windsurf at the qURL skill (https://layerv.ai/skills/qurl/SKILL.md) and ask it to share the app. It installs the CLI, publishes the app privately, and gives you an address to send. The agent applies the private access rules you choose. For named recipients, give it their email addresses so it can send invitations. Recipients verify their email in the browser and save a passkey; they never send you their email verification code. The agent checks policy support before sharing and keeps the app private if the deployment cannot support it. For one person right away, ask it for a one-time link instead. Codex starts with network access off, so save the skill file for it first.
Which ngrok alternative is private by default?
Microsoft dev tunnels are private until you allow anonymous access, but need a GitHub or Microsoft sign-in. Tailscale Serve is private to your tailnet. qURL gives the app no public URL and needs no account; without one you can keep up to 3 active resources, with links that last up to 24 hours.
Built it with an agent? Let it share it.
One prompt points Claude Code, Cursor, or Windsurf at the qURL skill. Or install the CLI and publish the app yourself. No account either way.
New to qURL? Start at qurl.link