FeaturesGuidesBlogDocumentationFreeGet Started

How to Expose Localhost to the Internet (Step-by-Step)

How to expose localhost to the internet: HTTPS public URL with npx localtolink — webhooks, OAuth callbacks, and phone testing in one walkthrough.

Why expose localhost?

Your laptop runs a dev server on localhost, which only your machine can reach. Webhook providers, OAuth services, mobile devices, and remote colleagues need a public HTTPS URL that forwards traffic to your local app. A development tunnel creates that bridge without deploying to staging.

Common reasons developers expose localhost:

LocalToLink gives you a random HTTPS subdomain in one command. No account signup, no config file.

For a faster hook before this walkthrough, see Expose Localhost in One Command.

Expose localhost vs alternatives

You can reach localhost from the internet in several ways. Pick the lightest option that matches your task.

ApproachBest forTrade-off
Router port forwardingHomelab or always-on serverOpens your network; static IP or DDNS; usually HTTP unless you manage TLS
Account-based tunnel (e.g. ngrok-style)Teams that want dashboards and request inspectionSignup, config, and plan limits before the first URL
Dev tunnel (npx localtolink)Webhooks, OAuth, and short client previewsRandom subdomain; session limits; not production ingress

This guide focuses on the dev tunnel path because it is the fastest way to get HTTPS on localhost for a focused test. For a deeper ngrok-style comparison without a feature matrix, see LocalTunnel not working?.

Prerequisites

Before starting, confirm:

RequirementDetails
Node.jsVersion 22.14 or later (node --version)
Local appDev server running on a common port (3000, 5173, etc.)
NetworkOutbound HTTPS allowed (corporate firewalls sometimes block this)

LocalToLink auto-detects ports: 3000, 3001, 4000, 4200, 5000, 5173, 5174, 8000, 8080, 8888, 9000. If your app uses a different port, pass --port explicitly.

Windows, macOS, and Linux

The workflow is the same on every desktop OS: install Node 22.14+, start your app, then run the CLI.

npx localtolink

On Windows, use PowerShell or Windows Terminal. On macOS and Linux, use your usual shell. If you cannot install a global binary, see Expose Localhost Without Installing Software — npx still needs Node, but nothing permanent is added to your PATH.

Step-by-step: start a tunnel

1. Start your local dev server in one terminal:

npm run dev

2. Start LocalToLink in a second terminal:

npx localtolink

3. Copy the public URL from the output:

LocalToLink v1.0.1

Detected local app:
  http://localhost:5173

Connecting…

Public URL:
  https://k7m2x9p4q1.localtolink.com

Expires:
  2026-09-05 20:00 UTC (2 hours)

Tunnel active — press Ctrl+C to stop

4. Share or register the public URL wherever you need external access — webhook dashboards, OAuth redirect settings, or a message to a colleague.

Traffic arrives over HTTPS at LocalToLink's edge and is forwarded to your localhost port automatically.

Use your public URL

Once you have https://k7m2x9p4q1.localtolink.com, three common next steps:

  1. Webhooks — register https://k7m2x9p4q1.localtolink.com/your/webhook/path and verify signatures. Start with Test Webhooks Locally, then provider guides such as Stripe or GitHub.
  2. OAuth callbacks — add the exact redirect URI (scheme, host, path, trailing slash) in your provider console. Follow OAuth Callback on Localhost.
  3. Phone or client preview — scan the terminal QR code or send the HTTPS link. See Test Localhost on Your Phone and Share Localhost with a Client.

Framework-specific tunnel settings: Vite HMR and Next.js allowedDevOrigins.

Specify a port manually

When multiple apps run locally, auto-detection may pick the wrong one:

npx localtolink --port 3000

Use this for Next.js on 3000, Vite on 5173, Django on 8000, or any port your framework uses.

JSON output for scripts and CI

For automation, capture the URL programmatically:

npx localtolink --json --port 3000

Returns a single JSON object on stdout:

