qurl. link
ngrok alternative

Is there an ngrok alternative that doesn’t give my app a public URL?

Yes. qURL shares the app running on your computer without giving it a public URL. The CLI needs no account. You publish the app privately, then invite people by email or let them ask for access. The app gets no public address and no open port.

Your options

Who can reach your app.

qurl.link

qURL CLI

Sign-up
None for the CLI.
What visitors get
An email invitation, or an address they can ask to open.
Who can reach it
People you invite or approve. Then the network it was opened from, for that visit.

ngrok

ngrok agent

Sign-up
An account and an authtoken.
What visitors get
A public URL on ngrok’s dev domain. Free-plan visitors see a warning page first.
Who can reach it
Anyone with the URL, unless you add sign-in rules.

Cloudflare quick tunnel

cloudflared

Sign-up
None.
What visitors get
A trycloudflare.com address that changes each run.
Who can reach it
Anyone with the URL, unless you set --allowed-mail.

Tailscale Serve

Tailscale client

Sign-up
A tailnet.
What visitors get
A ts.net address for authorized users with Tailscale installed.
Who can reach it
Authorized Tailscale users.

This is each tool’s quick way to share. Most of them have more settings you can turn on. Every tool side by side, with sources: every way to share localhost.

With qURL

From localhost to one private link.

Share it with qURL

  1. Install the qurl CLI.

    On a Mac, use Homebrew. On Linux and Windows, download the .deb, .rpm or archive from the CLI releases and put qurl on your PATH. No account to make first.

    Install (macOS)
    $ brew install layervai/tap/qurl
  2. Publish the app that’s running.

    Use your app’s port and choose the access policy: review lets people ask and you approve each one; invite_only admits only the people you invite. The app stays on your computer. Nothing is uploaded or deployed, and the first publish creates a free identity for this computer.

    Publish
    $ qurl publish http://127.0.0.1:3000 --access review
  3. Send the address, then approve who asks.

    Send the address that qurl publish returned. Each person who opens it asks for access, and nobody gets in before you approve them: list the requests, then approve the one you chose by its decision ID. Rather invite people by email? Publish with --access invite_only instead and let your AI send the invitations.

    Approve a request
    $ qurl access list_grants <id> -o json
    $ qurl access approve <id> <decision-id> --version <current-version> -o json

Done sharing? qurl stop <id> takes the app offline, and qurl delete <id> --yes retires it: its links stop working and open visits end.

When ngrok fits better

When to use something else.

  • Stripe, GitHub or another service has to call your webhook?Use a public tunnel
  • You’re serving a public API?Use a public tunnel
  • You need raw TCP, like SSH or a database?Use a TCP tunnel
  • Everyone who needs it is on your tailnet?Use Tailscale Serve
  • It has to stay up when your laptop is closed?Deploy it

qURL is not for webhooks, public APIs or raw TCP. Use a public tunnel for those.

Made a thing?

Start with qurl.link.
Show someone today.

Free to try. No account needed. Current limits