Your own tunnel. Your own domain.

A self-hosted ngrok replacement. Run the edge on your own VPS, point your own domain at it, and keep every request off someone else’s servers.

$ngstone port 3000
https://amber-fox-42.yourdomain.com
Self-hosted, on your own VPS
Your domain, not a shared one
No request caps, no seat pricing
No third party sees your traffic

Everything ngrok does. None of the strings attached.

Built for developers who’d rather own the whole path from browser to laptop than rent a slice of someone else’s.

Your domain, your rules

No third party sees your traffic, no monthly seat pricing, no forced login walls. One wildcard domain gives you infinite custom subdomains.

NAT-friendly by design

The agent dials out to your VPS — it never connects into your laptop. No inbound firewall holes at home, and it works behind any NAT.

Multiplexed over one connection

A single TLS 1.3 connection carries a yamux session; every request gets its own flow-controlled stream. No per-request handshakes anywhere.

Automatic wildcard TLS

Let's Encrypt wildcard certs via DNS-01. https://anything.yourdomain.com just works, with a valid padlock, auto-renewed.

Request inspector (planned)

A local web UI at localhost:4040 is on the roadmap — every request and response live, headers, bodies, timing, replay and edit-and-replay. Not built yet.

Constant-memory streaming

Bodies are never buffered — a 1 GiB download or 100 MB upload passes through at constant memory. WebSockets and SSE ride the same tunnel, though hardening for them is still in progress.

Instant reconnect

Laptop sleeps or wifi blips? The agent reconnects with the same identity and reclaims its subdomain immediately. Same URL after recovery.

Hardened edge

Per-IP rate limiting, in-flight caps, slowloris protection, and constant-time token auth. Unknown hosts get a cheap uniform 404.

One connection, dialed from your side

The agent on your laptop reaches out to your VPS — never the other way around. That single connection carries every request.

Browser

https://api.yourdomain.com

HTTPS request

Your VPS edge

:443 · wildcard TLS · ngstoned

dialed outbound from the agent

one TLS 1.3 / yamux connection — traffic flows both ways once established

Your laptop

ngstone agent → localhost:3000

01

A browser asks for your subdomain

A request for https://api.yourdomain.com hits your VPS on port 443, terminated with a wildcard TLS certificate that ngstoned already holds.

02

The edge routes it down the tunnel

ngstoned looks up the subdomain, finds the matching agent session, and forwards the request as a new stream on that session.

03

Your local app answers, unaware

The agent receives the stream and proxies it to localhost:3000. The response streams back the same way it came — no buffering, no polling.

Planned — not yet shipped

Watch every request land, live

The design: a local web UI at localhost:4040 showing every request and response as it happens, with headers, bodies, and timing — and letting you replay any of them straight to your app. This is on the roadmap, not in your hands today.

GET/api/health2003ms
POST/api/orders20145ms
GET/api/users/48220012ms
GET/static/app.js3048ms
WS/socket101
GET/api/users?page=220019ms
POST/api/orders201

Headers

content-type: application/json
user-agent: curl/8.6.0
x-forwarded-for: 203.0.113.42
authorization: Bearer •••••••••••

Body

{
  "id": "ord_7f3a9c",
  "status": "created",
  "total": 42.5
}

From clone to public URL in three commands

No dashboard, no account creation. Just a binary on your server and a binary on your laptop.

  1. 1

    Point DNS at your VPS, and start the edge

    Add a wildcard A record for *.yourdomain.com pointing at your server, generate a token, then run the edge binary there.

    $ TOKEN=$(openssl rand -base64 32 | tr '+/' '-_' | tr -d '=')
    $ HASH=$(printf '%s' "$TOKEN" | shasum -a 256 | cut -d' ' -f1)
    $ ngstoned --domain yourdomain.com --cert-email you@yourdomain.com \
        --cf-api-token "$CF_API_TOKEN" --token-sha256 "$HASH"
  2. 2

    Install the agent, and authenticate

    Install the agent on your dev machine, then verify the plaintext token from step one against your edge.

    $ brew install emilio-kariuki/tap/ngstone
    $ ngstone auth "$TOKEN"
  3. 3

    Start tunneling

    Point the agent at any local port. Add --subdomain to pick your own name instead of a random one.

    $ ngstone port 3000
    → https://amber-fox-42.yourdomain.com
    
    $ ngstone port 3000 --subdomain api
    → https://api.yourdomain.com

Stop renting your own tunnel.

Two binaries, one domain you already own. Point ngstoned at your VPS, point ngstone at your laptop, and you’re done.