tmux vs herdr: Which Terminal Multiplexer Fits Your Workflow

l9c l9c

TL;DR — Both are client/server terminal workspaces with the same default Ctrl+b prefix. tmux is a general-purpose multiplexer that is usually already installed on servers; herdr is a younger, agent-native workspace that tracks which pane is working, blocked, or idle and exposes that state through a JSON CLI and socket API. Pick tmux for ubiquity, plugins, and text-protocol automation. Pick herdr when orchestrating several coding agents is the main job.

At a glance

tmux 3.8herdr 0.9.5
First release20072026 (0.1.0 in March)
ImplementationC, with libevent and ncursesRust, native binary, vendored Ghostty VT parser
LicenseISCApache-2.0
Design centreAny terminal workloadTerminal workspace for AI coding agents
Object modelSessions → windows → panesSessions → workspaces → tabs → panes
Configuration~/.tmux.conf, command language~/.config/herdr/config.toml (%APPDATA%\herdr on Windows), TOML
Default prefixCtrl+bCtrl+b
MouseOn by default (set -g mouse off)Mouse-first UI; capture can be disabled
Agent stateNot built in; assemble it from pane dataBuilt-in detection: working, blocked, done, idle
AutomationShell commands, formats, hooks, text control modeJSON CLI and socket API, agent-aware waits
Remote hostsSSH per host, then attachSaved SSH machines in one client with a combined agent list
PluginsTPM and a large third-party ecosystemManifest plugins, marketplace and agent integrations
PlatformsOpenBSD, FreeBSD, NetBSD, Linux, macOS, Solaris; Windows via WSLLinux, macOS, Windows; remote servers Linux/macOS and Windows x86_64
Floating panesYes, expanded in 3.8Pane zoom plus popup/overlay panes; no general floating layer
Restore after rebootNot native; add tmux-resurrect/continuumRestores layout and resumes supported agent sessions; processes do not survive

Architecture: the same split, different vocabulary

Both tools put a long-lived server between your terminal and the programs you run. In tmux the server owns sessions, windows, and panes; clients attach to that server and can detach without stopping anything. In herdr the server owns pane processes and terminal state, while the TUI is just one client. Multiple clients can attach, and each can view a different tab.

The difference is what the hierarchy is for. A tmux window is a layout container; a herdr workspace is a project container whose sidebar state rolls up from the agents inside it, and tabs separate views such as agents, logs, and review. Herdr also gives workspaces, tabs, and panes first-class IDs that the CLI and socket API can address; a pane such as w1:p1 can be targeted directly, which matters later when you script panes by name.

Under the terminal layer, tmux carries its own VT parser and renderer in C. Herdr vendors libghostty-vt for terminal parsing and renders the result in its Rust TUI. Both are native terminal programs — there is no Electron or browser runtime in either.

Persistence: detach is table stakes, restart is the divider

On detach, both tools behave the same way: the server keeps running, so shells, agents, test runs, and servers keep working. The commands differ only in the key:

# tmux: detach with prefix + d
tmux new-session -s work
tmux attach -t work

# herdr: detach with prefix + q
herdr --session work
herdr session list

A server restart is where the designs separate. tmux has no native snapshot or reboot recovery: when the server process dies, the panes die with it. The usual answer is tmux-resurrect and tmux-continuum, which save and replay session shape, not live processes.

Herdr writes its session shape to session.json and restores workspaces, tabs, panes, cwd, layout, and focus after a server restart. The original processes are still gone. It can additionally replay recent pane screen history (opt-in, because that history can contain secrets) and, for agents with an installed integration, resume the agent's native conversation using its own resume command. Live handoff across a binary update is experimental and opt-in.

Failuretmux 3.8herdr 0.9.5
Client detaches or SSH dropsEverything keeps runningEverything keeps running
Server process stopsPanes are lostLayout restores; panes restart as new shells
Machine rebootsNothing restores without pluginsLayout restores; supported agents resume their sessions
Binary upgradeRestart server, lose panesCompatible servers keep running; --handoff can move live panes

Agent awareness: primitives vs a built-in state machine

tmux treats every pane as an opaque terminal. It exposes excellent primitives — #{pane_current_command}, pane titles, capture-pane, hooks, and, in 3.8, OSC 133 events for command start and finish — but it does not know that the thing in pane 2 is waiting for approval. You build that state machine yourself.

Herdr ships one. It identifies agents from foreground processes, screen manifests, and optional integrations, then classifies each pane as working, blocked, done, idle, or unknown. State rolls up to tabs and workspaces so the sidebar can point at the agent that needs an answer. That classification is the product, so it is also the part to evaluate critically: detection reads the visible bottom of the pane, and herdr's own docs warn that an unfamiliar approval prompt may read as idle until a manifest learns its shape.

# herdr: wait for an agent to need input, then answer it
herdr agent wait reviewer --until blocked
herdr agent prompt reviewer "fix the failing test" --wait

# tmux: send input, but you decide when the agent is ready
tmux send-keys -t agents:0.1 'fix the failing test' Enter
tmux capture-pane -p -t agents:0.1 | tail -20

Herdr also folds Git worktrees into the model: herdr worktree create makes a checkout, opens it as a workspace, and groups it under the source repo. In tmux the same workflow is git worktree add plus a new window or session — perfectly workable, just not part of the tool.

Automation: text protocol vs JSON API

tmux automation is a text protocol with decades of scripting behind it. One-shot commands return text; control mode (tmux -C) frames command output with %begin, %end, and %error and streams notifications. Formats such as #{session_name} are a small query language, and 3.8 adds event payloads, monitor hooks, and wait-for -E.

