hallway run
v1 hallway run replaces the ad-hoc npm run dev that leaves orphaned servers behind.
hallway run <slug> [--cwd DIR] [--port N] [--persist] [--name "Display name"] -- <command...>For example:
hallway run slides -- npx astro dev --port '$PORT'hallway run docs --persist -- npx vite --port '$PORT' --strictPortHallway sets PORT to the app’s port in the server’s environment, and replaces $PORT (or ${PORT}, $HOST,
${HOST}) in the command’s arguments with the app’s values when it generates the job. Quote it, as above:
unquoted, your own shell would expand $PORT before Hallway sees it, usually to nothing. The app file keeps the
command as written, so it stays right if you edit the file later.
What it does
Section titled “What it does”- Registers the app. It creates or updates
apps/<slug>.yamlwith the command, the working directory (default: where you ran it) and the port: the app’s existing port if it has one, the one you pinned with--port, or else a stable one assigned from 5100–5999. The app isexpected: adhoc, orrunningwith--persist. - Hands the server to the OS’s service manager (a launchd job on macOS, a systemd user unit on Linux, a scheduled task on Windows), so it is
owned by that, not by your session, and survives the session ending.
- Without
--persist, it won’t come back after a reboot; it stays on the dashboard asstopped, is listed under Lost at last reboot, andhallway run <slug>starts it again. - With
--persist, it is a full service that starts at login and restarts if it exits.
- Without
- Waits until the port is listening (up to 30 seconds), then prints the URL and the log path, and exits 0. If the server doesn’t come up (or exits first), it prints the last 30 lines of its logs and exits 1, and leaves the app declared so you can fix it and re-run.
Because it returns promptly and prints the URL, an agent can run it inside a tool call without hanging.
Run it again with no command to reuse the recorded one:
hallway run slidesCompanions:
hallway stop slideshallway restart slideshallway logs slides --followFramework flags
Section titled “Framework flags”Hallway sets PORT and HOST=127.0.0.1 in the server’s environment. Frameworks that don’t read PORT need a flag:
| Framework | Command |
|---|---|
| Vite | npx vite --port '$PORT' --strictPort |
| Astro | npx astro dev --port '$PORT' |
| Next.js | npx next dev -p '$PORT' |
Always pass --strictPort to Vite. Without it, Vite quietly takes another port when its own is busy, and the app
moves away from the URL Hallway printed.
Why launchd and systemd, and why not PM2
Section titled “Why launchd and systemd, and why not PM2”launchd is how macOS itself keeps things running, and systemd is how most Linux distributions do; both are reliable across reboots. On Windows, best effort, Task Scheduler starts the server at logon and Hallway’s own small supervisor restarts it if it exits (details). A second process manager (PM2, or a home-grown wrapper like the ones this command replaces) would be one more supervisor on top of them, with its own history of boot-integration problems. See Services and reboots.
Why it’s CLI-only
Section titled “Why it’s CLI-only”hallway run executes a command. That is safe in your shell, or in an agent’s shell under that agent’s own
permission prompts. It is deliberately not available over MCP, where any agent with the server
configured could use it to run arbitrary code.
To catch an agent that starts a server directly anyway, add the optional dev-server hook: it blocks
the command and tells the agent the hallway run equivalent.