routeup
Run routeup with no subcommand inside a project directory and it works as a
script runner: it starts your dev server as a child process, gives it a stable
route, and injects the route’s URLs into the environment. This is the
Portless-style mode.
routeupWhat it does
Section titled “What it does”- Loads config from
routeup.jsonor thepackage.jsonrouteupblock in the current directory. - Resolves the route from
ROUTEUP_NAME, configname, or the working-directory basename. It uses a configured root target when present and otherwise picks a free local port. - Registers the route with the local agent and, when
expose.enabledis set, claims the public route before starting the app. - Starts the configured script as a child process with routeup’s environment variables set.
- Waits for the assigned port to accept connections, then prints the ready URL.
- Tears down the route, public tunnel, and complete child process group when
the process stops or you press
Ctrl-C.
The runner is a live desired-state owner. If the agent restarts, it restores its
local claim and any configured public exposure. Stop runner mode from its owning
terminal or by letting the child process exit; routeup stop controls only
routeup serve owners.
Runner output
Section titled “Runner output”routeup prints the resolved command and route before child output starts. When no root port is configured, the assigned port may change on each run:
routeup command pnpm dev --port ${PORT} route example-app local https://example-app.localhost target / -> localhost:59370 status waiting for localhost:59370After the child starts listening, routeup prints:
ready: https://example-app.localhostChild output can appear between the preamble and the ready line.
Environment passed to the child
Section titled “Environment passed to the child”PORT=<assigned-port>HOST=127.0.0.1ROUTEUP_LOCAL_URL=https://example-app.localhostROUTEUP_URL=https://example-app.localhostNODE_EXTRA_CA_CERTS=/Users/me/.routeup/ca.crtYour app should bind the port from PORT instead of a hard-coded one. ROUTEUP_LOCAL_URL is always the local HTTPS URL. ROUTEUP_URL is the URL your app should advertise: it is local for local-only runs and becomes the public URL when the route is exposed.
With public exposure enabled, the environment changes to:
This example shows a token-less hosted URL under try.routeup.dev.
ROUTEUP_LOCAL_URL=https://example-app.localhostROUTEUP_URL=https://example-app.try.routeup.devConfig
Section titled “Config”{ "scripts": { "dev": "routeup", "dev:app": "vite" }, "routeup": { "name": "example-app", "script": "dev:app" }}With this in place, npm run dev starts routeup, which in turn runs your real
dev server (dev:app) behind https://example-app.localhost.
Public exposure
Section titled “Public exposure”Add expose.enabled to automatically open a public tunnel when the runner
starts. ROUTEUP_URL is updated to the granted public URL before the child
process launches:
{ "routeup": { "name": "example-app", "script": "dev:app", "expose": { "enabled": true } }}Requires a server configured via routeup setup --server. See
Exposing publicly for setup steps.
Command groups and terminal output
Section titled “Command groups and terminal output”routeup --help groups commands by workflow instead of presenting one long
list: Start contains exec, expose, serve, and stop; Observe contains config,
dashboard, doctor, inspect, logs, and routes; and Manage contains
machine lifecycle commands such as setup, update, uninstall, and version.
Human-readable output uses color and emphasis in an interactive terminal.
Redirected output stays plain, and NO_COLOR or TERM=dumb disables styling.
JSON and NDJSON output never contains terminal styling.
See Configuration for the full field reference, serve when you want to register a route for an app you start yourself, and exec when a separate process only needs the Routeup environment.