Herdr now comes in three forms with nearly the same name. Here's what each one is, and how to pick.
TL;DR: Use the Herdr TUI if you work in a terminal or over SSH. Use the Herdr desktop app if you want a native window you can customize. Use herdr-core (hc) on its own only if you're scripting agents or building your own client, because it has no panes, tabs or sidebar. Already happy on the TUI? You don't need to switch.
Herdr keeps coding agents running in terminals that survive when you close your window. That's true of all three options, so the choice comes down to how you work. We build Moshi, a mobile client that supports both the Herdr TUI and herdr-core, and all facts below are as of November 4, 2026.
Which one should you use?
| If you... | Use |
|---|---|
| Work mostly over SSH on a server or VPS | Herdr TUI |
| Want to stay inside the terminal you already use | Herdr TUI |
| Need agents to resume their sessions after a reboot | Herdr TUI |
| Run agents that don't report OSC 7501 yet | Herdr TUI |
| Connect over Mosh and need scrollback | Herdr TUI |
| Want a native desktop window | Herdr app |
| Want to reshape your layout, keys and panels | Herdr app |
| Want agents to start and manage other agents from scripts | herdr-core |
| Are building your own client | herdr-core |
What's the difference?
| Herdr TUI | Herdr app | herdr-core (hc) | |
|---|---|---|---|
| What it is | Terminal app with its own server | Native desktop app, built on herdr-core | Headless runtime, draws nothing |
| Spaces, tabs and panes | Yes | Yes | No |
| Agents survive closing the window | Yes | Yes | Yes |
| Remote machines over SSH | Yes | Yes | Yes |
| Agent status | Screen detection and integrations | OSC 7501 only | OSC 7501 only |
| Resume agent sessions after a reboot | Supported agents | No, you get a fresh shell | No |
| Customization | Config file and plugins | Layouts and mods | Build your own |
| Current version | 0.9.5 | 0.1.12 | 0.1.17 |
| Price | Free, Apache-2.0 | Free, Apache-2.0 | Free, Apache-2.0 |
The TUI and the app don't share agents. Each has its own server, so what runs in one doesn't show up in the other.
Herdr TUI
This is the original Herdr, and the one to choose if your work happens in a terminal. It's a single binary, so you can install it on a server, SSH in, and the interface is already there. herdr --remote user@host can even install it for you.
It also has the widest agent support. It detects 22 agents out of the box by reading their screens, so most agents show their status with no setup. Installing an integration lets supported agents resume the same session after a server restart.
curl -fsSL https://herdr.dev/install.sh | sh
See the Herdr cheat sheet for its shortcuts and config. Recent development has mostly gone to the app and core, so check herdr.dev/tui if you're depending on it long term.
Herdr desktop app
This is the one to choose if you'd rather have a window than a terminal multiplexer. It's a native app for macOS on Apple silicon, Linux and Windows, and its main feature is customization: you or your agent can change layouts, keys and panels by editing files while it runs.
Keep two limits in mind. Agents only show a status if they report it through OSC 7501, and after a reboot your panes come back with a shell in the same folder, without the agents.
curl -fsSL https://releases.herdr.dev/app/install.sh | sh
The installer adds herdr-core if it's missing, so you don't need to install core separately. On a Mac you can also use brew install --cask herdr-app.
herdr-core
This is the runtime underneath the app, and you can use it directly from a shell. Choose it when agents or scripts are doing the driving. Agents started inside an hc terminal become its children, so a parent can send them work and wait for them with hc wait --children all. Templates give an agent a reusable command and role, and hc schema publishes the full API for building a client.
curl -fsSL https://releases.herdr.dev/core/install.sh | sh
hc run --bg --name web bun dev
hc attach web
For everyday hands-on work it's not enough by itself. hc attach shows one terminal at a time, and there's no layout to return to.
It also has no scrollback over Mosh. hc attach has no scroll view of its own, so history lives in your local terminal, and Mosh only syncs the visible screen. The TUI keeps its scrollback on the server, so it isn't affected. Use SSH if you need history from a core terminal.
Which agents show a status?
The TUI reads status from the screen, so it covers the agents in its detection list. The app and core rely on the agent to report through OSC 7501, a terminal protocol for program status. Anything still runs without it, but it won't have a status or appear in the app's agents list.
We've seen Claude Code report OSC 7501 in live testing, and the Codex 0.166.0 binary includes it. Pi and Crush are reported to support it too. Older agent versions may not, so update first if an agent doesn't show up. An agent running inside tmux can't report through it either, so run it directly in a Herdr pane.
How they work under the hood
If you're building on Herdr or debugging it, these are the differences that matter. Details come from the public repos.
Process model: server vs. core and holders
The TUI runs one background server that owns the PTYs, the app state and the rendering. Replacing that server with running panes intact needs live handoff, which is still experimental and opt-in (herdr update --handoff).
herdr-core splits this into two processes. A holder owns every PTY and is the parent of every program. It only spawns, pumps bytes, resizes, signals and reaps, with no parsing or policy. The core does everything else, so it can update or crash while programs keep running. The holder keeps about 1 MB of output per terminal so a crashed core can rebuild its screens, and it restarts the core itself.
Neither design survives a reboot, because the processes are gone. The TUI restores its saved layout and can resume supported agents. Core's hc run --keep brings back a fresh shell and never reruns the task.
Rendering: frames vs. raw bytes
This is the biggest architectural difference. The TUI server renders the interface itself and streams frames to its clients, so a thin client can attach from anywhere.
Core draws nothing. On attach it sends a first paint of the current screen, then the program's raw output, and each viewer runs its own terminal emulator. The desktop app does that with libghostty-vt, then draws with GPUI.
The herdr-core API
A connection starts as newline-delimited JSON-RPC 2.0 over a Unix socket, or a named pipe on Windows, so any language can talk to it:
→ {"jsonrpc":"2.0","id":1,"method":"terminal.list","params":{}}
← {"jsonrpc":"2.0","id":1,"result":{"terminals":[...],"hidden_finished":0}}
Attaching to a terminal needs framed mode, which you turn on with hello. Each frame is [channel u32 LE][kind u8][len u32 LE][payload], so many streams share one connection:
- Flow control is credit-based. A stream starts with 256 KiB of credit, and a viewer more than 4 MiB behind gets a fresh repaint instead of the backlog.
- Isolation: a stalled stream never blocks channel 0 or other streams.
- Multiple viewers: the last active viewer sets the terminal size, and
observeviewers can never type or resize. - Compatibility:
hc schemareturns an OpenRPC document generated from the Rust types. A test fails on any change that would break a client of the last release, and a real break needs a new protocol generation. It's still labelled preview, at generation 1.
The TUI has a socket API with its own JSON Schema (herdr api schema), and it covers workspaces, tabs and panes as well, which core's doesn't.
Status: a regex vs. an escape sequence
The TUI's detection manifests are TOML rules that match the bottom of a pane's screen. A simplified rule for Claude Code looks like this:
[[rules]]
id = "live_turn_working"
state = "working"
region = "bottom_non_empty_lines(12)"
The real rule adds a regex for "esc to interrupt", and the manifest's comments track which Claude Code version changed its spinner. Those rules can break when an agent changes its UI. OSC 7501 replaces all of that with one sequence the program writes itself:
printf '\033]7501;state=working\033\\'
printf '\033]7501;state=blocked:kind=permission:app=claude-code\033\\'
Fields are colon-separated key=value pairs, and title and msg are base64. Programs can ask 7501;? to detect support, and we've seen Claude Code do this and get its answer from the core. Core stores each report as given and doesn't translate it. Child records let one program report its workers separately, up to 256 records per terminal.
One limit we hit building our driver: a report can't tell one turn from the next, or spot a /new. Core does count a turn each time the root record leaves working, but apps that need exact turn boundaries still need the agent's hooks or transcript.
Where layouts live
Core has no concept of a space, but it does store the app's layout. doc.get and doc.set keep opaque JSON in docs.json, up to 1 MiB per document. Writes use optimistic concurrency: doc.set takes a version, and a stale write fails with conflict. On simultaneous edits, the newest accepted document wins.
That's how several screens share one structure while keeping their own focus and zoom, which stay local to each client. It also means a third-party client can't see what the window has selected, because that never reaches core. Our own driver polls the Herdr window every 500ms to follow it.
Remote machines
hc connect speaks the same protocol over stdin and stdout, so ssh box hc connect is a remote core. Your local core keeps the connection and merges terminal lists and events, while the remote core owns the programs and files. Addresses like box/t3 work everywhere.
Connections don't need to be plain SSH. --via accepts any command that carries bytes unchanged, which is how Fly and Vercel sandboxes attach, and --temp marks short-lived machines. hc file edit makes exact remote edits, and multiple edits succeed or fail together.
Mods in the desktop app
Mods are JavaScript that describes GPUI elements, running on a QuickJS-based runtime with hot reload. The default sidebar, tab bar and agents list are built from the same parts you get.
They aren't sandboxed. A mod can run programs with your environment, fetch URLs and read files, with no permission prompts, so read one as you would a shell script before installing it.
Security model
Core is not a sandbox. Anyone who can reach its socket can run commands as your account, and there's no API password or per-client permission check. It relies on 0700 directories on Unix and named pipe rules on Windows, and SSH provides the remote login and encryption. HC_SESSION gives you a separate core and state, but it isn't a security boundary. A blocked status stops a normal hc send, but it isn't an access control either.
FAQ
Is herdr-core the same as Herdr?
No. herdr-core is the headless runtime, and its command is hc. Herdr is the desktop app built on it. The original terminal app is called Herdr TUI.
Should I switch from the TUI to the app?
Only if you want a native window or its customization. You'd lose session resume after a reboot and status for agents without OSC 7501. Running agents don't move across, so finish or restart them in the app.
Is Herdr TUI discontinued?
No. Herdr says it keeps working, and it was still getting fixes in late October.
Is Herdr free?
Yes. The app, herdr-core and the TUI are all open source under Apache-2.0.
Can I use Herdr from my phone?
Yes. Moshi supports both the Herdr TUI and herdr-core, including the spaces and tabs you set up in the desktop app. It connects to your host from iOS or Android, so you can check on agents and answer approvals away from your desk. Over Mosh, herdr-core terminals have no scrollback, and that includes the desktop app's, so connect over SSH if you need history. If you're still deciding on a multiplexer, see tmux or Herdr.
Related Articles
- Herdr Cheat Sheet: keybindings, config and commands for the Herdr TUI
- Moshi vs. ADEs: who holds your agents when the app quits
- How to Run Claude Code from Your Phone: SSH/Mosh, tmux or Herdr, and moshi-hook, end to end