{
  "url": "https://k7m2x9p4q1.localtolink.com",
  "localPort": 3000,
  "expiresAt": "2026-09-05T20:00:00.000Z",
  "websocketUrl": "wss://k7m2x9p4q1.localtolink.com"
}

Pipe through jq in shell scripts:

URL=$(npx localtolink --json --port 3000 | jq -r .url)
echo "Webhook endpoint: $URL/api/webhooks"

Free tier limits

Session duration and bandwidth caps apply to anonymous tunnels on the free tier. Each session gets a random subdomain. Custom subdomains and user accounts are not available on the free tier yet. See Documentation for current limits.

Reconnection and URL stability

If your network drops briefly, LocalToLink reconnects automatically and keeps the same URL for up to 10 minutes after disconnect. This grace window helps you survive Wi-Fi hiccups without re-registering webhook URLs.

After the grace window expires, the next session gets a new random subdomain. Update any external configuration (Stripe Dashboard, OAuth redirect URIs) when the subdomain changes.

Security and trust

Visitor interstitial

When the visitor interstitial policy is enabled, people opening your link in a browser may see a one-time Opening a shared link page before your app loads. Tap Continue once per tunnel subdomain (a cookie remembers for 24 hours).

Webhook and API traffic often skips the page: non-browser user agents (for example curl or provider bots), Accept: application/json, and paths under /api/ pass through without the prompt. For automated browser tests, send the header localtolink-skip-browser-warning or complete the continue flow once.

Warn clients and teammates before a demo so the safety page is expected — see Share Localhost with a Client.

Troubleshooting

ProblemLikely causeFix
No local app detectedDev server not runningStart npm run dev first, then retry
Wrong app loadsMultiple ports in useUse --port to target the correct server
Tunnel refused or limit messageAnother tunnel active or session cap reachedStop other tunnels; restart npx localtolink and update external URLs
Session ended unexpectedlySession time or bandwidth limit reachedRestart npx localtolink and update external URLs
Browser shows warning pageVisitor interstitial (when enabled)Continue through once; use bypass header in tests if needed
Connection refused externallyFirewall blocks outbound WSSCheck corporate VPN/firewall settings

What LocalToLink does not include

We state these explicitly so you choose the right tool:

For webhook testing, see Test Webhooks Locally. For mobile testing with QR codes, see Test Localhost on Your Phone. For delivery failures, see Why Webhooks Fail on Localhost.

FAQ

Is it free?
Yes for anonymous dev tunnels on the free tier — no signup required. Session time, bandwidth, and rate limits apply; see Documentation.

Do I need to open ports on my router?
No. The CLI connects outbound to LocalToLink. You do not configure port forwarding or change firewall inbound rules.

Does it work behind VPN or corporate firewall?
Usually yes if outbound HTTPS and WebSocket traffic to the tunnel service is allowed. Some corporate proxies block npm or WSS — try --port explicitly and check with your network team.

Can I expose localhost without deploying?
Yes. That is the point of a dev tunnel: your code stays on your machine while external services call a public HTTPS URL.

How is this different from ngrok?
LocalToLink optimizes for anonymous, one-command HTTPS URLs without a request inspector. ngrok adds dashboards and replay at the cost of signup and configuration. Choose based on whether you need inspection or the fastest path to a URL.

Do I need an account?
No. Anonymous tunnels require no signup.

Does it work with WebSockets?
Yes. WebSocket upgrades pass through the tunnel — useful for Vite HMR and real-time apps. See WebSocket Through a Tunnel.

Can I use this in CI?
Yes. Use --json to capture the URL in GitHub Actions or similar pipelines. Remember the 2-hour session limit.

Is my traffic encrypted?
Visitors connect via HTTPS. Traffic between LocalToLink's edge and your CLI is encrypted over WebSocket.

Try it now

Start a tunnel from your project directory — no account required.

$ npx --yes localtolink@latest

See the full CLI reference for flags and exit codes.

LocalToLink CLI 1.0.1 — verified 2026-09-20