CLI tool
akazwz/hostc avatar
akazwz/hostc

hostc turns a localhost port into a public HTTPS URL

Localhost, anywhere. One command gives your dev server a public HTTPS URL, with WebSockets and hot reload. Free, no account, runs on Cloudflare Workers.

606 stars65 forksTypeScriptApache-2.0

At a glance

What is it?
hostc is a TypeScript CLI that puts a Cloudflare Worker and a Durable Object between your dev server and the open internet, so a local port gets a public HTTPS address, WebSockets keep working, and hot reload still fires on a phone. It costs one command and no account, at the price of a public URL that anyone holding can reach.
Who is it for?
hostc fits front end work that needs to be seen from another device or another network: sharing a build with a client, triggering Stripe, GitHub or Slack webhooks against local code, or letting a coding agent read a live URL. It is the wrong tool for anything that must stay private, because the generated address has no access control and no credential in front of it.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The tunnel problem reduced to one argument and one port

The usual way to expose a dev server to someone outside your machine involves an account, an auth token, a binary to install, and a domain to configure. hostc removes the first three. The project describes itself as "Localhost, anywhere", and the mechanism is that one command gives a running dev server a public HTTPS URL with WebSockets and hot reload included, free and without an account. The command takes the port as its argument, so the only thing you have to know is which port your app already listens on.

That makes hostc a good fit for a specific set of jobs rather than a general purpose tunnel. The project lists sharing something built with an AI coding tool before deploying it, showing work in progress to a teammate or a client, testing webhooks from Stripe, GitHub or Slack against code on your own machine, trying a site on a real phone with hot reload, and letting a coding agent inspect what it built. In each of those cases the requirement is a link that works from a phone or a different network, not a permanent hosting arrangement.

One outgoing WebSocket carries every request

The architecture in the README is drawn as a single line, and the shape of it matters more than the individual boxes:

code
browser ──▶ Worker ──▶ Durable Object (one per tunnel) ◀── WebSocket ── hostc ──▶ localhost

The client opens a single outgoing WebSocket, so nothing on your machine has to be reachable from the internet, which avoids opening a hole in a local firewall. Each public request or WebSocket becomes a stream on that one connection, with flow control for bodies. The Worker sits in front, and a Durable Object is created per tunnel, which gives each tunnel its own state rather than sharing one global connection. Idle tunnels sleep on the server side, and that behaviour is what keeps the service free.

The wire format lives in docs/protocol.md, and the repository splits the pieces into packages/protocol for the frame format and shared messages, packages/client for the Node.js connection, streams and reconnect logic, apps/server for the Worker and Durable Object, apps/cli for the hostc command, and apps/web for the hostc.dev site and its llms.txt file.

Pointing hostc at a running dev server

Start your app first, then run the CLI with the port. There is nothing to install permanently and no token to paste:

sh
npx hostc@latest 3000

The terminal prints the public address and the local origin it maps to:

text
  https://k7m2xq9pa4dn.hostc.app  → http://localhost:3000

  Anyone with this URL can reach your local server. Press Ctrl+C to stop.

Open that address on any device and every request shows up in your terminal as it arrives, which is the fastest way to confirm the tunnel is live. The target argument accepts a port, a host and port pair, or an https origin:

text
hostc <target> [options]

  3000                     http://localhost:3000
  127.0.0.1:8080           http://127.0.0.1:8080
  https://localhost:5173   any http(s) origin

  --server <url>   tunnel server (env HOSTC_SERVER)
  --qr             print a QR code of the public URL
  -h, --help       show this help
  -v, --version    show the version

The --qr flag prints a QR code of the public URL, which saves typing on a phone. Press Ctrl+C to stop, and the URL is released right away.

Why the docs insist on npx hostc@latest

hostc makes a deliberate choice that will annoy anyone who prefers a global install: the documentation tells you not to install it globally and not to add it to a project. The stated reason is version skew. Because the service is free and changes quickly, a server update can be incompatible with older CLIs, and an installed copy stays pinned on its version and stops working when the server moves on. The project says an outdated CLI stops at startup and tells you to upgrade.

That constraint also shapes the workflow for coding agents. The project tells you to point an agent at hostc.dev/llms.txt, where it learns how to run hostc and how to read the generated URL, so the agent can start a tunnel and then look at what it just built.

There is also a claim worth reading carefully. The documentation says the link survives, because network drops and server restarts do not change the URL and hostc reconnects on its own. The same page also states that restarting hostc gives a new URL. So link stability is per running client process, not per project.

The public URL is the whole security model

There is no access control here, and the project says so plainly: the URL is public, anyone who has it reaches your server, and you should only expose what you mean to share. The project also says visitors see your app directly, with no warning page to click through. Both facts matter for adoption.

