Codeman logocodeman GitHub →

Claude Code in tmux: setup, scrolling and sessions that survive

Updated 2026-10-10

On this pageWhy run Claude Code in tmuxA minimal ~/.tmux.conf for Claude Code and CodexShift+Enter in tmux for Claude Code and CodexScrolling Claude Code and Codex in tmuxOne agent per window, namedAttach from another deviceBells and notifications in tmuxAutomation pitfallsHow Codeman handles it

Claude Code runs in tmux with no changes, and tmux is what keeps it running after you close the terminal or an SSH connection drops. Two things misbehave until you configure tmux: Shift+Enter submits instead of adding a newline, and desktop notifications never reach your terminal. Three lines in ~/.tmux.conf fix both, and set -g mouse on lets the wheel scroll Claude Code's fullscreen view. Codex uses the same file plus one setting of its own to keep its transcript in tmux's scrollback.

Why run Claude Code in tmux

A claude started directly in a terminal window or an SSH shell usually ends when the window closes or the connection drops. Inside tmux it belongs to the tmux server instead; the tmux manual says each session "is persistent and will survive accidental disconnection (such as ssh(1) connection timeout) or intentional detaching".

tmux new -s work       # start a named session, then run claude inside it
# press Ctrl-b, then d, to detach: claude keeps running
tmux attach -t work    # come back later, locally or over SSH

A reboot still ends tmux. The conversation survives on disk: claude -c continues the most recent one in that directory, and codex resume --last does the same for Codex.

Does Claude Code use tmux? Not for ordinary sessions. Agent teams can put teammates in tmux or iTerm2 split panes (teammateMode set to "tmux" or "auto"; the default is "in-process"), and inside tmux you press Ctrl+B twice to background a running command, because it is tmux's prefix. Claude Code's own way to keep work going without a terminal is agent view: claude --bg "<task>" runs a session under a supervisor process with no terminal open, and claude attach <id> reopens it. As of October 2026 it is a research preview, and a shutdown still stops its sessions.

A minimal ~/.tmux.conf for Claude Code and Codex

# ~/.tmux.conf  (tmux 3.3 or later)
set -g mouse on                              # wheel scrolling for fullscreen TUIs
set -g history-limit 50000                   # lines kept per pane; the default is 2000
set -s extended-keys on                      # tell Shift+Enter apart from Enter
set -as terminal-features 'xterm*:extkeys'
set -g allow-passthrough on                  # let notifications through to your terminal
set -s focus-events on                       # report focus changes to programs
set -s escape-time 10                        # tmux 3.4 and older wait 500 ms after Esc
set -ga terminal-overrides ',*:Tc'           # only if your terminal supports 24-bit colour

Apply it with tmux source-file ~/.tmux.conf. The extended-keys and passthrough lines come from Anthropic's tmux section; the rest from the tmux manual and changelog:

Line What it does
mouse on Needed for wheel scrolling in Claude Code's fullscreen view. The default since tmux 3.8 (September 2026), off before. To select with your terminal instead, hold Shift on many Linux terminals or Option in iTerm2 (tmux FAQ).
history-limit Lines kept per pane. Before tmux 3.7, a change only affects new panes.
allow-passthrough on Lets escape sequences past tmux: Claude Code's desktop notifications and progress bar, and Codex's OSC 9 notifications.
focus-events on Passes focus changes to programs. Reattach after changing it.
escape-time 10 How long tmux holds an Esc to see whether more keys follow; both CLIs interrupt on Esc. The default since tmux 3.5.
terminal-overrides ',*:Tc' Declares RGB colour support. Claude Code still clamps to 256 colours in tmux unless you export CLAUDE_CODE_TMUX_TRUECOLOR=1.

Shift+Enter in tmux for Claude Code and Codex

In Claude Code, Ctrl+J, or \ then Enter, inserts a newline in any terminal with no setup. Shift+Enter inside tmux needs the extended-keys lines "even when the outer terminal supports it" (terminal guide). If your terminal needs /terminal-setup (such as VS Code, Cursor, Zed or Alacritty before 0.16), run it in the host terminal, not inside tmux, since it edits the host terminal's configuration.

