Terminal GuideTerminal Guide

tmux.conf Configuration Guide: Customize Your tmux

Complete tmux.conf configuration guide. Learn prefix key customization, key bindings, status bar styling, mouse settings, true color, performance tuning, and workflow-specific configs.

12 min readLast updated: February 22, 2026
Dai Aoki

Dai Aoki

CEO at init, Inc. / CTO at US & JP startups / Creator of WebTerm

Configuration File Basics

tmux reads its configuration from two locations. The system-wide configuration file is located at /etc/tmux.conf, which applies settings for all users on the system. The user-specific configuration file is located at ~/.tmux.conf, which overrides system defaults for your account. In most cases, you will only need the user-level file.

tmux automatically loads ~/.tmux.conf when the server starts (i.e., when you run your first tmux session). If you make changes to the file while tmux is running, you need to reload it manually. You can do this from the command line or from inside tmux:

bash
# Reload from the command line
tmux source-file ~/.tmux.conf

# Reload from inside tmux
# Press prefix + : to enter command mode, then type:
source-file ~/.tmux.conf

As a best practice, add a keybinding to reload the configuration file so you can quickly apply changes while iterating on your config:

bash
# Add this to ~/.tmux.conf for quick reload with prefix + r
bind r source-file ~/.tmux.conf \; display "Config reloaded!"

The display command provides visual confirmation that the reload completed successfully. The \\; syntax chains multiple tmux commands together in a single key binding.

Prefix Key Customization

The prefix key is the gateway to all tmux commands. The default prefix is Ctrl+b, but most users change it to Ctrl+a for better ergonomics and compatibility with GNU Screen. The Ctrl+a key is easier to reach because the a key is on the home row.

bash
# Change prefix from Ctrl+b to Ctrl+a
unbind C-b
set -g prefix C-a
bind C-a send-prefix

The three lines above do the following: first, unbind the default Ctrl+b prefix so it is free for other uses. Second, set the new prefix to Ctrl+a. Third, bind Ctrl+a with send-prefix so that pressing Ctrl+a twice sends a literal Ctrl+a to the underlying application. This is essential for nested tmux sessions -- if you SSH into a remote machine running tmux, the outer tmux captures the first Ctrl+a, and pressing it again sends the prefix to the inner tmux.

Other popular prefix key choices include:

  • Ctrl+Space -- a comfortable key combo that does not conflict with most applications
  • ` (backtick) -- minimal finger movement, though it requires special handling when typing backticks in the terminal
bash
# Alternative: Use Ctrl+Space as prefix
unbind C-b
set -g prefix C-Space
bind C-Space send-prefix

# Alternative: Use backtick as prefix
# unbind C-b
# set -g prefix `
# bind ` send-prefix

Key Binding Syntax

tmux provides flexible key binding syntax through the bind command. Understanding the different flags lets you create intuitive, efficient keybindings.

SyntaxDescription
bind KEY commandBind KEY after prefix (default behavior)
bind -r KEY commandRepeatable binding -- key can be pressed again within repeat-time without re-pressing prefix
bind -n KEY commandNo prefix required -- key triggers the command directly (use with caution)
bind -T TABLE KEY commandBind to a specific key table (prefix, root, copy-mode-vi, etc.)