The positive side is that local development servers do not have to be taught to trust an external hostname. The documentation explains that requests arrive addressed to localhost and redirects point back to the public URL, so there is no allowed-hosts setting to change for frameworks that check one. Hot reload also keeps working because WebSockets pass straight through, and Server-Sent Events stream as they are produced, so a Vite or Next.js save reaches every open device.

The negative side is that anything bound to that port is exposed for as long as the tunnel runs. A dev server with a debug endpoint, a local database admin interface, or an environment file in the served directory is all reachable by anyone who obtains the link, which is why the choice of what to point hostc at matters more than the command itself.

Running the tunnel server on your own Cloudflare domains

The server side is a Cloudflare Worker, and the documentation covers self-hosting it. You add two domains, one for the API and one for tunnels, and the guide suggests keeping them separate so tunnel cookies and abuse reports stay away from your main site. On the tunnel domain you add a proxied wildcard DNS record pointing `*` at `192.0.2.1`, with Universal SSL covering the wildcard. Then you set a token secret of at least 32 random bytes by running the wrangler secret put command for the hostc-tunnel secret, using a value such as one produced by `openssl rand -base64 48`. Deployment is the deploy script with the two domains supplied as environment variables, in the form `API_DOMAIN=example.com TUNNEL_DOMAIN=example.app pnpm deploy:server`.

Clients then target your server with the --server option, in the form `npx hostc@latest 3000 --server https://example.com`, or you bake the default into a build with `HOSTC_DEFAULT_SERVER=https://example.com pnpm build`.

The repository is licensed Apache-2.0, and the workspace package.json sets the package manager to pnpm 12.6.0 with Node.js 22.22 or newer as the engine requirement. Those constraints matter for self-hosters more than for anyone just running the CLI.

A fast moving codebase with an explicit test story

The last push was on 2026-10-21, and three tagged releases sit in the preceding weeks: v2.0.6 on 2026-10-04, v2.0.5 on 2026-10-01 and v2.0.4 on 2026-09-27. The pace is short cycle and the project describes itself as moving fast, which is consistent with the rule that server changes can break older clients.

For contributors, the workflow is explicit. Clone, install, copy the example environment file, then run the server locally:

sh
pnpm install
cp apps/server/.env.example apps/server/.env
pnpm dev                       # tunnel server on http://localhost:8787
pnpm build                     # build the CLI
node apps/cli/dist/hostc.mjs 3000 --server http://localhost:8787

In development, tunnels are served on `http://<id>.localhost:8787`, relying on Chrome and Firefox resolving `*.localhost` to the local machine. The workspace exposes a check script that runs formatting, linting, typechecking and tests together, plus an end to end script that drives wrangler dev with the CLI and a local origin:

sh
pnpm check      # format check, lint, typecheck, unit and integration tests
pnpm test:e2e   # wrangler dev + CLI + a local origin, end to end

The root package.json also lists oxlint and oxfmt for linting and formatting, with TypeScript and vitest in the devDependencies.

Editorial conclusion

hostc fits front end work that needs to be seen from another device or another network: sharing a build with a client, triggering Stripe, GitHub or Slack webhooks against local code, or letting a coding agent read a live URL. It is the wrong tool for anything that must stay private, because the generated address has no access control and no credential in front of it. Before adopting it for a team, check two things: that you can tolerate every visitor who has the link, and that you can run it through npx hostc@latest every time, since the project states that an installed copy stops working when the server moves on.

Frequently asked questions

Does hostc need an account or an auth token?

No. The project states that there is no sign-up, no auth token and no binary to download, so running it needs only Node.js and the command. A token secret appears only when you self-host the server, where the guide asks for at least 32 random bytes in TOKEN_SECRET.

Does hostc keep WebSockets and hot reload working?

Yes. The documentation says WebSockets pass straight through so frameworks such as Vite and Next.js update every open device when you save, and that Server-Sent Events stream as they are produced. The hostc client opens one outgoing WebSocket and turns each request or WebSocket into a stream on that connection.

Will I keep the same public URL if I restart hostc?

No. The usage notes say that restarting hostc gives a new URL and that Ctrl+C releases it immediately. What does survive is a network drop or a server restart, in which case the URL stays the same and hostc reconnects on its own.

Can I run the hostc tunnel server on my own domain?

You can. The self-hosting section describes adding an API domain and a tunnel domain to Cloudflare with a proxied wildcard DNS record, setting the TOKEN_SECRET, and running the deploy script with API_DOMAIN and TUNNEL_DOMAIN. Clients then use the --server option to point at it.

Official sources

  1. akazwz/hostc on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/akazwz-hostc.svg)](https://hysenlabs.com/projects/akazwz-hostc)

Was this useful?