# Ports

> Start a server on the box and open it on your laptop as localhost, with no flags or config. Mirroring is on by default and takes a few seconds; a port can also be shared with your workspace at a prized.dev link.

URL: https://prized.dev/docs/ports

## How it works [#how-it-works]

The agent on the box watches for listening TCP ports. When one appears, the daemon on your machine opens the same port on 127.0.0.1 and tunnels it to the box. Servers that bind only to the box's loopback (Vite, most dev servers) are relayed by the agent, and websockets work. On Windows the daemon runs while you are signed in.

```bash title="you@box ~/code/myproject"
npm run dev
# ready on http://localhost:3000
# two seconds later, localhost:3000 works on your machine
```

## Inspect and toggle [#inspect-and-toggle]

| Command                      | What it does                                                         |
| ---------------------------- | -------------------------------------------------------------------- |
| `prized ports ls`            | Every box listener with its process and mirror state.                |
| `prized ports toggle 3000`   | Flip a port off or back on. The preference persists across restarts. |
| `prized proxy box-3fa9 5432` | Forward one port from any box to `127.0.0.1:5432` until Ctrl-C.      |

An interactive `prized ssh` session to a non-default box forwards that box's ports for the life of the session.

## Limits [#limits]

* **TCP only.** UDP is not forwarded.
* **Ports 3000 through 9999** are auto-mirrored. The range and per-port allow and never lists live in the config's `[ports]` section.
* **Never mirrored:** ports below 1024, port 22, and the agent's port 7377; 5900 is off by default. Anything else outside the range needs an allow-list entry or a manual `prized proxy`.
* **A mirrored port is open to your whole machine,** like `ssh -L` or `docker -p 127.0.0.1:`; on a machine you share with other accounts, treat it as if the service were running there unprotected.
* **Local wins.** If something on your machine already listens on a port, the mirror waits, `prized proxy` refuses it, and an `ssh` session skips it; nothing binds underneath your own server.
* **Every request crosses the network.** An app that makes hundreds of database round trips per page should run next to its database on the box, with only the app port mirrored.

## Share a port with your team [#share-a-port-with-your-team]

`prized ports share 3000` gives a port on the box a link on prized.dev that members of your workspace can open in a browser, with nothing to install on their side.

```bash
prized ports share 3000
# ✓ port 3000 on mango shared
#   https://mango-3000-k7x2q9.p.prized.dev/
```

* **Who can open it.** Anyone who opens the link signs in to Prized first. A member of your workspace who can see the box gets through; anyone else sees a page saying the link is not available to their account. There is no public link, and no way to make one.
* **What it carries.** HTTP and websockets, so a dev server with hot reload works. The app on the box sees itself reached as `localhost:3000`, so host and origin checks in Vite, Next.js and friends pass. Anything that is not HTTP (a database, SSH) stays on [`prized proxy`](#inspect-and-toggle).
* **A paused box** is woken when someone opens the link; the page retries until the box answers.
* **Stop sharing** with `prized ports unshare 3000`, or **Stop sharing** on the box page: the link stops working within a moment for everyone on it. Deleting the box, or closing the workspace, does the same. Removing a member, or making them a contractor, closes their access as part of the change, open pages included.
* **Cookies stay on the link's own host.** Every shared port has its own host under `p.prized.dev`, and the relay keeps the app's cookies there: a cookie your app sets with a wider `Domain` is stored for that link alone, so it is never sent to a teammate's shared port. Everything else about the cookie — its name, value, path, expiry and flags — is untouched, and an app that sets no `Domain` (the usual case) sees no difference.
* **If a link answers "Too many requests",** one browser or script is asking faster than a shared port serves; reload in a moment. The relay is shared with every other workspace's links, so no single link may take it.
* **The log.** Sharing, stopping, and each member's first opening are rows on the [audit log](https://prized.dev/docs/teams#what-is-recorded).

The same controls are on the box page under **Access → Shared ports** ([Dashboard](https://prized.dev/docs/dashboard#overview)), where a selector shows what is listening on the box right now so you can pick a port rather than type it; `prized ports share` with no port lists what the box shares. Links are read by the same relay as the browser terminal, which can see the traffic as it passes and stores nothing ([Security](https://prized.dev/docs/security#other-ways-in)).

## A second box [#a-second-box]

Each box's daemon mirrors that box's ports: a box connected with `prized setup --box mango` gets `prized --box mango ports ls` and `prized --box mango ports toggle 3000`, automatic mirroring included ([Several boxes](https://prized.dev/docs/boxes#several-boxes)).

Two boxes listening on the same port collide on your machine, so the second mirror shows as `conflicted` in `ports ls`; toggle the port off on one box, or add it to `[ports].never` in that box's config.
