Localghost User Flows

Drop-In Install

As a developer, I want Localghost to be a drop-in dev dependency so I can add friendly local hostnames without rebuilding the same Caddy and hosts setup in every repo.

yarn add -D @hamedb89/localghost

Then initialize the project contract:

yarn localghost init --write-scripts

Project Contract

As a developer, I want one small file that explains the local domain map for this repo.

# .localghost
app.localhost 5173
www.app.localhost 5173
api.app.localhost 8787

.localghost is the default config file. Repos can opt into another file name with --config, an ordered list of names, or a filename regex.

Machine Readiness

As a developer, I want to know whether my laptop is ready before Localghost changes system files.

yarn localghost doctor

Localghost checks for Caddy and prints the exact install command when it is missing. It does not run Homebrew automatically.

Update Awareness

As a developer, I want to know when Localghost itself is stale without paying for a network check on every run.

yarn localghost update
LOCALGHOST_NO_UPDATE_CHECK=1 yarn localghost doctor

Localghost checks npm after successful commands, caches the result for 24 hours, and ignores check failures. LOCALGHOST_NO_UPDATE_CHECK=1 and --no-update-check disable the automatic check.

One-Time Setup

As a developer, I want one explicit setup command that updates only the managed Localghost block in /etc/hosts and validates Caddy.

yarn localghost:setup

Daily Dev

As a developer, I want a daily command that starts the local HTTP proxy from the same config file, with local HTTPS available only when I ask for it.

yarn localghost:ready
yarn localghost:proxy

Most repos will run this next to their app server, for example Vite on 127.0.0.1:5173.

When a repo really needs local certificates:

yarn localghost:proxy:https

Config Discovery

As a developer, I want Localghost to fit repos that already have naming conventions without hidden file searches.

yarn localghost print --config .localghost.preview
yarn localghost print --config .localghost.private --config .localghost
yarn localghost print --config-pattern '^\.localghost\.(private|preview)$'

Localghost uses the first existing configured file. Regex discovery scans filenames in the project root.

Domain Routing

As a developer, I want to see the local domain layer as a simple domain -> upstream map.

yarn localghost routes
localghost routes
  http://app.localhost/ -> http://127.0.0.1:5173
  http://api.app.localhost/ -> http://127.0.0.1:8787

setup and dev print this same map before Caddy is validated or run.

Vite Integration

As a Vite user, I want Localghost to set the dev host to my configured domain, keep strict allowedHosts, print browser-facing URLs, and never run in production/build mode.

import { localGhostPlugin } from "@hamedb89/localghost/vite";

export default {
  plugins: [localGhostPlugin({ port: 5173 })]
};

The plugin defaults to HTTP. Pass https: true only when Vite is expected to sit behind a Caddy HTTPS proxy. Localghost prints URLs but does not open browser tabs.

If .localghost is missing, an interactive yarn dev asks whether to create it, asks for the primary .localhost domain, allows extra domains, explains the /etc/hosts password prompt, and runs setup when confirmed. Non-interactive runs fail with the exact setup command instead of guessing.

Ghost Tunnel

As a production app, I want one opt-in flag that makes <route>-<project>-<owner>.ghost.<domain> a known product entrypoint on top of the deployed Vite app, without running local Caddy or requiring the local .localghost file.

export default defineLocalghostConfig({
  ghostTunnel: {
    domains: "socialworkouts.app",
    mode: "manual"
  }
});

The production flow is DNS wildcard -> constructGhostTunnelUrl -> deployed app -> app auth -> assertSecureGhostTunnelRequest. By default the helper constructs and parses route, project, and owner from the wildcard label before ghost.<domain>, requires HTTPS, and requires the app to pass authenticated: true. See Ghost Tunnel.

Relay registration is local-agent-only: signed exact-host claims, explicit local targets, private access by default, no arbitrary URL proxy endpoint, and safe offline behavior when the agent disconnects.

When ghostTunnel is configured, route and Vite startup logs print the production URL shape. Manual mode can fill local defaults for route, project, and owner; public mode leaves those slots as <route>, <project>, and <owner> unless ghostTunnel.preview pins a concrete preview URL. Add ghostTunnel.domains to fill one or more production base domains; omit it to show the wildcard domain as *. In an interactive Vite terminal, press g to show Ghost Tunnel configuration and open a numbered concrete URL when one is configured.

Reset For Testing

As a developer, I want to retest setup without deleting my project config.

yarn localghost reset
yarn localghost setup

reset removes only the managed hosts block, generated Caddyfile, and setup state. It leaves .localghost in place.

Teardown

As a developer, I want to cleanly remove Localghost from a project when the repo is archived or no longer needs friendly hostnames.

yarn localghost teardown
yarn localghost teardown --remove-caddyfile

teardown removes only the Localghost managed /etc/hosts block. The generated Caddyfile is kept unless --remove-caddyfile is passed.

State Tracking

As a developer or agent, I want to see what Localghost changed without reading system files directly.

yarn localghost status
yarn localghost status --json

Localghost records setup and teardown in ops/local/localghost-state.json. That file is project-local state, not OS temp state.

Agent-Friendly Tools

As a Codex or agent user, I want commands that are inspectable and scriptable without opening a browser.

yarn localghost print
yarn localghost doctor
yarn localghost update

The CLI reference lives in localghost(1). Future flows can add MCP helpers and repo templates, but the base package should remain a small, predictable CLI.