Skip to main content
Browse referenceAdvanced Features

Advanced Features

Unlock tmux's full potential with advanced workflows, integrations, and automation — building on the basics from the configuration guide.

Verified Nov 2026 for tmux 3.7c
8 min read
advanced

This page collects the features that turn tmux from a window splitter into a real workbench. Each section stands on its own, so jump to whatever you need. Everything here works in tmux 3.7, and most of it in much older versions too.

Mouse mode

Turn on mouse support with one line in ~/.tmux.conf:

bash
set -g mouse on

With the mouse on you can:

  • Click a pane to make it active, and click a window name in the status line to switch to it.
  • Drag a pane border to resize it.
  • Scroll with the wheel. Scrolling up enters copy mode, and scrolling back to the bottom leaves it.
  • Drag to select text. When you release the button, tmux copies the selection into a paste buffer and leaves copy mode. Paste it with Ctrl+b then ].
  • Right-click a pane or a window name for a menu of common actions.

Mouse mode means tmux handles clicks instead of your terminal app, so your terminal's own selection stops working inside tmux. Most terminals let you hold a key to bypass this, often Shift, or Option in iTerm2. Check your terminal's settings for the exact key.

Copying to the system clipboard

Text you copy in tmux goes into a tmux paste buffer first. Whether it also reaches your system clipboard depends on two things: the set-clipboard option (default external) and whether your terminal app accepts clipboard requests, a feature called OSC 52. Many modern terminals support it; some need it enabled in their settings.

If your terminal does not support OSC 52, pipe copies to a clipboard tool instead. For vi copy keys on macOS:

bash
set -g mode-keys vi
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'pbcopy'

On Linux, replace pbcopy with wl-copy (Wayland) or xclip -selection clipboard -i (X11). The copy and paste guide covers this in detail, including copying over SSH.

Pane synchronization

Synchronized panes send every key you type to all panes in the window at once. It is perfect for running the same command on several servers, each in its own pane (see the DevOps workflows).

bash
# Turn it on or off from the command prompt (Ctrl+b then :)
setw synchronize-panes on
setw synchronize-panes off
 
# Or toggle it with Ctrl+b S (add to .tmux.conf)
bind S setw synchronize-panes

Synchronization is easy to forget about. A command typed into one pane runs in all of them, so turn it off before doing anything destructive. Adding #{?pane_synchronized,SYNC ,} to your status-right shows a reminder while it is on.

Layouts: arrange, save, and restore

Ctrl+b then Space cycles through the preset layouts, and Ctrl+b then Alt+1 to Alt+7 picks one directly. Ctrl+b then E spreads the panes out evenly without changing their arrangement.

tmux can also describe the exact current layout as a string, and rebuild it later:

bash
# Print the layout of the current window
tmux display -p '#{window_layout}'
# 9295,80x24,0,0[80x11,0,0,0,80x12,0,12,1]
 
# Apply that layout again (to a window with the same number of panes)
tmux select-layout '9295,80x24,0,0[80x11,0,0,0,80x12,0,12,1]'

This is handy in scripts, where you can arrange panes by hand once, save the string, and reuse it every time.

Scripting a workspace

Because every tmux action is a command, a short shell script can build a whole project workspace in one go. This one creates the session only if it does not exist yet, so it is safe to run again:

bash
#!/bin/sh
session=api
dir=~/code/api
 
if ! tmux has-session -t "=$session" 2>/dev/null; then
  tmux new-session -d -s "$session" -c "$dir" -n editor
  tmux send-keys -t "$session:editor" 'nvim .' Enter
 
  tmux new-window -t "$session:" -n server -c "$dir"
  tmux send-keys -t "$session:server" 'npm run dev' Enter
  tmux split-window -v -t "$session:server" -c "$dir"
 
  tmux select-window -t "$session:editor"
fi
 
# Attach from outside tmux, or switch to it from inside
if [ -n "$TMUX" ]; then
  tmux switch-client -t "$session"
else
  tmux attach -t "$session"
fi

A few details make scripts like this reliable:

  • has-session -t "=api" uses = so it matches the name exactly, not a session called api-old.
  • -t "api:" with an empty window part means the next free window index in that session.
  • send-keys needs Enter at the end, or the command is typed but never run.
  • The final check uses switch-client inside tmux, because attach there would nest tmux.

See the send-keys and new-session references for every option.

Popups and floating panes

Popups open a temporary terminal on top of your layout. They are ideal for quick tools:

