The ~/.tmux.conf behind the screenshots on this site — tuned for a small screen, a coding agent, and a phone and a laptop attached at the same time.
Written
tmux's defaults were written for a desktop: one client attached, a keyboard with a full modifier row, and a program whose output is text. On a phone every one of those is wrong. The screen is small, a second client is often attached from a laptop, and the thing running inside is increasingly a coding agent that speaks in colour, images and Shift+Enter — none of which survives a stock tmux intact.
This is the file we actually run, not a starter template: every tmux screenshot on this site was taken through it. Copy it whole, or take the parts you want — every line carries a comment saying what it buys, and the sections below explain the choices that are not obvious.
##### Terminal capabilities ##### # Terminal type + 24-bit true color -- without RGB, gradients show banding set -g default-terminal "tmux-256color" set -as terminal-features ",*:RGB" # RGB tells tmux the OUTER terminal speaks truecolor; COLORTERM is what the # programs INSIDE check (nvim, bat, fzf, delta) before sending 24-bit color. # tmux never passes that variable through by itself, so pin it set-environment -g COLORTERM truecolor # Inline images (sixel, kitty, imgcat) -- otherwise tmux drops them set -g allow-passthrough on set -as terminal-features ",*:sixel" # Copying inside tmux lands on the phone clipboard (OSC 52) set -g set-clipboard on # ...and over mosh too. tmux sends that OSC 52 with an empty target -- 52;; -- # and mosh forwards only 52;c;, so without this line a copy made inside tmux # reaches tmux's own paste buffer and never leaves the server. Keep the %p1: # a format that skips to %p2 loads without complaint and then sends nothing set -ag terminal-overrides ',*:Ms=\E]52;%p1%sc;%p2%s\a' # Let Ctrl+Shift+..., Shift+Enter etc. pass through tmux, in CSI u form # (Claude Code relies on this for Shift+Enter newlines) set -s extended-keys on set -as terminal-features ",*:extkeys" set -g extended-keys-format csi-u # Don't sit on Esc -- the default 500ms wait ruins Alt combos set -sg escape-time 10 # Focus events and mouse (hold Shift in the terminal for local selection) set -g focus-events on set -g mouse on # Forward window titles so the terminal app can name its tabs set -g set-titles on set -g set-titles-string "tmux · #{pane_title}" # Scrollback depth -- agents produce a lot of output, give them room set -g history-limit 100000 ##### Mobile / multiple clients attached at once ##### # Size windows to the most recently active client -- with phone and desktop # both attached, whoever is typing gets their screen size; a small client # never locks the layout down set -g window-size latest setw -g aggressive-resize on # Number windows and panes from 1, refill gaps on close -- 1 is easier to # reach than 0 on a phone keyboard set -g base-index 1 setw -g pane-base-index 1 set -g renumber-windows on # Killing the current session jumps to the next one instead of detaching -- # reconnecting from a phone is a pain set -g detach-on-destroy off # Keep messages up long enough to read on a small screen set -g display-time 2000 set -g display-panes-time 2000 ##### Code agent alerts ##### # Claude Code and friends ring the bell when done -- no screen flash, just # a bold ! flag on that window in the status line set -g bell-action any set -g visual-bell off setw -g monitor-bell on # New output in a background window -> # flag in the status line, so you # can tell at a glance which agent is running and which has stopped setw -g monitor-activity on set -g visual-activity off ##### Colors ##### # bg=default lets the terminal's own background show through, and the # accents (session name, prefix hint, activity) come from its palette. # Anything that has to stay readable on every attached client uses fixed # 256-colour values instead, which look the same in every theme # Status line on top, away from Claude Code's input box at the bottom set -g status-position top set -g status-interval 5 set -g status-style "bg=default,fg=default" # Left: session name; right: ^B hint only while the prefix is held set -g status-left "#[fg=colour5,bold] #S #[default]" set -g status-left-length 20 set -g status-right "#{?client_prefix,#[fg=colour3 bold]^B ,}" set -g status-right-length 20 # Window list: the current window is a blue block carrying its own white # text (5.8:1 in any theme), the others a mid-gray; bell(!) red, # activity(#) yellow setw -g window-status-format " #I #W#{?window_flags,#{window_flags}, } " setw -g window-status-style "fg=colour245" setw -g window-status-current-format " #I #W " setw -g window-status-current-style "bg=colour26,fg=colour231,bold" setw -g window-status-bell-style "fg=colour203,bold" setw -g window-status-activity-style "fg=colour3" # Pane borders, messages, copy-mode selection -- one gray, one blue set -g pane-border-style "fg=colour243" set -g pane-active-border-style "fg=colour32" set -g message-style "fg=colour32,bold,bg=default" # tmux's own command prompt is an opaque black bar -- match the messages set -g message-command-style "fg=colour32,bold,bg=default" set -g mode-style "bg=colour26,fg=colour231" set -g display-panes-colour colour243 set -g display-panes-active-colour colour32 setw -g clock-mode-colour colour32 ##### Key bindings ##### setw -g mode-keys vi # Splits and new windows inherit the current directory -- no need to cd # back to wherever the agent is working bind | split-window -h -c "#{pane_current_path}" bind - split-window -v -c "#{pane_current_path}" bind c new-window -c "#{pane_current_path}" # Alt+number jumps straight to a window, no prefix -- one less chord on # a phone keyboard bind -n M-1 select-window -t 1 bind -n M-2 select-window -t 2 bind -n M-3 select-window -t 3 bind -n M-4 select-window -t 4 bind -n M-5 select-window -t 5 # prefix + hjkl to move between panes bind h select-pane -L bind j select-pane -D bind k select-pane -U bind l select-pane -R ##### Copy & paste ##### # prefix + v also enters copy mode (easier to remember than [) bind v copy-mode # Copy mode: v to select, y to copy (via OSC 52 to the phone/local clipboard), # Y grabs the whole line, Ctrl+v toggles rectangle selection bind -T copy-mode-vi v send -X begin-selection bind -T copy-mode-vi y send -X copy-selection-and-cancel bind -T copy-mode-vi Y send -X copy-line-and-cancel bind -T copy-mode-vi C-v send -X rectangle-toggle # Mouse drag copies but stays in copy mode at the same spot -- no jump back # to the bottom, so you can keep reading agent scrollback; q exits bind -T copy-mode-vi MouseDragEnd1Pane send -X copy-selection # Double-click copies a word, triple-click copies the line. Word boundaries # are whitespace only, so a double-click grabs a whole file path or URL out # of agent output in one go set -g word-separators " " # Keep the `run -d0.3`: entering copy mode and copying in the same command # fills tmux's buffer but sends no OSC 52, so nothing reaches the clipboard. # -H, not -M: -M passes the click on and stretches the selection past the word bind -n DoubleClick1Pane copy-mode -H \; send -X select-word \; run -d0.3 \; send -X copy-selection-and-cancel bind -n TripleClick1Pane copy-mode -H \; send -X select-line \; run -d0.3 \; send -X copy-selection-and-cancel bind -T copy-mode-vi DoubleClick1Pane send -X select-word \; send -X copy-selection-and-cancel bind -T copy-mode-vi TripleClick1Pane send -X select-line \; send -X copy-selection-and-cancel # prefix + ] pastes the newest copy (tmux default); prefix + P opens the # buffer list to paste something copied earlier bind P choose-buffer # prefix + t: popup scratch terminal for one-off commands without touching # the agent's layout; closes on exit bind t display-popup -E -w 80% -h 75% -d "#{pane_current_path}" # prefix + r: reload config bind r source-file ~/.tmux.conf \; display "reloaded ~/.tmux.conf"
A multiplexer sits between the program and Term, and a stock one is conservative about what it passes on. allow-passthrough on is what lets inline images reach the screen — sixel, kitty graphics and imgcat all arrive as escape sequences tmux would otherwise swallow. terminal-features ",*:RGB" restores 24-bit colour, without which every gradient in a TUI turns to banding. And set-clipboard on is what makes y in copy mode land on the phone's clipboard over OSC 52, with no helper binary installed on the server.
RGB only tells tmux itself that Term can draw 24-bit colour. The programs inside decide for themselves by reading COLORTERM, and tmux never passes that variable through: a server started from a plain shell leaves nvim, bat and delta falling back to 256 colours, which looks like a washed-out theme rather than an error. set-environment -g COLORTERM truecolor pins it for every pane opened after it. Term also sets it on a running tmux server when it connects; the line keeps the config right from any terminal.
The three extended-keys lines are the newest of the group and the easiest to miss. They let Ctrl+Shift+…, Shift+Enter and friends through in CSI u form instead of flattening them into their plain equivalents. Claude Code uses Shift+Enter for a newline inside a prompt; without these lines that keystroke arrives as a bare Enter and submits the prompt half-written.
The terminal-overrides line under set-clipboard exists for one specific pairing: tmux running inside a mosh session. An OSC 52 names which clipboard it means, and tmux leaves that name empty — it sends 52;;. mosh matches the target as a literal 52;c;, so it forwards nothing, and a copy made in tmux lands in tmux’s own paste buffer and stops there. The override pins the name to c. Keep the %p1 in the format even though its value is thrown away: a version that skips straight to %p2 loads without complaint and then sends nothing at all.
Attach twice and stock tmux sizes every window to the smallest client — so the moment a phone joins, a 200-column laptop is squeezed down to 56 and stays there. window-size latest hands the size to whichever client was last active instead: type on the laptop and it is the laptop's screen, pick up the phone and it re-flows for the phone. aggressive-resize does the same for individual windows.
detach-on-destroy off is there for the same reason. Kill the last pane of a session and stock tmux drops you out to the far-end shell — which, from a phone, means the connection you just spent twenty seconds establishing. Jumping to the next session instead keeps you inside.
An agent that finishes a turn rings the bell. With monitor-bell on and visual-bell off, that becomes a bold red ! beside the window's name in the status line rather than a flash across the screen you are reading, and monitor-activity puts a yellow # on any window that produced output at all. On a phone, where exactly one window is visible at a time, the status line is the only way to tell which of four agents is still thinking and which is waiting on you.
bg=default lets Term's own background show through the status line, and the accents (the session name, the ^B hint, the activity flag) are palette colours, so they re-theme along with Term. But following the palette is not the same as staying readable. A palette colour keeps its role, not its brightness: colour8 is "bright black" in every theme, a dim grey on a dark one. And the old trick for the current window, reverse, made its contrast a lottery: 2.2:1 on a black-background palette, fine on a pastel one. With a phone and a laptop attached, the two palettes are not even the same.
So everything you have to read uses fixed 256-colour values, which draw the same in every terminal. The current window is a blue block that carries its own white text (colour26 behind colour231, 5.8:1 in any theme); the other window names are a mid-grey that reads on light and dark alike; borders, messages, the command prompt and the clock share one blue. tmux 3.7 can tell a light client from a dark one (#{client_theme}), but only when the terminal reports it, and over mosh that report never arrives, so nothing here depends on it.
Every binding here removes a chord or a trip across the keyboard. | and - split the way they look. prefix + hjkl moves between panes without going near the arrow keys. prefix + t opens a popup scratch terminal over the current pane — the phone answer to “I need to run one command without disturbing the agent’s layout” — and it closes when you exit.
Switching windows is the most frequent thing you do in tmux and the most expensive on a phone: prefix, then a digit, is two chords deep. bind -n drops the prefix entirely, and Term’s key bar has a sticky alt, so it comes down to two taps.
The -c "#{pane_current_path}" on the split and new-window bindings opens the new pane in the directory you are already in. Without it every split starts at $HOME, and the first thing you type on a phone keyboard is a long cd.
The copy bindings are tuned for picking things out of what an agent printed. Double-click copies a word, and because word-separators is just a space, a "word" is a whole file path or URL: one click instead of a careful drag. Triple-click takes the line. A mouse drag copies and leaves you in copy mode where you were, instead of snapping back to the bottom, so you can keep reading back through the scrollback; q leaves. prefix + P opens the list of earlier copies.
In the double- and triple-click bindings, keep the run -d0.3. Entering copy mode and copying in the same command fills tmux's paste buffer but sends no OSC 52, so the copy never reaches the clipboard, on any connection. The short delay lets the mode change settle first, which is why tmux's own default binding has one too.
~/.tmux.conf on the server — not on the phone. tmux reads it where the session runs.prefix + r reloads it following every edit.tmux source-file ~/.tmux.confThat middle step looks redundant next to the reload binding, and it is not: prefix + r cannot perform the first load. The binding only exists once the file has been read, and a tmux server reads its config when it starts — which, the first time, was before the file existed. The one reload you cannot do with the shortcut is the one that installs the shortcut. Note also that source-file is a tmux command rather than a shell one: that is why it needs tmux in front of it here, and nothing in front of it inside the config.
Two things to check before any of it takes: this needs tmux 3.5 or newer, because an older build answers “unknown option” at start-up and the setting silently does nothing — tmux -V tells you which you have. And on Debian and Ubuntu the tmux-256color terminfo entry the first line selects ships in the ncurses-term package rather than with tmux itself, so install that alongside it.
See also: Using tmux from a phone · SSH auto-resume · FAQ