Herdr's CLI is a thin wrapper over its local socket API, and most commands print JSON. IDs are explicit and addressable, and several commands are agent-aware rather than screen-aware. The socket schema is inspectable with herdr api schema.

Tasktmux 3.8herdr 0.9.5
Run a command in a panesend-keys -t … 'cmd' Enterpane run or agent prompt
Read the screencapture-pane -p -t …pane read / agent read
Wait for outputpoll capture-pane, or build a hookpane wait-output --match/--regex
Wait for an agentnot built inagent wait --until blocked
Machine-readable outputformats and control-mode textJSON responses and herdr api schema
Event streamcontrol-mode notifications, hooks, monitorssocket API plus blocking waits
Attached TUI requiredNoNo

Which is better depends on the consumer. If an existing script already parses tmux formats or control mode, tmux remains the lowest-friction choice. If a program wants structured IDs and typed agent states, herdr's JSON surface is cleaner than parsing capture-pane output.

Remote machines: one host at a time vs a fleet in one sidebar

tmux's remote story is SSH plus attach: connect to a host, attach to the server already running there, and detach when you leave. It is simple, assumes nothing, and works on machines where you cannot install new software. Managing several hosts means several terminals or several clients.

Herdr saves SSH machines as profiles and shows their workspaces beside Local in one UI. Each machine keeps its own server, sessions, and processes, and a lost connection to one does not disconnect the others. The agent list spans connected machines, and CLI commands can be routed with herdr --machine "Build machine" agent list. It uses OpenSSH for authentication and does not store passwords or keys. The trade is that the remote side needs a compatible herdr server, which machine add can install or update with approval.

UI and input: keyboard-first vs mouse-first

Both default to Ctrl+b, and the muscle memory transfers surprisingly well. tmux is keyboard-first and its mouse handling is a single session option: with mouse off, applications inside panes still receive mouse events, but tmux itself does not bind them. Herdr is mouse-first — click panes, drag borders, right-click menus — with the prefix as an optional layer and direct chords configurable for prefix-free use.

tmux 3.8 is the stronger choice for pane geometry. Floating panes gained modal panes, mouse move and resize, new-pane -A, JSON layout strings, and default bindings such as Ctrl+b * for a new floating pane and Ctrl+b @ to toggle floating and tiled. Herdr has pane zoom and popup/overlay panes for plugins and custom commands, but not a general floating-pane layer.

Copy mode is close enough to be uneventful. Both open it with Ctrl+b [ and support movement, search, and selection, though the default key set differs: tmux uses emacs bindings unless you set -g mode-keys vi or start it with $EDITOR/$VISUAL set to something containing vi, while herdr is vi-style out of the box. Herdr keeps the pane's output flowing while you navigate history; tmux 3.8 can auto-refresh copy mode and adds scrollbars that auto-hide instead of resizing the pane.

Configuration and extensibility

A tmux config is a script. .tmux.conf is a list of tmux commands, which means any option, binding, hook, or conditional can be expressed without a separate plugin API. Extensibility grew around that: TPM installs plugins, and plugins are usually shell scripts that call tmux commands. The result is a very large, very mature ecosystem, at the cost of configuration that reads like code.

Herdr config is declarative TOML and optional — it runs without a config file, and herdr --default-config prints a complete starting point. Its plugin model is a manifest plus out-of-process commands, so a plugin can be written in any language; integrations add agent session tracking. The ecosystem is much younger, and the 0.x version number is a fair warning that defaults and APIs can still move.

tmux 3.8herdr 0.9.5
Config formatCommand scriptTOML
Extend byShell scripts, hooks, formats, TPM pluginsManifest plugins, integrations, socket API
Ecosystem sizeLarge and long-runningNew, with an indexed marketplace that is not a reviewed catalog
Stability signalMature major release0.x, pre-1.0

Portability, install, and terminal fidelity

tmux is available from the package manager of essentially every Unix-like system, is part of the OpenBSD base system, and runs on FreeBSD, NetBSD, Linux, macOS, and Solaris. On Windows it runs under WSL. That ubiquity is a feature no competing tool has matched: you can assume tmux on a server in a way you cannot assume anything else.

Herdr ships native Rust builds for Linux (x86_64, aarch64), macOS (x86_64, aarch64), and Windows x86_64, which is generally available with documented platform limits and a ConPTY-based runtime. Install options include its install script, Homebrew, mise, and PowerShell. For remote use, the server must run on Linux or macOS (x86_64 or aarch64) or Windows x86_64. Both tools are native and fast; the practical difference is distribution reach, not raw rendering speed.

On graphics, tmux handles sixel images in-tree when built with --enable-sixel, while herdr renders the Kitty graphics protocol and crops images around popups and menus. Neither is a reason alone to switch, but it matters if your agent tooling emits images.

Migration map

Tasktmux 3.8herdr 0.9.5
Start or attachtmuxherdr
Named sessiontmux new -s work / tmux attach -t workherdr --session work / herdr session attach work
DetachCtrl+b dCtrl+b q
Split right / downCtrl+b % / "Ctrl+b v / -
Move between panesCtrl+b o or arrow keysCtrl+b h/j/k/l
Rename window / tabCtrl+b ,Ctrl+b Shift+t
List sessionstmux lsherdr session list
New workspacenew session or windowCtrl+b Shift+n
Pick a window or paneCtrl+b wCtrl+b g
Send inputtmux send-keys -t …herdr pane send-text …
Read outputtmux capture-pane -pherdr pane read
Config~/.tmux.conf~/.config/herdr/config.toml (Windows: %APPDATA%\herdr\config.toml)

Which should you use?