Always-on
There are two separate questions here, and mixing them up is the usual source of confusion:
- Do your
.testnames resolve after a reboot, without you opening LocalRun? - Does a particular project keep running?
The first is about the daemon. The second is about that project's keep-running tier.
Keeping the daemon up
Turn on Launch at login in Settings. macOS then starts LocalRun when you log in, the daemon
comes up with it, and .test names resolve without you doing anything.
This uses RunAtLoad and nothing else.
KeepAlive does not mean "start at login"; it means "restart forever". With it set, quitting
LocalRun would immediately relaunch it and the app would look possessed. Launch at login uses
RunAtLoad alone, so Quit actually quits.
Quitting LocalRun stops the daemon too. That is deliberate: the app spawns the daemon detached, so
without an explicit stop it would outlive the app and keep serving ports you thought you had closed.
If you want things running in the background, that is what launch at login and the always tier are
for.
Keeping one project up
Set that project's tier to Always. LocalRun writes a LaunchAgent for it into
~/Library/LaunchAgents, and macOS keeps it alive across quit, crash and reboot, including when
LocalRun itself is not running.
The generated agent handles the things that break only on other people's machines:
- A usable PATH. launchd gives a process
/usr/bin:/bin:/usr/sbin:/sbin. Homebrew, pnpm, bun, and any nvm-installed node are all missing from that. The agent puts your project'snode_modules/.binfirst, then the usual install locations. - Restart on failure only. A crash restarts, with a throttle. An explicit stop wins instead of fighting you.
- Logs that keep working. Output is written back into
~/.localrun/logs/, so the Logs tab still shows the project once launchd owns it.
If the first word of your run command cannot be resolved from that rebuilt PATH, LocalRun tells you
when you set the tier. Fix it by using an absolute path, or a command that lives in the project's
own node_modules/.bin.
Checking it worked
launchctl list | grep localrunYou should see an entry per always-on project. To inspect one:
launchctl print gui/$(id -u)/<label>Turning it off
Set the tier back to Manual, or press Stop. Stopping an always-on project also demotes it to Manual. Otherwise, the next reboot would bring back something you deliberately shut down.
LocalRun waits for the port to be genuinely free before reporting the stop as done, rather than assuming launchd has finished reaping the process.
What survives what
| Quit LocalRun | Crash | Reboot | |
|---|---|---|---|
| Launch at login (daemon) | Daemon stops | n/a | Comes back at login |
Project on manual | Stops | Stays down | Stays down |
Project on localrun | Stops | Restarts | Comes back with the daemon |
Project on always | Keeps running | Restarts | Comes back |
Next: Troubleshooting if something does not come back the way this table says it should.