A common customization is to replace the default split-window keys (" and %) with more intuitive alternatives:

bash
# Intuitive split keys
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
unbind '"'
unbind %

# The -c flag preserves the current working directory in the new pane

Vim-style pane navigation is another popular setup. The -r flag on resize bindings lets you press the key repeatedly without re-pressing the prefix:

bash
# Vim-style pane navigation (prefix + h/j/k/l)
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

# Vim-style pane resizing (repeatable with -r)
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5

Key tables provide fine-grained control. The prefix table holds bindings activated after the prefix key. The root table holds bindings that work without a prefix (equivalent to bind -n). The copy-mode-vi table holds bindings active in vi copy mode.

bash
# Switch windows without prefix using Alt+arrow
bind -n M-Left previous-window
bind -n M-Right next-window

# Switch panes without prefix using Alt+h/j/k/l
bind -n M-h select-pane -L
bind -n M-j select-pane -D
bind -n M-k select-pane -U
bind -n M-l select-pane -R

Mouse Configuration

Enabling mouse support in tmux allows you to interact with panes, windows, and scroll buffers using the mouse. Since tmux 2.1, mouse configuration is controlled by a single option:

bash
# Enable mouse support (tmux 2.1+)
set -g mouse on

With mouse mode enabled, you can:

  • Click on a pane to select it
  • Drag pane borders to resize them
  • Click on window names in the status bar to switch windows
  • Scroll up and down with the mouse wheel to browse the scrollback buffer

In versions prior to tmux 2.1, mouse support required setting multiple individual options (mode-mouse, mouse-select-pane, mouse-resize-pane, mouse-select-window). These were consolidated into the single mouse option in 2.1. If you need to support older versions, you can use conditional configuration (covered later in this guide).

bash
# For tmux versions before 2.1 (legacy)
# setw -g mode-mouse on
# set -g mouse-select-pane on
# set -g mouse-resize-pane on
# set -g mouse-select-window on

Status Bar Customization

The status bar is one of the most visible parts of tmux and is highly customizable. You can control its appearance, content, and update frequency through several options:

OptionDescription
status-styleSet the background and foreground colors of the status bar
status-leftContent displayed on the left side of the status bar
status-rightContent displayed on the right side of the status bar
status-left-lengthMaximum length of the left component (default: 10)
status-right-lengthMaximum length of the right component (default: 40)
status-intervalUpdate interval in seconds (default: 15)
status-justifyWindow list alignment: left, centre, or right

Here is a practical status bar configuration with session name, window list, date/time, and hostname:

bash
# Status bar colors
set -g status-style bg=colour235,fg=colour136

# Left side: session name
set -g status-left-length 40
set -g status-left "#[fg=colour148,bold]#S #[fg=colour245]| "

# Right side: date, time, and hostname
set -g status-right-length 60
set -g status-right "#[fg=colour245]%Y-%m-%d #[fg=colour39]%H:%M #[fg=colour148]#H"

# Center the window list
set -g status-justify centre

# Update the status bar every second (for clock)
set -g status-interval 1

# Active window styling in status bar
setw -g window-status-current-style fg=colour39,bold
setw -g window-status-current-format " #I:#W "

# Inactive window styling
setw -g window-status-style fg=colour245
setw -g window-status-format " #I:#W "

Format Strings

tmux uses format strings (variables prefixed with #) to display dynamic information. Here are the most commonly used format strings:

FormatDescription
#SSession name
#WWindow name
#IWindow index
#PPane index
#HHostname
#hShort hostname (without domain)
#FWindow flags (*, -, Z, etc.)
#TPane title

Colors can be specified using colour0 through colour255 for the 256-color palette. In newer versions of tmux (3.2+), you can also use hex color codes like #ff5f00. Color attributes are applied using the #[fg=COLOR,bg=COLOR,ATTR] syntax, where ATTR can be bold, dim, underscore, italics, or reverse.

Color and Terminal Settings

Correct terminal and color settings are essential for applications like vim, neovim, and other TUI programs to display colors properly inside tmux.

bash
# Set the default terminal to support 256 colors
set -g default-terminal "screen-256color"

# For better compatibility, use tmux-256color if available
# set -g default-terminal "tmux-256color"

# Enable true color (24-bit) support
set -ga terminal-overrides ",xterm-256color:Tc"

# Enable RGB color support (alternative syntax)
# set -ga terminal-overrides ",*256col*:Rgb"

The default-terminal setting tells tmux what $TERM value to set inside sessions. Use screen-256color for maximum compatibility, or tmux-256color if your system has the appropriate terminfo entry. The terminal-overrides setting enables true color (24-bit color) by adding the Tc capability for terminals matching the pattern.

You can verify true color support by running this test inside tmux:

bash
# Test true color support in your terminal
awk 'BEGIN{
    s="/\"; s=s s s s s s s s;
    for (colession=0; colession<77; colession++) {
        r = 255-(colession*255/76);
        g = (colession*510/76);
        b = (colession*255/76);
        if (g>255) g = 510-g;
        printf "\033[48;2;%d;%d;%dm", r,g,b;
        printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;
        printf "%s\033[0m", substr(s,colession+1,1);
    }
    printf "\n";
}'

# Simpler test: should show a smooth gradient, not banded colors
printf "\x1b[38;2;255;100;0mTruecolor test\x1b[0m\n"

Performance Settings

These settings affect the responsiveness and behavior of tmux. Tuning them can significantly improve your experience, especially if you use vim or neovim.

OptionRecommendedDescription
escape-time0Delay after pressing Escape before tmux passes it through. Set to 0 for instant Escape response (critical for vim/neovim users).
display-time4000Duration in milliseconds that status bar messages are displayed.
repeat-time500Time in milliseconds to allow repeatable key bindings (bound with -r) without re-pressing prefix.
history-limit50000Maximum number of lines kept in the scrollback buffer per pane.
bash
# Remove delay after pressing Escape (critical for vim/neovim)
set -sg escape-time 0

# Increase status bar message display time
set -g display-time 4000

# Allow repeatable key presses for 500ms
set -g repeat-time 500

# Increase scrollback buffer size (default is 2000)
set -g history-limit 50000

The escape-time setting is particularly important. By default, tmux waits 500ms after receiving an Escape key to determine if it is part of a function key sequence. This causes a noticeable delay when switching modes in vim. Setting it to 0 eliminates this delay entirely.

Vi Mode and Copy Settings

tmux supports vi-style keybindings in copy mode, which provides a familiar experience for vim users when navigating and selecting text in the scrollback buffer.

bash
# Use vi keybindings in copy mode
setw -g mode-keys vi

# Vi-style copy mode bindings
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

# Enter copy mode with prefix + v (in addition to default prefix + [)
bind v copy-mode

With these bindings, you can enter copy mode with prefix + [ (or prefix + v with the binding above), navigate with vim keys (h/j/k/l), start selection with v, toggle rectangular selection with Ctrl+v, and yank with y. For a complete guide to copy mode including system clipboard integration, see the dedicated copy mode guide.

Window and Pane Behavior

These settings control how tmux numbers and manages windows and panes. The defaults start numbering at 0, but starting at 1 is more natural for keyboard-driven workflows since the 1 key is at the far left of the number row.

bash
# Start window numbering at 1 (instead of 0)
set -g base-index 1

# Start pane numbering at 1
setw -g pane-base-index 1

# Renumber windows when one is closed (avoids gaps like 1, 3, 4)
set -g renumber-windows on

# Automatically rename windows based on the running command
setw -g automatic-rename on

# Set the terminal title (shown in terminal tab/title bar)
set -g set-titles on
set -g set-titles-string "#S - #W"

The renumber-windows on setting is particularly useful. Without it, if you have windows 1, 2, and 3, and you close window 2, you are left with windows 1 and 3. With renumbering enabled, window 3 automatically becomes window 2.

The set-titles option updates your terminal emulator's title bar or tab name to reflect the current tmux session and window, making it easier to identify windows when using a tabbed terminal emulator.

Conditional Configuration

The if-shell command lets you include configuration that adapts to different operating systems, tmux versions, or runtime conditions. This is invaluable when sharing your dotfiles across macOS and Linux machines.

bash
# macOS-specific: use reattach-to-user-namespace for clipboard
if-shell "uname | grep -q Darwin" \
  "set -g default-command 'reattach-to-user-namespace -l zsh'"

# macOS clipboard integration (modern approach with pbcopy)
if-shell "uname | grep -q Darwin" \
  "bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'pbcopy'"

# Linux clipboard integration with xclip
if-shell "uname | grep -q Linux" \
  "bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard'"

You can also check for tmux version features:

bash
# Check tmux version for feature support
if-shell '[ "$(tmux -V | cut -d" " -f2 | tr -d "a-z")" \> "2.0" ]' \
  "set -g mouse on" \
  "setw -g mode-mouse on; set -g mouse-select-pane on"

# Load a file only if it exists
if-shell "test -f ~/.tmux.local.conf" "source-file ~/.tmux.local.conf"

The last example is a useful pattern for machine-specific overrides. Keep your main ~/.tmux.conf in version control, and use ~/.tmux.local.conf for machine-specific settings that should not be committed to your dotfiles repository.

Complete Example Configuration

Here is a well-commented, production-ready ~/.tmux.conf that brings together all the concepts covered in this guide. You can use it as-is or as a starting point for your own configuration:

bash
# =============================================================================
# tmux.conf - Production-Ready Configuration
# =============================================================================

# ---------------------
# Prefix Key
# ---------------------
# Change prefix from Ctrl+b to Ctrl+a (GNU Screen compatible)
unbind C-b
set -g prefix C-a
bind C-a send-prefix

# ---------------------
# General Settings
# ---------------------
# Remove delay after pressing Escape (critical for vim/neovim)
set -sg escape-time 0

# Increase scrollback buffer
set -g history-limit 50000

# Increase message display time
set -g display-time 4000

# Allow repeatable key presses for 500ms
set -g repeat-time 500

# Enable focus events (useful for vim autoread)
set -g focus-events on

# ---------------------
# Display
# ---------------------
# Start window and pane numbering at 1
set -g base-index 1
setw -g pane-base-index 1

# Renumber windows when one is closed
set -g renumber-windows on

# Automatically rename windows
setw -g automatic-rename on

# Set terminal title
set -g set-titles on
set -g set-titles-string "#S - #W"

# ---------------------
# Terminal & Colors
# ---------------------
# Enable 256-color support
set -g default-terminal "screen-256color"

# Enable true color (24-bit)
set -ga terminal-overrides ",xterm-256color:Tc"

# ---------------------
# Mouse
# ---------------------
# Enable mouse support (tmux 2.1+)
set -g mouse on

# ---------------------
# Key Bindings
# ---------------------
# Reload configuration
bind r source-file ~/.tmux.conf \; display "Config reloaded!"

# Intuitive split keys (preserving current path)
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
unbind '"'
unbind %

# New window preserving current path
bind c new-window -c "#{pane_current_path}"

# Vim-style pane navigation
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

# Vim-style pane resizing (repeatable)
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5

# Switch windows with Alt+arrow (no prefix)
bind -n M-Left previous-window
bind -n M-Right next-window

# ---------------------
# Copy Mode (Vi)
# ---------------------
# Use vi keybindings in copy mode
setw -g mode-keys vi

# Vi-style selection and yank
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
# ---------------------
# Status bar colors
set -g status-style bg=colour235,fg=colour136

# Left: session name
set -g status-left-length 40
set -g status-left "#[fg=colour148,bold] #S #[fg=colour245]| "

# Right: date, time, hostname
set -g status-right-length 60
set -g status-right "#[fg=colour245]%Y-%m-%d #[fg=colour39]%H:%M #[fg=colour148] #H "

# Center window list
set -g status-justify centre

# Update every second
set -g status-interval 1

# Active window
setw -g window-status-current-style fg=colour39,bold
setw -g window-status-current-format " #I:#W "

# Inactive window
setw -g window-status-style fg=colour245
setw -g window-status-format " #I:#W "

# Pane border colors
set -g pane-border-style fg=colour238
set -g pane-active-border-style fg=colour39

# ---------------------
# Platform-Specific
# ---------------------
# macOS clipboard integration
if-shell "uname | grep -q Darwin" \
  "bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'pbcopy'"

# Linux clipboard integration
if-shell "uname | grep -q Linux" \
  "bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard'"

# Load local overrides if they exist
if-shell "test -f ~/.tmux.local.conf" "source-file ~/.tmux.local.conf"

Save this configuration to ~/.tmux.conf and reload it with tmux source-file ~/.tmux.conf. As you become more comfortable with tmux, you can customize each section to match your workflow. Consider exploring tmux plugins for additional functionality like session persistence and enhanced copy mode.

Official Documentation

For authoritative information, refer to the official documentation:

Related Articles