Browse referenceAdvanced Features
Advanced Features
Unlock tmux's full potential with advanced workflows, integrations, and automation — building on the basics from the configuration guide.
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:
set -g mouse onWith 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+bthen]. - 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:
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).
# 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-panesSynchronization 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:
# 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:
#!/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"
fiA few details make scripts like this reliable:
has-session -t "=api"uses=so it matches the name exactly, not a session calledapi-old.-t "api:"with an empty window part means the next free window index in that session.send-keysneedsEnterat the end, or the command is typed but never run.- The final check uses
switch-clientinside tmux, becauseattachthere 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:
# 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:
# 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:
set -g status-right '#{?client_prefix,#[reverse] PREFIX #[noreverse] ,}%H:%M'In scripts, display -p is the standard way to ask tmux a question:
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:
# 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.conftmux 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:
tmux -L test -f ./new.tmux.conf new -s trial
# ...try it out, then:
tmux -L test kill-servertmux 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
# 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 contentGrouped sessions (independent windows)
# 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 contentRead-only access
# Observer mode (cannot type)
tmux attach-session -t shared -r
# Perfect for live coding demos or debugging sessionsSharing 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):
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-onlyAlice then joins with tmux -S /tmp/pair attach -t pair. Only share with people you trust: even
read-only viewers see everything on screen.