Guides

Run Dev Servers in Parallel

Configure ports so several workspaces can run at the same time without colliding.

Two branches, two dev servers, one machine. uxd allocates a port block per workspace; your job is to hand those ports to your app.

Single port

Most apps need one. Interpolate {port} into [env]:

~/.uxd/my-project.toml
[env]
PORT = "{port}"

[commands.dev]
run = "pnpm dev"

Now every workspace gets its own PORT:

uxd my-project feat/login run dev    # PORT=3053
uxd my-project feat/search run dev   # PORT=3011
$UXD_PORT is exported to every child process whether or not your config references it. [env] is how you map it onto the variable name your app actually reads.

Several ports per workspace

An app that needs a web port, an API port, and a database port asks for a block:

~/.uxd/my-project.toml
ports = 3

[env]
PORT = "{port}"
API_PORT = "{port+1}"
DB_PORT = "{port+2}"
VITE_API_URL = "http://localhost:{port+1}"

ports accepts 1–10. {port+N} is valid for N < ports; asking for {port+3} with ports = 3 is a config error, caught by uxd config validate.

The same values reach child processes as $UXD_PORT, $UXD_PORT_1, $UXD_PORT_2.

Pinning the window

By default uxd derives a per-project base port. Pin it when you want predictable ranges across a team, or to keep two projects out of each other's way:

~/.uxd/my-project.toml
base_port = 5700
ports = 2

Allocation starts at a deterministic candidate derived from the workspace slug within a 100-stride window above base_port, and only scans upward if that block is claimed or already listening. So a given branch keeps the same port across sessions — bookmarks and OAuth callback URLs keep working.

Overriding for one run

uxd my-project 42 run dev --port 6000

--port changes the environment for that invocation only. Nothing is persisted, and the workspace keeps its allocated block.

Checking what a workspace holds

uxd my-project list
SLUG        KIND    BRANCH      STATUS  PORT  AGE  LAST USED
feat-login  branch  feat/login  clean   3053  0m   0m

Or for one workspace, with --json if you are scripting:

uxd my-project feat/login info --json

Seeing the computed environment

Not sure what your app will receive? Ask, without running anything:

uxd my-project feat/login run dev --dry-run

--dry-run prints the environment as export lines followed by the shell-quoted command:

export UXD_PATH=~/dev/uxd/my-project/trees/feat-login
export UXD_REPO_PATH=~/dev/uxd/my-project/repo
export UXD_DATA_DIR=~/dev/uxd/my-project/trees/.data/feat-login
export UXD_PROJECT=my-project
export UXD_REF=feat/login
export UXD_BRANCH=feat/login
export UXD_SLUG=feat-login
export UXD_PORT=3053
export PORT=3053
bash -c 'pnpm dev "$@"' uxd