Headless mode
Keep your development stack running on a stable host and return to the same work from your desktop app, a browser, or the hob mobile app.
Run hob on a VM, workstation, or server so your development environment stays available when you leave your laptop. Headless mode runs the hob Host without requiring a native window. Connect your hob desktop app to it for the full app, including web panes. The Web IDE brings the same workspaces to a browser tab on a computer without hob, and the hob mobile app brings monitoring and steering to your phone.
- Isolation — keep project files, agent tools, and credentials on a dedicated machine.
- Uptime — let agents, commands, and automations continue when your laptop sleeps or disconnects.
- One setup — install and authenticate your development stack once on the host.
- Remote review — return to the same conversations, previews, and changes from another device.
Access requirements
The Host you connect to and the desktop that connects both need an active hob Pro+ license. The Web IDE and hob mobile need it on the Host. Without one, the Host still starts and keeps running, but without remote access. See If the license is inactive. Use the same operating-system account for installation, license activation, agent authentication, and the service.
Set up a new VM
From your desktop app, hob sets up a VM over SSH in one window. You need the
hob desktop app on your own computer, with an active Pro+ license, and an SSH
login to the VM. An entry in ~/.ssh/config makes the VM appear in the list.
How you sign in depends on your own computer:
- macOS and Linux: a password or a key with a passphrase works. You sign in once inside the setup, and hob reuses that connection until the setup closes.
- Windows: use an SSH key that signs in without a prompt, for example a key in the SSH agent. Windows' OpenSSH cannot share a connection, so each step signs in on its own.
After the setup, each connection to the VM signs in on its own, on every computer, so it needs such a key too.
Choose the VM
In the desktop app, choose the computer button at the left of the titlebar,
then Connect to a new computer, then Choose SSH machine. Pick the VM,
or enter the destination you use with ssh, such as me@203.0.113.7. hob uses
your own ssh, keys, and ~/.ssh/config, and stores no SSH credentials.
Follow the steps
Set up hob on your VM checks the VM and shows the setup as one list: sign in, install, PATH, license, run, and connect. What the VM already has is ticked, and only the next step is open.
- If ssh must ask you something first, such as whether to trust the VM's host key, you answer it in a terminal inside the step. The installer runs there too, so you can type your sudo password when it asks.
- When a new shell on the VM does not find
hob, hob offers to add it toPATHin your shell's startup file. - For the license, use this computer's license or paste another key. The key reaches the VM over SSH only, never on a command line.
- Always run keeps hob running on the VM as a service: on Linux also after a restart, on a Mac each time someone signs in to it. Run now starts it until the VM restarts. On Linux, starting at boot before anyone signs in can need your sudo password once, and hob asks in the step.
- Last, hob turns on desktop connections, opens an SSH tunnel, and approves the request on the VM over SSH. Name the computer, then open it.
Not now skips a step. Skipping PATH continues; skipping the install, the license, or the run ends the setup there, because the later steps need it. The setup then lists each skipped step with the command to run on the VM later. You can also choose the VM again in Host connections to continue.
Remote access needs Pro+ on both computers. If you do not have a key, start the hob Pro+ trial. Setting up a Windows computer over SSH is not supported yet; hob says so when you choose one.
Keep working on the VM
Each later connect opens a new SSH tunnel; there is nothing to keep running. Install and sign in to your agent tools on the VM: the Host's own setup offers this the first time a window shows it. The first time you connect, hob also asks whether to set up the VM like this computer. See Set up the other Host from your desktop.
From the command line, hob connection check --ssh <destination> shows the next
step, and hob connection pair --ssh <destination> pairs.
Set up from the VM's terminal
You can also set up the VM in its own terminal and pair through an SSH tunnel that you run.
-
Install hob on the VM:
curl -fsSL https://get.hob.dev/install | shIf a new shell does not find
hob, run~/.local/bin/hob app path add. It adds hob's folder toPATHin your shell's startup file (bash, zsh, or fish). For another shell, it prints the line to add.Install and authenticate your agent backends on this host too. Bring the repositories, language runtimes, package managers, MCP configuration, and other tools the projects need. Accounts and profiles let you keep backend setups organized on this machine.
-
Start the Host:
hob --headlessWhen this machine has no active license, hob asks for the key:
hob headless is running without remote access: the license is inactive. Activate the license on this computer: hob app license activate No license key yet? Start a hob Pro+ trial: https://hob.app/trial License key (Enter skips):Paste the key. The input stays hidden. hob activates the license on the running Host and continues:
License activated: hob Pro+ trial, expires <date>. hob headless is ready. Desktop app (recommended): desktop connections set to Localhost only, port 22907. Web IDE (browser fallback): <your credentialed access URL> -
The guided pairing session starts next. Press Enter to keep Localhost only. On your computer, open an SSH tunnel and keep it running:
ssh -N -o ExitOnForwardFailure=yes -L 22908:127.0.0.1:22907 <user>@<address you use for SSH>Then run
hob connection pair 127.0.0.1:22908on your computer, or choose the computer button in the titlebar, then Connect to a new computer, and enter127.0.0.1:22908. The VM shows the request with its code. Approve it only when the code matches on both computers, then confirm the code on your computer and name the Host. Choose Connect to open the VM in your desktop app.On a VPN, choose Private networks in the session and pair with the VM's VPN address instead; see VPN or private network.
The order does not matter. You can activate first with
hob app license activate, then run hob --headless. For a script or a
service, give the key on standard input:
printf '%s\n' "$HOB_LICENSE_KEY" | hob app license activate --key-stdinhob asks for the key only in a terminal, and never with --detach or under a
service manager.
Desktop and Host
In the 1.19 beta, the desktop window runs in Electron. The Go Host owns your projects, sessions, and files. Headless mode runs that same Host without a desktop window; your desktop app on another computer, a browser, or the hob mobile app supplies the interface. Closing a window and stopping the Host are different actions.
Choose how to keep it running
Choose how the Host keeps running after setup:
| Method | Use it for | Lifetime |
|---|---|---|
Foreground: hob --headless | Setup and troubleshooting. | Stays attached; Ctrl-C or SIGTERM requests Host shutdown. |
Daemon: hob --headless --detach | Leaving the Host running after your shell exits. | Enables the daemon service and returns. Does not install an operating-system startup service. |
Service: hob service install | A host that starts hob again after a restart. | Runs the foreground command as a systemd user service, a launchd agent, or a scheduled task. See Run hob as a service. |
| tmux, byobu, or screen | Keeping a foreground session you can reattach to. | Survives SSH disconnect while the multiplexer lives; does not start after reboot. |
Closing an app or a browser, or losing its connection, does not stop the Host. Host shutdown ends running agents, commands, and preview servers; a later start restores saved context. See Returning to your work for that boundary.
Run the Host
Start in the foreground
hob --headless stays attached to your terminal. Its output starts with the
ready lines:
hob headless is ready.
Desktop app (recommended): desktop connections set to Localhost only, port 22907.
Web IDE (browser fallback): <your credentialed access URL>The desktop line comes first because the desktop app is the recommended way to use a headless Host. The Web IDE line appears once the Web IDE serves. Keep that URL private: it carries the Web IDE credential.
The Host restores saved project/window context when available. On a fresh setup, open a folder from the desktop app or the Web IDE to choose a project on the host.
Do not append a project path to --headless. The current command starts
headless service mode and rejects a path or native-window target. The shell's
working directory does not select a project. Choose and switch projects from
the connected app instead.
Press Ctrl-C to request Host shutdown and wait for it to finish. During a long shutdown or restart, the command reports progress; a second interrupt detaches the foreground command without forcing the Host to exit. Closing a terminal abruptly is not a substitute for this explicit shutdown.
If the license is inactive
Without an active Pro+ license, hob --headless does not exit. The Host starts
without remote access and prints:
hob headless is running without remote access: the license is inactive.
Activate the license on this computer: hob app license activateIn a terminal, hob then asks for the key, as in
Set up a new VM. Press Enter to skip. Without a
terminal, or with --detach, hob does not ask.
In this mode there is no Web IDE or remote access, and agents, terminals, and
automations stay unavailable. A service manager sees a running service, so the
service does not restart in a loop. To activate later, run
hob app license activate from another shell as the same user. The Host
switches to full service at once, without a restart, and the foreground
command prints its ready lines within a few seconds.
If the Web IDE is off
If you set the Web IDE to Off, hob --headless starts normally and says so:
Web IDE (browser fallback) is off. Turn it on: hob connection web-ide localhostDesktop connections are a separate switch; see Desktop connections and the Web IDE.
If the port is in use
If another program already listens on the Host's port, hob keeps running and
prints the port, a command that finds the program, and the next steps. Stop
that program and the Host takes the port again by itself, within about 30
seconds. To use another port instead, stop the Host, then start it with
--port:
hob --headless --port 22917hob saves the port, so later starts, --detach, and restarts keep it. --port
works only with --headless. While the Host runs, it cannot change its port:
the command stops with an error that tells you how to stop the Host first.
Run more than one Host on a computer
hob runs one Host for each config directory. The config directory holds the
settings, the license activation, paired computers, projects, and logs. To
run a second headless Host on the same computer, give it its own config
directory with --config-dir and its own port:
hob --config-dir ~/.config/hob-b --headless --port 22917 --detach- A new config directory starts empty. Activate the license and pair your computers for it, as for a new computer.
- Name the config directory in each command you run for that Host, for
example
hob --config-dir ~/.config/hob-b connection pending. A command without--config-dirreaches the Host of the default config directory. The commands that hob prints for a Host include its--config-dir. - Agents and terminals inside a Host already use that Host's config directory.
- Put
--config-dirbefore the command. It has the same effect as theHOB_CONFIG_DIRenvironment variable.hob --config-dir <dir> service installgives that Host its own service. - On your own computer, forward a different local port to each Host, for
example
-L 22918:127.0.0.1:22917.
Enable the daemon service
hob --headless --detachThe command enables the elected Host's headless service, prints the same ready lines, and returns to the shell. The Host keeps running after the shell exits, also when you started it over SSH and close the session. This is hob's daemon mode; use a service if hob should also start after a restart.
To print the Web IDE URL again without staying attached, run the same command.
To stop a daemon you started this way, run hob --headless as the same user,
wait for its ready message, then press Ctrl-C once and wait for shutdown.
For a Host that the service runs, use hob service uninstall, or stop it with
the service manager, for example systemctl --user stop hob-headless.service.
Run hob as a service
To start hob again after a restart, install it as a service of the operating system. Run this as the user that runs hob:
hob service installThe service runs the foreground command hob --headless, so stopping the
service is the same Host shutdown as Ctrl-C. Check it with
hob service status.
| System | Service | When it starts hob |
|---|---|---|
| Linux | systemd user service hob-headless.service | At boot when lingering is on; otherwise when you sign in. |
| macOS | launchd agent dev.hob.headless | When you sign in to the Mac. After a restart, it waits for a sign-in. |
| Windows | Scheduled task hob headless | Installed as an administrator: at boot, under your account, without a stored password. Otherwise: when you sign in. |
If hob already runs. When a Host already runs outside the service, for
example after hob --headless --detach, install leaves it running. The service
takes over at its next start. To move the Host to the service now, run
hob service install --replace-running. This stops the running Host first,
which ends its agents, terminals, and preview servers.
Lingering on Linux. Without lingering, a user service starts when you sign in and stops when your last session ends. Install turns lingering on when the system allows it. When it needs an administrator, install prints the command:
sudo loginctl enable-linger "$USER"Some Linux systems end all your processes when you sign out
(KillUserProcesses in systemd-logind). There, only the service with lingering
keeps hob running; hob service status says when this applies.
Logs. Read the startup output, including the access URL, with
journalctl --user -u hob-headless.service -f on Linux, or in
~/Library/Logs/hob/headless.log on macOS. Keep them private: the output
includes the credentialed browser URL.
Environment. A service does not run your interactive shell startup files.
On Linux, add variables with systemctl --user edit hob-headless.service, under
[Service], for example Environment=PATH=.... hob keeps that file when you
install again. Then restart the service:
systemctl --user restart hob-headless.service.
To remove the service, run hob service uninstall. It stops the service and
its Host, removes the service, and on Linux turns lingering off again when
install turned it on.
Use a terminal multiplexer
Run hob --headless inside your existing tmux, byobu, or screen session and
detach the multiplexer as usual. Reattach to return to its output. Pressing
Ctrl-C inside that foreground session requests Host shutdown; detaching the
multiplexer leaves it running.
Desktop connections and the Web IDE
A headless Host serves two kinds of connection on one listener port, 22907
by default. Each has its own switch:
| Desktop connections | Web IDE | |
|---|---|---|
| What connects | The hob desktop app on another computer | A browser tab on another computer |
| Where to set it | hob desktop tab of Access to this computer | Web IDE tab of Access to this computer |
| Command on the Host | hob connection desktop [off|localhost|lan] | hob connection web-ide [off|localhost|lan] |
Each switch is Off, Localhost only, or Private networks only,
independently of the other. A new profile starts with both switches Off.
hob --headless sets each switch that you never chose to Localhost only
and saves it, so Settings shows the real value. A switch that you set to Off
stays Off. Run the commands from any shell on the Host, as the same user;
hob connection access is the older name of hob connection desktop.
Use the desktop app when you can: web panes and agent web steps run only in the desktop app (see Web steps need the desktop app). Use the Web IDE on a computer without hob.
Pair your desktop app
A foreground hob --headless runs the guided pairing session while no computer
is approved yet. To pair another computer later, run hob --headless --pair,
also while the Host runs in the background.
- Choose which computers' hob desktop app can connect: Private networks, Localhost only (for an SSH tunnel), or Off. The session shows the address that each choice makes reachable.
- On your computer, run
hob connection pair <address>, or choose the computer button in the titlebar, then Connect to a new computer, and enter the address. With SSH access to the Host, you can instead select Choose SSH machine there, or runhob connection pair --ssh <destination>; hob opens the tunnel and approves the request over SSH. With Localhost only, the SSH tunnel must already run on your computer, and the address is127.0.0.1:22908. - The session shows the request with its source address and code. Approve it only when the code matches on both computers, then confirm the code on your computer.
Then connect from your computer with Connect, or later from the Host button in the titlebar. See Connect your desktop to another Host.
Reach a VM over the internet
Desktop connections and the Web IDE accept only this machine (Localhost only) or private networks (Private networks only). A public address cannot connect. For a VM on the public internet, choose one path:
| Path | Switch on the Host | Address to pair or open |
|---|---|---|
| SSH from the desktop app | Localhost only, the hob --headless default | The SSH destination; hob opens the tunnel. See Set up a new VM. |
| SSH tunnel | Localhost only | 127.0.0.1:22908 on your computer |
| VPN, such as Tailscale | Private networks only | The VM's VPN address |
A cloud VM's private address, such as 10.0.0.5, is reachable only from inside
that cloud network.
SSH tunnel
When you connect over SSH from the desktop app, hob opens and closes this tunnel for you. Run it yourself for the Web IDE, or when you pair by address. On your computer, forward a local port to the Host's listener and keep the command running:
ssh -N -o ExitOnForwardFailure=yes -L 22908:127.0.0.1:22907 <user>@<address you use for SSH>22908 is the local port on your computer; choose a free one. 22907 is the
Host's listener port; substitute its configured port if different.
ExitOnForwardFailure stops SSH if it cannot establish the tunnel. When you
choose Localhost only, the guided pairing session prints this command with
the Host's user and port.
- Desktop app: pair with
hob connection pair 127.0.0.1:22908, or enter127.0.0.1:22908under Connect to a new computer. - Web IDE: open the printed Web IDE URL on your computer, changing only its
host and port to
127.0.0.1:22908. Preserve the path and credential fragment. The Host normally serves HTTPS using its generated local certificate, so the browser may ask you to accept that certificate on your first connection.
VPN or private network
On the Host, set the switches that you use to Private networks only:
hob connection desktop lan, hob connection web-ide lan, or the guided
pairing session. Then pair or open the URL with the VM's VPN or LAN address.
The default listener is 0.0.0.0:22907; Settings → Remote connections →
Listen address is available in Advanced mode. Restrict firewall access to the
networks you intend to use. Only hob mobile supports the
internet relay.
Restrict external file access
Some hosts should keep hob's file operations inside the active project or worktree. Set the containment policy in the environment that starts the Host:
HOB_ALLOW_READS_OUTSIDE_PROJECT_ROOTS=false hob --headlessFor the Linux service, run systemctl --user edit hob-headless.service and add
this under [Service]:
Environment=HOB_ALLOW_READS_OUTSIDE_PROJECT_ROOTS=false| Question | Behavior |
|---|---|
| Default | Unset means true: hob can access external paths where the OS user has permission. An empty or invalid value prevents Host startup. |
| How to change it | Stop the Host, set the variable, then start it again. An additional launch cannot change the running Host's environment; ordinary relaunch helpers retain the policy. |
| What it governs | With false, hob-facilitated browsing, mentions, reads, rendering, creation, edits, rename, move, and deletion stay inside the active project/worktree, including checks against escaping symlinks. External requests get a policy error. Despite the historical READS name, mutations are covered too. |
| What it does not govern | Agent subprocess filesystem access. Set each backend's permissions and sandbox separately; use OS isolation for the machine-level boundary. |
Use the work from another device
Connect from your desktop app, the Web IDE, or hob mobile, and take control when prompted. Closing the app or the browser leaves the Host and its work running. Remote access explains the surface choice, device approval, and control handoff.
The Web IDE supports project switching; native new window actions are unavailable in the browser. A native hob invocation on a machine with a desktop can attach a window to the same headless Host.
Web steps need the desktop app
Web panes render only in the hob desktop app. Agent web steps (hob web act,
hob web flow run, waits and screenshots of web panes) and automations that
drive web pages therefore run on a headless Host only while a hob desktop app
is attached to it, on the same machine or from another one. The page's network
traffic then goes through the Host's network.
With no desktop app attached, or with only the Web IDE or hob mobile
connected, these steps fail at once with pane_unavailable (no desktop) and
say how to fix it: open the hob desktop app on this machine, or attach one from
another machine. If the desktop app disconnects during a step, that step fails
the same way.
Reconnect, reopen, or restart
hob elects one Host per canonical data directory. An ordinary invocation such as
hob /path/to/project submits a native launch request to that Host; it can attach
or focus a native presentation. It is not the way to choose a project on a VM
without a desktop. A second hob --headless joins the existing Host and stays
attached, while hob --headless --detach enables the service and exits.
Native windows attached to a headless service are presentation clients. Closing them does not stop that service. Use the foreground shutdown flow or your service manager when you intend to stop the Host.
A dropped browser connection needs a reconnect, not a new Host. After an actual Host restart, reopen the access URL and return to the saved work. Start any agent processes, terminal commands, or preview servers that ended; saved conversations and layouts are distinct from running processes.
For agents
Agents run on the host with its tools and backend configuration. They use the same hob CLI to open panes, run visible terminal commands, and bring results into the workspace you review remotely. Keep the working context in hob so the person can continue from whichever device controls it.
Security checklist
- Use a dedicated OS account and scope repository, cloud, and provider credentials to its work.
- Keep desktop connections and the Web IDE on Localhost only for an SSH tunnel, or use a trusted LAN/VPN.
- Restrict listener/firewall access; desktop connections and the Web IDE have no public relay mode.
- Set hob mobile to Internet only when you want phone access through
connect.hob.dev. - Keep access URLs and startup logs private; regenerate exposed credentials in Remote.
- Set file containment and backend permissions to match the host's intended use.
Next
Last updated on 10/9/2026