tailscale-proxy
Share all your local dev servers through one stable Tailscale *.ts.net URL — a
self-hosted ngrok alternative. Grab the app, or run one command.
⬇️ Download the desktop app
A native menu-bar app — no terminal needed. Screenshots, install steps & all releases →
⚡ Or one command in the terminal
npx tailscale-proxy # discovers your dev servers + shares them via Tailscale
brew install meabed/tap/tsp && tsp # or install the binaryFirst time? npx tailscale-proxy doctor checks your setup, or follow the 4-step
Installation guide.
An open-source, self-hosted ngrok alternative built on Tailscale : discover your local dev servers by port and expose them through a single Tailscale entry — privately (Serve , tailnet-only) or publicly (Funnel ) — routed by project name.
Why not ngrok? Your traffic runs over your own Tailscale tunnel on a stable
*.ts.net URL — no third-party tunnel, no per-session random URLs, no request
rate limits or paywalls. Share many dev servers through one hostname,
and discovery is automatic — no ngrok http 3000 per port.
No per-app wiring: just run your servers (node, bun, deno, python, php,
ruby, go, java, …) and tsp finds the ones listening in a port range,
derives a path slug from each project’s folder, and routes to them under one
hostname:
tsp strips the first path segment (the project name) and forwards the rest to
that project’s local port — so …/web/foo → 127.0.0.1:4983/foo.
It re-scans every few seconds (so servers that come and go are picked up), keeps a service for a few scans before de-registering (no flapping on restarts), streams SSE, and proxies WebSocket upgrades. Zero runtime dependencies — one small Go binary.
Try it in 30 seconds
# Start a couple of dev servers (each in its own project folder)
cd ~/sites/portfolio && npx serve -l 3000
cd ~/apps/web && npx next dev -p 4000
# Share them through one Tailscale URL
npx tailscale-proxy doctor
npx tailscale-proxyServices:
https://bigfoot.tail-scale.ts.net/portfolio/ → 127.0.0.1:3000
https://bigfoot.tail-scale.ts.net/web/ → 127.0.0.1:4000Why
- One hostname, many apps. Funnel only exposes a single hostname;
tspputs a path-routing proxy behind it so every dev server is reachable. - Zero config per app. Run your server normally;
tspdiscovers it by port. - Looks like localhost. The app receives
Host: localhost:<port>(so CORS, cookies, and host-allowlists match) — with--forward-hostwhen you need the public URL. - Private or public.
--privatefor tailnet-only Serve; Funnel by default.
Head to Installation or Getting started.