← Back to posts

Stop Forcing Everything Through One Terminal: A Controlled AI Coding Desk with tmux / Zellij

The point of a terminal multiplexer is not more agents at once. It is making task ownership, write scope, verification, and human decisions visible and controlled.

The first time people run Claude Code and Codex side by side, they often reach the wrong conclusion: open more terminals, assign an agent to every pane, and throughput will grow linearly. It will not. Unbounded parallelism produces duplicate edits, overlapping files, fragmented context, and a merge bill paid by the human at the end. A terminal multiplexer is useful because it turns parallel work into a system you can observe, pause, and resume.

I treat tmux or Zellij as an AI coding control surface, not a badge of terminal fluency. tmux organizes sessions, windows, and panes; a session can detach and later reattach while its programs keep running. Zellij makes panes, tabs, and layouts more immediately visible. Their shared value is that terminal real estate can have persistent responsibilities instead of becoming a trail of one-off commands.

Start with a four-part desk: read-only investigation at top left, implementation A at top right, tests and logs at bottom left, and implementation B or manual work at bottom right. The number of panes is not the point. One pane should have one job. Investigation is read-only by default; verification does not accept “done” as proof; two implementation panes run together only when their file scopes do not overlap. The layout becomes a collaboration contract.

The key rule is this: a pane is a task boundary, not an agent boundary. Do not give the same feature to two capable coding agents and hope competition will improve it. Split by write scope instead: one task owns tests or documentation, one owns an isolated module, and another only investigates. If two tasks touch the same data flow, component, or configuration surface, they are dependent work and should be sequenced, not parallelized.

Choose tmux when you want a durable, scriptable terminal environment that survives remote access and reconnects. Name a session for the project with `tmux new -s product-ai`; detach with `Ctrl-b d`; return through `tmux attach -t product-ai`. Think of the layout as project runtime state: one window for implementation, one for checks, one for Git and deployment observation. Its strength is predictability, especially over SSH.

Choose Zellij when you value a workspace that is legible at a glance. Its layouts can define tabs, panes, and startup commands, so an `ai-workflow` layout can reserve places for investigation, implementation, verification, and Git. That reduces shortcut memorization, but it does not replace task design. A layout presents responsibilities; it cannot invent safe boundaries for them.

Before starting Claude Code or Codex, write a compact handoff: the goal, allowed directories, prohibited surfaces, the exact verification command, and the stop condition. For example: “Change only `src/auth/**` and its tests; do not alter the API contract; run `pnpm test auth`; stop and report if a database migration is needed.” That is only marginally longer than “improve login,” but it dramatically reduces collateral damage when work is parallel.

The two tools can coexist, but they should not share an undeclared write zone. Claude Code supports continuing or resuming CLI sessions; Codex is likewise a terminal coding agent that works from task context and tools. Use one for exploration, review, or tests and the other for a bounded implementation. If work really needs isolated branches, add Git worktrees: they isolate the filesystem, not just the conversation.

Verification deserves its own pane because its role is the inverse of implementation. An implementation pane produces a candidate change; verification tries to falsify it. Keep type checks, focused tests, the dev server, and logs there. When an agent says it is finished, accept the diff and command output as evidence—not the explanation. Moving verification out of a chat transcript and into a visible terminal removes a common illusion of completion.

A safe rhythm is: establish file boundaries in investigation, send two non-overlapping small tasks to implementation, start the smallest meaningful checks early, and involve a human only for conflicts, failures, or product decisions. At the end, inspect `git diff` and make an atomic commit for one clear intention before the next round. The multiplexer preserves the process; Git preserves the right to reverse it.

This is not a recipe for more agents. It is a recipe for less confusion: every task has an owner, every write has a scope, every conclusion has verification, and every parallel branch has an exit condition. You may end up with fewer panes open—but each one will be answering a question you can name.

— End —