In Codex's keymap source, as of October 2026, Ctrl+J, Shift+Enter and Alt+Enter insert a newline by default, and /keymap rebinds them. Under tmux, Codex only asks tmux for extended keys when tmux's extended-keys-format is csi-u (keyboard_modes.rs), and the open issue openai/codex#47760 reports Shift+Enter arriving as a plain Enter with tmux's default xterm format. The reported workaround:

set -s extended-keys-format csi-u     # tmux 3.5 or later

Anthropic's lines keep the default format, so check Shift+Enter in Claude Code after the change. Ctrl+J works in both CLIs either way.

Scrolling Claude Code and Codex in tmux

Where the conversation lives decides how you scroll it:

Setup Where the history is How to scroll
Claude Code, classic renderer tmux's pane history The wheel (with mouse on), Ctrl-b [ or Ctrl-b PageUp enter tmux copy mode
Claude Code, fullscreen renderer Inside Claude Code, on the alternate screen The wheel (needs mouse on), or PgUp and PgDn
Codex, default settings On the alternate screen, not in tmux's history Set alternate_screen = "never" (below)

Run /tui to see which renderer is active; fullscreen is the default for many setups (fullscreen docs). In fullscreen, tmux search and copy mode see only the current screen. Press Ctrl+O, then [, to write the whole conversation into the scrollback where copy mode can search it, or go back to the classic renderer with /tui default or CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1. Anthropic also notes that fullscreen does not work in iTerm2's tmux -CC mode (plain tmux in iTerm2 is fine), and that tmux up to 3.6 lacks synchronized output, so redraws can flicker more than outside tmux. tmux 3.7 added it, per its changelog.

Codex uses the alternate screen by default everywhere except Zellij (config reference), so tmux's scrollback misses its transcript. The documented fix keeps terminal scrollback:

# ~/.codex/config.toml
[tui]
alternate_screen = "never"

Codex's /raw command (or Alt+R) also toggles a copy-friendly raw scrollback mode.

One agent per window, named

tmux new-session -d -s agents -n api  -c ~/src/api  claude
tmux new-window     -t agents -n web  -c ~/src/web  codex
tmux new-window     -t agents -n docs -c ~/src/docs claude
tmux attach -t agents

Naming a window at creation stops tmux from renaming it automatically. Ctrl-b w picks a window from a list, Ctrl-b 0 to 9 jumps by number, and Ctrl-b , renames. Agents working in one repository should each get their own git worktree; see Run multiple Claude Code sessions at once.

Attach from another device

ssh -t you@box tmux new -A -s agents    # attach, or create the session if it is missing
tmux attach -d -t agents                # attach and detach every other client

A window takes the size of the most recently active client, so typing on a phone also resizes the agent's screen on your desktop; attach -d avoids that by detaching the other clients. For phones, including Anthropic's Remote Control and mosh, see Use Claude Code from your phone.

Bells and notifications in tmux

Claude Code notifies when it finishes or waits on a permission prompt while you seem to be away (the hooks reference has the timings). It sends desktop notifications by default only in Ghostty, Kitty and iTerm2; elsewhere, ask for the bell in ~/.claude/settings.json:

{ "preferredNotifChannel": "terminal_bell" }

Codex notifications are on by default, sent as OSC 9 or a plain BEL (tui.notification_method, default auto), and only while the terminal is unfocused unless you change tui.notification_condition. Codex's source assumes focus until a focus event says otherwise, and tmux forwards those only with focus-events on. Setting notification_method = "bel" makes Codex ring the bell like Claude Code.

tmux monitors bells by default: a window that rang shows ! after its name in the status line, and Ctrl-b then Alt+n jumps to the next window with a bell or activity marker. From a script:

tmux list-windows -a -F '#{session_name}:#{window_name} #{?window_bell_flag,BELL,}'

Automation pitfalls

How Codeman handles it

Codeman is a self-hosted session manager built on this setup: each agent session, whether Claude Code, Codex or another CLI, runs in its own tmux session and streams to the browser as a real terminal. It uses its own socket (tmux -L codeman), so its sessions never show in a plain tmux ls; leave that socket to Codeman and use the web UI or codeman tui (Core Concepts).