bash
# Ctrl+b g: lazygit in a large popup, in the current pane's folder
bind g display-popup -E -d '#{pane_current_path}' -w 90% -h 90% lazygit
 
# Ctrl+b N: a scratch notes file
bind N display-popup -E -T ' Notes ' 'vim ~/notes.md'

-E closes the popup when the program exits. A popup is modal: your keys go to it until it closes. tmux 3.7 added floating panes (Ctrl+b then *), which also sit above the layout but are not modal, so you can click back into other panes while one stays open. They are still an early feature and can only be moved and resized with the mouse. See display-popup and new-pane.

Hooks: run commands on events

Hooks run a tmux command automatically when something happens, such as attaching, creating a session, or splitting a window:

bash
# Greet yourself when you attach
set-hook -g client-attached 'display "Welcome back"'
 
# Rebalance panes after every split
set-hook -ga after-split-window 'select-layout -E'
 
# Run a shell script when a session is created
set-hook -g session-created 'run-shell ~/bin/on-session.sh'

Use -a to add to a hook instead of replacing it, and show-hooks -g to list what is set. Hooks run tmux commands, so wrap shell scripts in run-shell. The set-hook reference lists the common events.

Formats: tmux's template language

Anywhere tmux shows text, such as the status line, window names, and display-message, you can use formats. A format like #{session_name} is replaced with its current value, and there are hundreds of them. tmux display -a lists them all with their values.

Formats can also make decisions. #{?condition,yes,no} shows one value or the other, and #[...] changes the style. This status line shows a highlighted PREFIX label while the prefix key is pressed, then the time:

bash
set -g status-right '#{?client_prefix,#[reverse] PREFIX #[noreverse] ,}%H:%M'

In scripts, display -p is the standard way to ask tmux a question:

bash
tmux display -p '#{session_name}:#{window_index}.#{pane_index}'
tmux display -p '#{pane_current_path}'

Conditional configuration

One .tmux.conf can serve several machines. if-shell runs a shell check, and -F uses a format instead, which is faster because no shell starts:

bash
# Only on macOS: copy to the system clipboard
if-shell 'uname | grep -q Darwin' 'bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel pbcopy'
 
# Only on the machine called laptop
if-shell -F '#{==:#{host},laptop}' 'source-file ~/.tmux-laptop.conf'
 
# Load an optional per-machine file without errors if it is missing
source-file -q ~/.tmux.local.conf

tmux also supports %if blocks in config files, for example %if #{==:#{host},myhost} set -g status-style bg=red %endif.

Running tmux inside tmux

When you SSH from a tmux pane into a server that also runs tmux, both use Ctrl+b, and the outer tmux catches it first. Press Ctrl+b twice to send the prefix through to the inner tmux: Ctrl+b then Ctrl+b sends a real Ctrl+b to the program in the pane. So Ctrl+b Ctrl+b d detaches the remote session while leaving your local one alone.

Many people give the outer and inner tmux different status bar colors so it is obvious which one has focus.

Testing a config safely

tmux runs one server per socket, so you can try a new config on a separate server without touching your real sessions:

bash
tmux -L test -f ./new.tmux.conf new -s trial
# ...try it out, then:
tmux -L test kill-server

tmux source-file -n ./new.tmux.conf checks a file for syntax errors without running anything.

Pair programming & session sharing

Collaborate in real time within the same tmux session.

Basic session sharing

bash
# User A creates session
tmux new-session -s shared
 
# User B attaches (sees identical view)
tmux attach-session -t shared
 
# Both users share the cursor and see the same content

Grouped sessions (independent windows)

bash
# User A creates session
tmux new-session -s alice
 
# User B joins the same group
tmux new-session -s bob -t alice
 
# Both can switch windows independently while sharing window content

Read-only access

bash
# Observer mode (cannot type)
tmux attach-session -t shared -r
 
# Perfect for live coding demos or debugging sessions

Sharing with another user account

The examples above assume both people log in as the same user. To let a different account on the same machine join, start the server on a socket they can reach and grant access with server-access (tmux 3.3 and later):

bash
tmux -S /tmp/pair new -d -s pair
chgrp devs /tmp/pair && chmod g+rw /tmp/pair
tmux -S /tmp/pair server-access -a -r alice   # alice may watch, read-only

Alice then joins with tmux -S /tmp/pair attach -t pair. Only share with people you trust: even read-only viewers see everything on screen.