More apps from usSnipora

Guide

Share localhost from Mac: ngrok and alternatives

Someone needs to see what’s running on your localhost, or a service needs to call it. A tunnel gives your dev server a public HTTPS address in one command. Here’s which one to use, and how to get past the “host not allowed” error that usually follows.

By Anmol Sethi · Updated

In short

The quickest free option is a Cloudflare quick tunnel: brew install cloudflared, then cloudflared tunnel --url http://localhost:3000 prints a public trycloudflare.com link, with no account. ngrok (ngrok http 3000) needs a free account but can keep the same address. Either way, allow the tunnel’s host in your dev server, or it answers with a “host not allowed” error.

1. Quickest: a Cloudflare quick tunnel

brew install cloudflared
cloudflared tunnel --url http://localhost:3000
Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):
https://quiet-river-example.trycloudflare.com

Send that link to anyone. It works until you press Ctrl-C, and you get a new random address each time. No account, no sign-up. Cloudflare means quick tunnels for testing, not for running a site; for a fixed address, set up a named tunnel with a Cloudflare account and your own domain.

Rather click than type? Portlivo shows every port with its project and frees it in one click. Try it free for 7 days →

2. ngrok

brew install ngrok
ngrok config add-authtoken <token>   # once, from your ngrok dashboard
ngrok http 3000

ngrok needs a free account. In return you get a web inspector at http://localhost:4040 that shows every request and can replay it, which is handy for webhooks, and the free plan includes a fixed domain, so a callback URL you register once keeps working.

On the free plan, people opening the link in a browser first see an ngrok warning page they have to click through. API calls with an ngrok-skip-browser-warning header skip it.

Every option at a glance

ToolAccountAddressStart it
Cloudflare quick tunnelNoneRandom, new each runcloudflared tunnel --url http://localhost:3000
ngrokFree accountCan stay the samengrok http 3000
Tailscale FunnelTailscale accountYour Mac’s ts.net nametailscale funnel 3000
VS Code port forwardingGitHub or MicrosoftPrivate unless you make it publicPorts panel → Forward a Port
localtunnelNoneRandomnpx localtunnel --port 3000
localhost.runNoneRandomssh -R 80:localhost:3000 nokey@localhost.run
  • Tailscale Funnel suits you if Tailscale is already on your Mac: the address stays the same. Without Funnel, tailscale serve shares only with devices on your own tailnet.
  • VS Code forwards ports from the Ports panel. Links need a sign-in until you set the port’s visibility to Public, which is safer for showing work to a teammate.
  • localtunnel shows visitors a password page first; the password is your public IP, which curl ifconfig.me prints.

Testing Stripe webhooks? stripe listen --forward-to localhost:3000/api/webhooks forwards events to your Mac with no tunnel at all. Other providers with a CLI often have the same.

3. Fix “host not allowed” errors

Dev servers reject requests for host names they don’t recognise, to block DNS rebinding attacks. Through a tunnel, the host is the tunnel’s, so the page fails even though the tunnel works. Allow the tunnel’s domain:

ErrorFix
Vite: Blocked request. This host ("….trycloudflare.com") is not allowed.server: { allowedHosts: [".trycloudflare.com"] } in vite.config.js
webpack dev server: Invalid Host headerdevServer: { allowedHosts: "all" }
Rails: Blocked hosts: ….ngrok-free.appconfig.hosts << ".ngrok-free.app" in config/environments/development.rb
Django: DisallowedHost at /Add ".trycloudflare.com" to ALLOWED_HOSTS
Next.js: a warning about cross-origin requests to /_nextallowedDevOrigins: ["*.trycloudflare.com"] in next.config.js

A leading dot (or *.) allows every subdomain, so a new random quick-tunnel address keeps working. Use the domain of the tunnel you actually use: .ngrok-free.app, .ts.net and so on.

Other things that break

  • Absolute localhost URLs. The page loads but API calls, images or redirects point at http://localhost:…, which on the visitor’s machine is their own computer. Use relative paths, or proxy the API through your dev server as in the phone guide.
  • OAuth sign-in. Google, GitHub and others only redirect to callback URLs you registered, so a random tunnel address fails. Use a fixed address (ngrok’s free domain, Tailscale, a named Cloudflare tunnel) and register it once.
  • Cookies. A cookie set for localhost isn’t sent to the tunnel’s domain, so you’re signed out there. Sign in again through the tunnel.

Anyone with the link reaches your dev server, debug pages and error traces included. Stop the tunnel when you’re done, and don’t share a server with DEBUG or a debugger console turned on.

The one-click way: Portlivo

Portlivo shares any dev server from its menu: Share via cloudflared starts a quick tunnel (or ngrok, if that’s what you have), copies the public link and marks the server with a globe. Stop Sharing ends it, and quitting Portlivo ends them all, so no tunnel stays open by accident. See Share and QR.

Questions people ask

What’s the best free alternative to ngrok?
A Cloudflare quick tunnel: cloudflared tunnel --url http://localhost:3000 gives a public HTTPS link with no account. It changes every run, so use ngrok’s free domain or Tailscale Funnel when you need the same address.
Why does Vite say “This host is not allowed”?
Vite blocks unknown host names. Add the tunnel’s domain to server.allowedHosts, for example [".trycloudflare.com"].
Is sharing localhost safe?
Anyone with the link can reach that one server while the tunnel runs. Share it only as long as needed, and not with debug consoles enabled.
Do I need a tunnel to test webhooks locally?
Not always. Stripe’s CLI forwards events to localhost with stripe listen --forward-to. Otherwise a tunnel with a fixed address saves re-registering the URL.

Try Portlivo free for 7 days. Every feature, no account.

Download for Mac

Still have a question?

Write to us — a real developer reads every email and replies personally.

support@portlivo.com