tmux Documentation Hub
- Run multiple terminal sessions in one window
- Split the terminal into panes (horizontal or vertical)
- Detach sessions that keep running in the background
- Reattach to sessions from any terminal or SSH connection
- Automate complex terminal layouts via scripts and plugins
What is tmux?
tmux (terminal multiplexer) is a free, open-source command-line tool for Unix-like systems that allows you to create, manage, and persist multiple terminal sessions from a single screen. It is released under the ISC license and runs on Linux, macOS, OpenBSD, FreeBSD, NetBSD, and Solaris.
tmux operates on a server-client architecture. When you run tmux, it
starts a background server process that owns all sessions. Your terminal window connects to this server
as a client. Because the server runs independently of any client, sessions persist after you close
a terminal window or lose an SSH connection — you simply reconnect and reattach.
The three-level hierarchy is: Session → Window → Pane. A session groups one or more windows. Each window occupies the full terminal and can be split into multiple panes. Each pane runs an independent shell process.
Installation
Platform-specific installation guides with full build-from-source instructions:
- macOS — Homebrew, MacPorts, and source build
- Windows — WSL2, MSYS2, and Cygwin
- Ubuntu / Linux — APT, Snap, DNF, Pacman, APK, and source
Quick Install (Most Common)
# macOS (Homebrew)
$ brew install tmux
# Ubuntu / Debian
$ sudo apt update && sudo apt install tmux
# Fedora / RHEL
$ sudo dnf install tmux
# Arch Linux
$ sudo pacman -S tmux
# Verify installation
$ tmux -V
Basic Usage Quickstart
# Start a named session
$ tmux new -s work
# Split the window horizontally (side by side)
$ Ctrl+b %
# Split vertically (top and bottom)
$ Ctrl+b "
# Navigate between panes
$ Ctrl+b ← → ↑ ↓
# Detach (session keeps running)
$ Ctrl+b d
# List running sessions
$ tmux ls
# Reattach
$ tmux attach -t work
Understanding the Prefix Key
All tmux key bindings require a prefix key pressed first. The default prefix is Ctrl+b. Press and release the prefix, then press the command key. The prefix activates tmux's command interception and distinguishes tmux shortcuts from regular terminal input.
Many users remap the prefix to Ctrl+a (GNU Screen style) because it's easier to reach.
Add to ~/.tmux.conf:
unbind C-b
set -g prefix C-a
bind C-a send-prefix
Sessions
A session is a persistent workspace that groups windows together and continues running when you detach or close your terminal. Sessions are managed by the tmux server and can be shared between users.
$ tmux new -s mysession # create and attach
$ tmux new -s mysession -d # create detached
$ tmux ls # list all sessions
$ tmux attach -t mysession # attach by name
$ tmux rename-session -t old new # rename
$ tmux kill-session -t mysession # kill session
$ tmux kill-server # kill ALL sessions
Named vs Unnamed Sessions
Named sessions (tmux new -s name) are persistent and easy to reattach by name. Unnamed sessions receive a numeric ID (0, 1, 2…). Always name sessions for important work: tmux new -s frontend.
Session Sharing
Multiple users can connect to the same tmux session simultaneously — useful for pair programming or live server debugging. Both clients see the same terminal and can type commands.
Window Management
Windows are tabs within a session. Each window has its own set of panes. Switch between windows to work on different tasks within the same session.
$ Prefix c # create window
$ Prefix , # rename window
$ Prefix n / p # next / previous
$ Prefix 0-9 # select by number
$ Prefix w # window chooser
$ Prefix & # kill window
$ tmux new-window -n logs
$ tmux move-window -t 3
Pane Splitting & Navigation
Panes divide a window into independent terminal areas. Each can run a different command or shell.
# Split
$ Prefix % # horizontal split
$ Prefix " # vertical split
$ tmux split-window -h -p 30 # 30% width
# Navigate
$ Prefix ↑↓←→ # move focus
$ Prefix q # show pane numbers
# Resize
$ Prefix Ctrl+↑↓←→ # resize (hold)
$ tmux resize-pane -L 10
# Zoom / Kill
$ Prefix z # toggle fullscreen
$ Prefix x # kill pane
$ Prefix ! # break pane to window
Pane Synchronization
Synchronize-panes broadcasts keystrokes to all panes simultaneously — useful for running the same command on multiple servers at once.
# Toggle sync (from command mode: Prefix :)
setw synchronize-panes on
setw synchronize-panes off
# Bind to a key in .tmux.conf
bind e setw synchronize-panes
Pane Layouts
tmux provides five built-in pane layout presets. Cycle through them with Prefix Space.
| Layout | Key | Description |
|---|---|---|
even-horizontal | Prefix Space ×1 | All panes same width, side by side |
even-vertical | Prefix Space ×2 | All panes same height, stacked |
main-horizontal | Prefix Space ×3 | Large pane at top, rest at bottom |
main-vertical | Prefix Space ×4 | Large pane on left, rest on right |
tiled | Prefix Space ×5 | Even grid of equal-sized panes |
Select a layout directly: tmux select-layout even-horizontal
Copy Mode
Copy mode lets you scroll through terminal history, search text, and copy output to the paste buffer. Enter with Prefix [, exit with q.
| Action | Vi mode | Emacs mode |
|---|---|---|
| Enter copy mode | Prefix [ | |
| Exit | q | q |
| Navigate | h j k l | ← ↓ ↑ → |
| Search forward | / | Ctrl+s |
| Search backward | ? | Ctrl+r |
| Start selection | v | Space |
| Copy selection | y | Enter |
| Paste | Prefix ] | |
| Page up | Ctrl+u | Alt+v |
| Jump to top / bottom | g / G | Alt+< / Alt+> |
Enable vi keys: add setw -g mode-keys vi to ~/.tmux.conf.
System Clipboard Integration
By default, tmux uses its internal paste buffer. To integrate with the system clipboard:
# macOS — use pbcopy
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"
# Linux (X11) — use xclip
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard"
# Linux (Wayland) — use wl-copy
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "wl-copy"
# Windows WSL2 — use clip.exe
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "clip.exe"
# Or use the tmux-yank plugin (recommended)
set -g @plugin 'tmux-plugins/tmux-yank'
Configuration File
tmux reads its configuration from ~/.tmux.conf at startup. You can also use $XDG_CONFIG_HOME/tmux/tmux.conf or /etc/tmux.conf for system-wide settings.
Reload without restarting: tmux source-file ~/.tmux.conf (or Prefix : source-file ~/.tmux.conf).
set -g mouse on
set -g history-limit 50000
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
set -sg escape-time 0
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",*256col*:Tc"
For the full interactive config generator and all option reference, see /config/.
Key Binding Customization
# Add a binding
bind r source-file ~/.tmux.conf \; display "Reloaded!"
# Remove a binding
unbind C-b
# Bind without prefix (-n flag)
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
# List all bindings
$ tmux list-keys
Status Bar Customization
set -g status-position top
set -g status-interval 5
set -g status-left " #[bold]#S #[nobold]| "
set -g status-right " %H:%M %d %b #H "
set -g status-style "bg=#1e1e2e,fg=#cdd6f4"
setw -g window-status-current-style "fg=#89b4fa,bold"
TPM — Tmux Plugin Manager
$ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
# Add to top of ~/.tmux.conf:
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
# Add to VERY BOTTOM of ~/.tmux.conf:
run '~/.tmux/plugins/tpm/tpm'
# Inside tmux: install with Prefix + I
# Update: Prefix + U | Remove unused: Prefix + alt+u
Essential Plugins
| Plugin | Install Snippet | Purpose |
|---|---|---|
| tmux-resurrect | set -g @plugin 'tmux-plugins/tmux-resurrect' | Save & restore sessions across reboots |
| tmux-continuum | set -g @plugin 'tmux-plugins/tmux-continuum' | Auto-save every 15 minutes |
| tmux-yank | set -g @plugin 'tmux-plugins/tmux-yank' | System clipboard in copy mode |
| tmux-sensible | set -g @plugin 'tmux-plugins/tmux-sensible' | Sane defaults for everyone |
| Dracula theme | set -g @plugin 'dracula/tmux' | Popular dark theme with status widgets |
Full plugin guide: /plugins/
Scripting & Automation
tmux provides a rich scripting interface. Every tmux command can be run from outside tmux, making it easy to create reproducible development environments.
#!/bin/bash
# Create session if it doesn't exist
tmux has-session -t dev 2>/dev/null || tmux new-session -d -s dev -c ~/projects
# Set up editor pane
tmux rename-window -t dev:0 'editor'
tmux send-keys -t dev:0 'nvim .' Enter
# Create server pane (split)
tmux split-window -h -t dev:0
tmux send-keys -t dev:0 'npm run dev' Enter
# Create git window
tmux new-window -t dev -n 'git'
# Attach
tmux attach -t dev
Key Scripting Commands
tmux send-keys -t session:window.pane "command" Enter— send keystrokes to a panetmux has-session -t name— check if session exists (returns 0/1)tmux if-shell "condition" "cmd"— conditional command executiontmux run-shell "shell command"— run a shell command from tmux
Session Managers
For complex, repeatable workspace layouts, dedicated session managers are more ergonomic than raw shell scripts:
- tmuxinator — YAML-based session layouts, Ruby gem. Define windows and panes in a project file.
- tmuxp — Python-based session manager with JSON/YAML configs. More scriptable than tmuxinator.
tmux over SSH
tmux is the standard tool for remote server work. Start a tmux session on the remote server before starting long-running tasks. If your SSH connection drops, the session continues and you can reconnect.
# Connect and start/attach session in one command
$ ssh user@server "tmux attach -t work || tmux new -s work"
# Or add to ~/.bashrc / ~/.bash_aliases on server:
[ -z "$TMUX" ] && (tmux attach -t default || tmux new -s default)
# After reconnect, list sessions and reattach
$ ssh user@server
$ tmux ls
$ tmux attach -t work
Default Key Bindings
| Binding | Action | Category |
|---|---|---|
| Prefix c | New window | Windows |
| Prefix n / p | Next / previous window | Windows |
| Prefix w | Window chooser | Windows |
| Prefix & | Kill window | Windows |
| Prefix % | Split horizontally | Panes |
| Prefix " | Split vertically | Panes |
| Prefix z | Toggle zoom | Panes |
| Prefix x | Kill pane | Panes |
| Prefix q | Show pane numbers | Panes |
| Prefix Space | Cycle layouts | Panes |
| Prefix d | Detach session | Sessions |
| Prefix s | Session chooser | Sessions |
| Prefix $ | Rename session | Sessions |
| Prefix [ | Enter copy mode | Copy |
| Prefix ] | Paste buffer | Copy |
| Prefix : | Command prompt | Misc |
| Prefix ? | List all key bindings | Misc |
| Prefix t | Clock | Misc |
Environment Variables
| Variable | Set By | Contains |
|---|---|---|
$TMUX | tmux | Socket path and server PID — non-empty when inside tmux |
$TMUX_PANE | tmux | Unique pane identifier (e.g., %0) |
$TERM | tmux | Set to tmux-256color inside sessions |
$TMUX_TMPDIR | user | Override for tmux socket directory (default: /tmp) |
Check if running inside tmux: [ -n "$TMUX" ] && echo "inside tmux"
Format Strings
Format strings are used in status-left, status-right, window-status-format, and other config options to display dynamic values.
| Variable | Expands To |
|---|---|
#{session_name} / #S | Current session name |
#{window_index} / #I | Current window index |
#{window_name} / #W | Current window name |
#{pane_index} / #P | Current pane index |
#{pane_current_path} | Working directory of current pane |
#{pane_current_command} | Command running in current pane |
#{host} / #H | Hostname |
#{host_short} / #h | Short hostname (no domain) |
#{session_windows} | Number of windows in session |
#{client_width} | Terminal client width in columns |
#{client_height} | Terminal client height in rows |
#{?condition,if_true,if_false} | Conditional format output |
List all format variables: tmux display-message -p '#{?window_active,ACTIVE,inactive}'