> ## Documentation Index
> Fetch the complete documentation index at: https://toolkit.astralsolutions.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Port-Free Local URLs with the *.localhost Reverse Proxy

> Route your local dev servers to clean *.localhost subdomains without sudo, port numbers, or browser extensions — with full WebSocket and HMR support.

Instead of typing `http://localhost:3000`, `http://localhost:5173`, and `http://localhost:8000` into your browser for every project, the Toolkit reverse proxy lets you access `http://dashboard.localhost`, `http://api.localhost`, and `http://docs.localhost`. No `sudo`, no browser extensions, no `/etc/hosts` edits required. This works natively because `.localhost` resolves to `127.0.0.1` in every modern browser and OS per [RFC 6761](https://www.rfc-editor.org/rfc/rfc6761).

<Note>
  The proxy daemon must be running for `*.localhost` subdomains to resolve. Start it with `toolkit ui` (which starts the daemon and opens the web dashboard) or run `toolkit daemon` directly in the background.
</Note>

***

## How It Works

When you run `toolkit run` or `toolkit proxy add`, Toolkit registers a route in its lightweight local proxy server. The proxy server listens on port `80` (or a fallback port) and forwards any request for `<subdomain>.localhost` to the correct internal port on `127.0.0.1`. The mapping is stored persistently so routes survive daemon restarts.

<Info>
  **WebSocket & HMR support.** The proxy fully supports WebSocket upgrades and Hot Module Replacement (HMR) — works seamlessly with **Next.js**, **Vite**, **React**, and **Socket.io** without any extra configuration. Your live-reload and fast-refresh workflows continue to function exactly as expected.
</Info>

***

## `toolkit run <appName> <cmd...>`

The primary workflow. Launch a dev server and automatically receive a clean `*.localhost` URL. Toolkit starts your command, waits for it to bind a port, registers the proxy route, and prints the public URL — all in one step.

```bash theme={null}
# Start a Next.js app at http://dashboard.localhost
toolkit run dashboard npm run dev

# Start a Python HTTP server at http://api-docs.localhost
toolkit run api-docs python -m http.server 8000

# Start Vite and force it to use port 5173 internally
toolkit run my-landing vite --port 5173
```

| Argument / Flag       | Type       | Required | Description                                                                             |
| --------------------- | ---------- | -------- | --------------------------------------------------------------------------------------- |
| `<appName>`           | `string`   | ✅        | Subdomain to assign — `my-app` becomes `http://my-app.localhost`.                       |
| `<cmd...>`            | `string[]` | ✅        | Full launch command with arguments (e.g., `npm run dev`, `python -m http.server 8000`). |
| `-p, --port <number>` | `number`   | —        | Force the internal port the process listens on, instead of auto-detecting.              |

***

## `toolkit proxy add <subdomain> <targetPort>`

Manually register a subdomain for an already-running server. Use this when your dev server is already started and you just want to wire it up to a clean URL.

```bash theme={null}
# Map http://api.localhost → localhost:4000
toolkit proxy add api 4000

# Map http://admin.localhost → localhost:8080 and confirm in JSON
toolkit proxy add admin 8080 --json
```

| Argument / Flag | Type      | Required | Description                                                     |
| --------------- | --------- | -------- | --------------------------------------------------------------- |
| `<subdomain>`   | `string`  | ✅        | The subdomain to create (e.g., `api` → `http://api.localhost`). |
| `<targetPort>`  | `number`  | ✅        | The local port your server is already listening on.             |
| `--json`        | `boolean` | —        | Emit the registered route as JSON.                              |

***

## `toolkit proxy remove <subdomain>`

Unregister a proxy route. Traffic to `<subdomain>.localhost` will stop being forwarded — the underlying server process is not affected.

```bash theme={null}
# Remove the route for http://api.localhost
toolkit proxy remove api

# Remove a route and confirm via JSON
toolkit proxy remove admin --json
```

| Argument / Flag | Type      | Required | Description                      |
| --------------- | --------- | -------- | -------------------------------- |
| `<subdomain>`   | `string`  | ✅        | The subdomain to unregister.     |
| `--json`        | `boolean` | —        | Emit the removal result as JSON. |

***

## `toolkit proxy list`

Display all active proxy routes registered with the daemon: subdomain, target URL, originating app, PID (if launched via `toolkit run`), request count, and last-active timestamp.

```bash theme={null}
toolkit proxy list

toolkit proxy list --json
```

**Example terminal output:**

```
=== Active *.localhost Routes (3) ===

dashboard.localhost        -> http://127.0.0.1:3000 (dashboard)
api.localhost              -> http://127.0.0.1:4000 (api)
api-docs.localhost         -> http://127.0.0.1:8000 (api-docs)
```

***

## `--json` Output

**`toolkit proxy list --json`** emits an array of active route objects:

```bash theme={null}
toolkit proxy list --json
```

```json theme={null}
[
  {
    "id": "r1a2b3c4",
    "domain": "dashboard.localhost",
    "subdomain": "dashboard",
    "targetPort": 3000,
    "targetUrl": "http://127.0.0.1:3000",
    "appName": "dashboard",
    "pid": 18421,
    "createdAt": "2025-01-15T09:00:00.000Z",
    "requestCount": 1204,
    "lastActiveAt": "2025-01-15T11:28:43.000Z"
  },
  {
    "id": "r5d6e7f8",
    "domain": "api.localhost",
    "subdomain": "api",
    "targetPort": 4000,
    "targetUrl": "http://127.0.0.1:4000",
    "appName": "api",
    "pid": 19087,
    "createdAt": "2025-01-15T09:15:00.000Z",
    "requestCount": 342,
    "lastActiveAt": "2025-01-15T11:22:10.000Z"
  }
]
```

**`toolkit proxy add --json`** emits the newly created `ProxyRoute` object:

```bash theme={null}
toolkit proxy add api 4000 --json
```

```json theme={null}
{
  "id": "r5d6e7f8",
  "domain": "api.localhost",
  "subdomain": "api",
  "targetPort": 4000,
  "targetUrl": "http://127.0.0.1:4000",
  "appName": "api",
  "createdAt": "2025-01-15T09:15:00.000Z",
  "requestCount": 0,
  "lastActiveAt": "2025-01-15T09:15:00.000Z"
}
```

**`toolkit proxy remove --json`** emits a confirmation object:

```bash theme={null}
toolkit proxy remove api --json
```

```json theme={null}
{
  "success": true,
  "subdomain": "api"
}
```
