tmux reads configuration from ~/.tmux.conf on startup. Changes take effect after reloading. There are four types of options: server, session, window, and pane. Use set for session options and setw (or set-window-option) for window options. Add -g to set globally.
Essential Settings
# Change prefix from Ctrl+b to Ctrl+a
unbind C-b
set -g prefix C-a
bind C-a send-prefix
# Enable mouse mode
set -g mouse on
# Start window/pane numbering at 1
set -g base-index 1
setw -g pane-base-index 1
# Enable vi mode for copy mode
setw -g mode-keys vi
# Increase scrollback buffer
set -g history-limit 10000
# Enable 256 colors
set -g default-terminal "screen-256color"
# Enable true color (24-bit) support
set -ga terminal-features ",xterm-256color:RGB"
# Reduce escape time (important for vim users)
set -sg escape-time 0
# Automatically renumber windows when one is closed
set -g renumber-windows on
# Monitor activity in windows
setw -g monitor-activity on
set -g visual-activity on
# Reload config with prefix+r
bind r source-file ~/.tmux.conf \; display "Config reloaded!"
Custom Key Bindings
# Intuitive split keys
bind | split-window -h
bind - split-window -v
unbind '"'
unbind %
# Switch panes with Alt+arrow (no prefix needed)
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D
# Vi-style pane navigation with prefix
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# Vi-style copy mode
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-selection-and-cancel
bind -T copy-mode-vi C-v send-keys -X rectangle-toggle
Status Bar Customization
# Position
set -g status-position bottom
# Colors
set -g status-style 'bg=colour234 fg=colour137'
# Left and right sections
set -g status-left '#[fg=colour233,bg=colour245,bold] #S '
set -g status-right '#[fg=colour233,bg=colour245,bold] %d/%m #[fg=colour233,bg=colour245,bold] %H:%M:%S '
# Window status
setw -g window-status-current-style 'fg=colour1 bg=colour238 bold'
setw -g window-status-current-format ' #I:#W#F '
setw -g window-status-style 'fg=colour9 bg=colour236'
setw -g window-status-format ' #I:#W#F '
# Pane borders
set -g pane-border-style 'fg=colour238'
set -g pane-active-border-style 'fg=colour51'
Common Configuration Options
| Option | Description |
| set -g prefix <key> | Change prefix key |
| set -g mouse on | Enable mouse support |
| set -g base-index 1 | Start window numbering at 1 |
| setw -g pane-base-index 1 | Start pane numbering at 1 |
| setw -g mode-keys vi | Use vi keys in copy mode |
| set -g history-limit <n> | Set scrollback buffer size |
| set -g default-terminal <term> | Set default terminal type |
| set -sg escape-time <ms> | Set escape key delay |
| set -g renumber-windows on | Renumber windows on close |
| set -g status-position top|bottom | Status bar position |
Reloading Configuration
# From the command line
tmux source-file ~/.tmux.conf
# From within tmux command prompt (Ctrl+b :)
source-file ~/.tmux.conf
Conditional Configuration
# Different settings per tmux version
%if "#{>=:#{version},3.2}"
set -g status-position top
%else
set -g status-position bottom
%endif
# Different settings per host
%if "#{==:#{host},laptop}"
set -g status-style bg=blue
%elif "#{==:#{host},desktop}"
set -g status-style bg=green
%endif
File Locations
| Path | Description |
| ~/.tmux.conf | User configuration file |
| /etc/tmux.conf | System-wide configuration |
| /tmp/tmux-UID/default | Server socket |
tmux can be fully controlled from the command line, making it ideal for scripting automated workspace setups. The two most powerful scripting commands are send-keys (send input to a pane) and capture-pane (read output from a pane).
send-keys
Programmatically send keystrokes to a target pane. Target format: session:window.pane
# Basic usage
tmux send-keys -t <target> '<command>' Enter
# Send command to specific session:window.pane
tmux send-keys -t mysession:0.0 'ls -la' Enter
tmux send-keys -t 0:1 'vim file.txt' Enter
# Send to pane by ID
tmux send-keys -t %2 'echo hello' Enter
# Send text without pressing Enter
tmux send-keys -t 0 'text without executing'
# Send literal text (no key interpretation)
tmux send-keys -l 'text with special chars'
capture-pane
Capture the visible contents (or history) of a pane for logging or automation.
# Print pane contents to stdout
tmux capture-pane -p
# Capture to a named buffer
tmux capture-pane -b buffer-name
# Capture with scrollback history (last 1000 lines)
tmux capture-pane -S -1000 -p
# Capture to a file
tmux capture-pane -p > output.txt
# Capture with ANSI escape sequences
tmux capture-pane -e -p
# Capture specific line range
tmux capture-pane -S 0 -E 50 -p
Session Startup Script
Create a reusable script that sets up your entire workspace.
#!/bin/bash
SESSION="dev"
# Create session (detached)
tmux new-session -d -s $SESSION
# Window 0: Editor with side terminal
tmux rename-window -t $SESSION:0 'editor'
tmux split-window -h -t $SESSION:0
tmux split-window -v -t $SESSION:0.1
# Send commands to each pane
tmux send-keys -t $SESSION:0.0 'vim' Enter
tmux send-keys -t $SESSION:0.1 'npm run dev' Enter
tmux send-keys -t $SESSION:0.2 'git status' Enter
# Window 1: Server
tmux new-window -t $SESSION:1 -n 'server'
tmux send-keys -t $SESSION:1 'cd ~/server && npm start' Enter
# Select starting window and pane
tmux select-window -t $SESSION:0
tmux select-pane -t $SESSION:0.0
# Attach
tmux attach-session -t $SESSION
Useful Scripting Patterns
# Create or attach (idempotent)
tmux new-session -A -s mysession
# Check if session exists before creating
tmux has-session -t mysession 2>/dev/null
if [ $? != 0 ]; then
tmux new-session -s mysession
fi
# Kill all sessions except one
tmux kill-session -a -t keep-this-one
# List all panes across all sessions
tmux list-panes -a -F "#{session_name}:#{window_index}.#{pane_index}"
# Run command in all panes of current window
for pane in $(tmux list-panes -F '#P'); do
tmux send-keys -t $pane "ls -la" Enter
done
# Capture output of a command
tmux send-keys -t mysession:0.0 'date' Enter
sleep 1
tmux capture-pane -t mysession:0.0 -p | tail -1
Format Strings
tmux format strings let you extract structured information from sessions, windows, and panes.
# Sessions with window count
tmux list-sessions -F "#{session_name}: #{session_windows} windows"
# Windows with pane count
tmux list-windows -F "#{window_index}: #{window_name} [#{window_panes} panes]"
# Panes with dimensions and running command
tmux list-panes -F "Pane #{pane_index}: #{pane_current_command} (#{pane_width}x#{pane_height})"
Synchronize Panes
Type the same command in all panes of a window simultaneously. Extremely useful for running the same command on multiple servers.
# Toggle on/off from command prompt (Ctrl+b :)
:setw synchronize-panes on
:setw synchronize-panes off
# From CLI
tmux setw synchronize-panes on
# Add toggle binding to .tmux.conf
bind S setw synchronize-panes
Hooks
Execute tmux commands automatically when events occur.
# Notification when a new window is created
set-hook -g after-new-window 'display "New window created"'
# Auto-tile after splitting
set-hook -g after-split-window 'select-layout tiled'
# Refresh after rename
set-hook -g after-rename-window 'refresh-client -S'
# List all hooks
show-hooks -g
Nested tmux Sessions
When running tmux inside tmux (e.g., local + remote), use different prefix keys to avoid conflicts.
# Outer session uses Ctrl+a as prefix
set -g prefix C-a
# Inner session keeps default Ctrl+b
# To send commands to inner: press Ctrl+a, then Ctrl+b, then the key
# Or use Ctrl+b Ctrl+b to send prefix to inner app
Session Groups
Link sessions together so they share the same set of windows. Each session can view different windows independently.
# Create main session
tmux new-session -s main
# Create linked session (shares windows with main)
tmux new-session -t main -s secondary
# Both sessions share windows
# Each can view a different window independently
Pipe Pane Output
Log all output from a pane to a file in real time.
# Start logging pane to file
:pipe-pane -o 'cat >> ~/output.log'
# Stop logging
:pipe-pane
# Toggle binding for .tmux.conf
bind P pipe-pane -o 'cat >> ~/tmux-#I-#P.log' \; display 'Toggled logging'
Clipboard Integration
Copy tmux buffer directly to your system clipboard.
# Linux (X11)
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard'
# macOS
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'pbcopy'
# WSL (Windows Subsystem for Linux)
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'clip.exe'
Break & Join Panes
Move panes between windows without losing their state.
# Break pane out to its own window
# Key: Ctrl+b !
# Join a pane from another window into current
tmux join-pane -s 2.0 -t 1.0
# Mark a pane, navigate to destination, then join
# Ctrl+b m (mark pane)
# navigate to target window
tmux join-pane # joins the marked pane here
Display Pane Numbers Longer
Give yourself more time to read pane numbers when using Ctrl+b q.
# Show pane numbers for 4 seconds (default is 1s)
set -g display-panes-time 4000
Respawn Pane
Restart a dead or exited pane without destroying the layout.
# Respawn a specific pane
tmux respawn-pane -k -t 0
# Add binding to .tmux.conf
bind R respawn-pane -k
Monitoring Windows
# Alert when a window has activity
:setw monitor-activity on
# Alert when a window has been silent for 30s
:setw monitor-silence 30
# Visual notification in status bar
set -g visual-activity on
Custom Layouts with Exact Sizing
# Split with specific percentage
tmux split-window -h -p 30 # 70/30 horizontal split
tmux split-window -v -p 50 # 50/50 vertical split
# Save and restore layouts
tmux list-windows -F "#{window_layout}" > ~/tmux-layout.txt
tmux select-layout "$(cat ~/tmux-layout.txt)"
Environment Variables
# Set environment variable for session
tmux set-environment VAR value
# Show all environment variables
tmux show-environment
# Use in new window commands
tmux new-window -n "test" 'echo $VAR'