Skip to content
Hallway is out (npm i -g hallway): v0, v1 and v2 have shipped, apart from checking it all on a real Mac. See the roadmap.

hallway run

v1 hallway run replaces the ad-hoc npm run dev that leaves orphaned servers behind.

Terminal window
hallway run <slug> [--cwd DIR] [--port N] [--persist] [--name "Display name"] -- <command...>

For example:

Terminal window
hallway run slides -- npx astro dev --port '$PORT'
hallway run docs --persist -- npx vite --port '$PORT' --strictPort

Hallway 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.

  1. Registers the app. It creates or updates apps/<slug>.yaml with 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 is expected: adhoc, or running with --persist.
  2. 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 as stopped, is listed under Lost at last reboot, and hallway run <slug> starts it again.
    • With --persist, it is a full service that starts at login and restarts if it exits.
  3. 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:

Terminal window
hallway run slides

Companions:

Terminal window
hallway stop slides
hallway restart slides
hallway logs slides --follow

Hallway sets PORT and HOST=127.0.0.1 in the server’s environment. Frameworks that don’t read PORT need a flag:

FrameworkCommand
Vitenpx vite --port '$PORT' --strictPort
Astronpx astro dev --port '$PORT'
Next.jsnpx 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.

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.

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.