tmux Tutorial 2026: From Zero to Productive with Sessions, Config, and Neovim Integration
If you have ever lost hours of work because an SSH connection dropped mid-deployment, or juggled a dozen terminal tabs trying to manage a project, tmux is the tool that will change how you work. This tutorial takes you from a fresh installation all the way to a fully configured tmux environment with a dev-session startup script, SSH persistence, Neovim integration, and plugin management — everything you need to make tmux genuinely productive in 2026.
The Problem tmux Solves
When you SSH into a remote server and start a long-running process — a database migration, a compilation job, a test suite — your work lives inside a shell process attached to your SSH connection. The moment that connection drops due to a network hiccup, a laptop lid closing, or a VPN timeout, the shell receives a SIGHUP signal and every process inside it is killed. Your work is gone.
tmux (Terminal MUltipleXer) solves this by running a server process on the remote (or local) machine that owns all your shells. Your terminal connects to that server as a client. When the client disconnects, the server keeps running. You reconnect and pick up exactly where you left off — running processes, command history, split panes, and all.
Beyond persistence, tmux gives you:
- Multiple sessions on a single machine, each completely independent
- Windows (like browser tabs) within each session
- Panes (splits) within each window, so you can see your editor, a running server, and a test runner simultaneously
- A scriptable, configurable environment you can automate at project startup
Installation
Ubuntu / Debian
sudo apt update && sudo apt install -y tmux
macOS with Homebrew
brew install tmux
Verify the installation
tmux -V
# tmux 3.4 (or newer)
This tutorial targets tmux 3.2 and above. Features like true color and improved copy mode work best on recent versions.
Core Concept: Sessions > Windows > Panes
Before touching the keyboard, understand the three-level hierarchy:
Session "myproject"
├── Window 0: "editor"
│ ├── Pane 0 (neovim)
│ └── Pane 1 (terminal)
├── Window 1: "server"
│ └── Pane 0 (dev server logs)
└── Window 2: "tests"
└── Pane 0 (test runner)
- Session: the outermost container. Detaching from a session leaves it running on the server. You can have many sessions — one per project.
- Window: a full-screen view inside a session, like a browser tab. You switch between them instantly.
- Pane: a rectangular region inside a window, created by splitting it horizontally or vertically. All panes in a window are visible at the same time.
The Prefix Key
Every tmux keybinding starts with a prefix — a key combination you press first to tell tmux "the next key is a command for you, not the shell." The default prefix is Ctrl+b.
Press Ctrl+b then release, then press a command key. For example:
Ctrl+b ?— show all keybindings (pressqto quit)Ctrl+b d— detach from the current session
Why change it to Ctrl+a: Ctrl+b requires an awkward hand position and conflicts with the common shell shortcut for moving back one character in readline. Ctrl+a (the default prefix in GNU Screen, which tmux replaced for many users) is far more ergonomic. The configuration section below makes this change.
Starting tmux
# Start a new unnamed session
tmux
# Start a new session with a name
tmux new-session -s myproject
# or shorter:
tmux new -s myproject
You are now inside tmux. Notice the status bar at the bottom showing the session name, open windows, and system info.
Sessions: The Persistence Layer
Sessions are the most important concept for SSH workflows. Think of them as workspaces that outlive your connection.
| Action | Command |
|---|---|
| New session (outside tmux) | tmux new -s name |
| New session (inside tmux) | Prefix :new-session -s name |
| Detach from session | Prefix d |
| List sessions (outside) | tmux ls |
| List sessions (inside) | Prefix s |
| Attach to session | tmux attach -t name or tmux a -t name |
| Attach to last session | tmux a |
| Kill a session | tmux kill-session -t name |
| Kill current session | Prefix :kill-session |
The critical workflow for SSH is:
# On your remote server, always start work with:
tmux new -A -s main
# -A means: attach if session 'main' exists, create it if not
Now your work persists through disconnects. After reconnecting to the server, just run tmux a -t main to get back to everything exactly as you left it.
Windows: Tabs Inside a Session
Windows are like browser tabs. Each has a name and a number, shown in the status bar.
| Action | Keybinding |
|---|---|
| New window | Prefix c |
| Next window | Prefix n |
| Previous window | Prefix p |
| Go to window by number | Prefix 0-9 |
| Rename current window | Prefix , |
| List windows | Prefix w |
| Kill current window | Prefix & |
Naming your windows is worth the habit — editor, server, db, git are far more useful than 0, 1, 2, 3 when you are switching quickly.
Panes: Splits Inside a Window
Panes let you see multiple terminals simultaneously inside one window.
| Action | Keybinding (default) |
|---|---|
| Split vertically (side by side) | Prefix % |
| Split horizontally (top/bottom) | Prefix " |
| Navigate to pane (direction) | Prefix Arrow |
| Zoom/unzoom pane (full screen) | Prefix z |
| Kill current pane | Prefix x |
| Show pane numbers | Prefix q |
| Resize pane | Prefix Ctrl+Arrow |
| Convert pane to window | Prefix ! |
| Swap pane | Prefix { / Prefix } |
The zoom feature (Prefix z) is extremely useful: it temporarily expands one pane to fill the entire window. Press it again to restore the split layout. Great for reading logs or writing code without losing your layout.
Full Annotated ~/.tmux.conf
This is the configuration file that makes tmux genuinely pleasant to use. Create or replace ~/.tmux.conf with the following. Each section is explained inline.
# ============================================================
# ~/.tmux.conf — production-ready tmux configuration 2026
# ============================================================
# ------------------------------------------------------------
# PREFIX KEY
# Change from Ctrl+b to Ctrl+a (screen-style, more ergonomic)
# ------------------------------------------------------------
unbind C-b
set -g prefix C-a
bind C-a send-prefix # Ctrl+a Ctrl+a sends a literal Ctrl+a to the shell
# ------------------------------------------------------------
# GENERAL SETTINGS
# ------------------------------------------------------------
set -g mouse on # Enable mouse: click panes, resize splits, scroll
set -g base-index 1 # Start window numbering at 1 (easier keyboard reach)
setw -g pane-base-index 1 # Start pane numbering at 1
set -g renumber-windows on # Re-number windows when one is closed (no gaps)
set -g history-limit 50000 # Keep 50,000 lines of scrollback per pane
set -g display-time 4000 # Show tmux messages for 4 seconds
set -g status-interval 5 # Refresh status bar every 5 seconds
set -sg escape-time 0 # No delay for escape key (critical for neovim)
set -g focus-events on # Pass focus events to applications (neovim uses this)
# ------------------------------------------------------------
# TRUE COLOR (required for neovim themes to render correctly)
# ------------------------------------------------------------
set -g default-terminal "tmux-256color"
set -ag terminal-overrides ",xterm-256color:RGB"
# ------------------------------------------------------------
# INTUITIVE SPLIT KEYBINDINGS (open in current directory)
# ------------------------------------------------------------
unbind '"'
unbind %
bind | split-window -h -c "#{pane_current_path}" # Prefix | → vertical split
bind - split-window -v -c "#{pane_current_path}" # Prefix - → horizontal split
bind c new-window -c "#{pane_current_path}" # Prefix c → new window in same dir
# ------------------------------------------------------------
# VIM-STYLE PANE NAVIGATION
# h/j/k/l move between panes (matches vim-tmux-navigator)
# ------------------------------------------------------------
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# Pane resize with capital H/J/K/L, 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
# ------------------------------------------------------------
# COPY MODE (vi-style)
# ------------------------------------------------------------
setw -g mode-keys vi # vi keybindings in copy mode
bind Enter copy-mode # Prefix Enter → enter copy mode
bind -T copy-mode-vi v send -X begin-selection
bind -T copy-mode-vi y send -X copy-pipe-and-cancel "xclip -selection clipboard -in 2>/dev/null || pbcopy"
bind -T copy-mode-vi Escape send -X cancel
bind -T copy-mode-vi H send -X start-of-line
bind -T copy-mode-vi L send -X end-of-line
# ------------------------------------------------------------
# RELOAD CONFIG
# ------------------------------------------------------------
bind r source-file ~/.tmux.conf \; display "tmux.conf reloaded"
# ------------------------------------------------------------
# STATUS BAR
# ------------------------------------------------------------
set -g status-position bottom
set -g status-style "bg=#1e1e2e,fg=#cdd6f4" # Catppuccin-inspired
set -g status-left-length 40
set -g status-right-length 80
set -g status-left "#[fg=#89b4fa,bold] #S #[fg=#cdd6f4]│ "
set -g status-right "#[fg=#a6e3a1] %Y-%m-%d #[fg=#cdd6f4]│#[fg=#89b4fa] %H:%M #[fg=#cdd6f4]│#[fg=#f38ba8] #h "
setw -g window-status-format " #I:#W "
setw -g window-status-current-format "#[fg=#1e1e2e,bg=#89b4fa,bold] #I:#W "
setw -g window-status-separator ""
# Active/inactive pane border colors
set -g pane-border-style "fg=#45475a"
set -g pane-active-border-style "fg=#89b4fa"
# ------------------------------------------------------------
# PLUGINS (tpm — tmux Plugin Manager)
# Install tpm first: see the Plugins section of this tutorial
# ------------------------------------------------------------
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @plugin 'tmux-plugins/tmux-yank'
set -g @plugin 'christoomey/vim-tmux-navigator'
# tmux-resurrect: restore neovim sessions too
set -g @resurrect-strategy-nvim 'session'
set -g @resurrect-capture-pane-contents 'on'
# tmux-continuum: auto-save every 15 minutes, auto-restore on tmux start
set -g @continuum-restore 'on'
set -g @continuum-save-interval '15'
# Initialize tpm (MUST be the last line)
run '~/.tmux/plugins/tpm/tpm'
After saving, reload the config from inside tmux:
# Inside tmux:
Prefix r
# Or from the shell:
tmux source-file ~/.tmux.conf
Copy Mode: Scroll, Search, and Clipboard
Copy mode lets you scroll back through pane history, search text, and copy output — all without leaving tmux.
Prefix Enter → Enter copy mode
q → Exit copy mode
Arrow keys / hjkl → Move cursor
Ctrl+u / Ctrl+d → Scroll half page up/down
Ctrl+b / Ctrl+f → Scroll full page up/down
g → Go to top of history
G → Go to bottom
/pattern → Search forward
?pattern → Search backward
n / N → Next/previous search match
v → Begin selection
y → Copy selection and exit
Copying to the system clipboard
The config above uses xclip on Linux and pbcopy on macOS via a shell pipe. Ensure the right tool is installed:
# Ubuntu/Debian
sudo apt install -y xclip
# macOS — pbcopy is built-in, nothing to install
With tmux-yank installed (covered in the Plugins section), clipboard integration becomes automatic and cross-platform.
Dev Session Startup Script
One of the highest-value uses of tmux is scripting your project environment so you can go from zero to a fully running dev stack with a single command. The script below creates a named session with four pre-configured windows or reattaches to it if it already exists.
Save this as ~/bin/dev-session and make it executable:
#!/usr/bin/env bash
# dev-session — create or reattach to a project tmux session
# Usage: dev-session [session-name] [project-dir]
SESSION="${1:-dev}"
PROJECT_DIR="${2:-$HOME/projects/$SESSION}"
# If the session already exists, just attach to it
if tmux has-session -t "$SESSION" 2>/dev/null; then
echo "Session '$SESSION' already exists. Attaching..."
tmux attach-session -t "$SESSION"
exit 0
fi
# Create the session detached so we can set it up before attaching
tmux new-session -d -s "$SESSION" -n "editor" -c "$PROJECT_DIR"
# Window 1: editor — start neovim
tmux send-keys -t "$SESSION:editor" "nvim ." Enter
# Window 2: server — run the dev server
tmux new-window -t "$SESSION" -n "server" -c "$PROJECT_DIR"
tmux send-keys -t "$SESSION:server" "# Start your dev server here, e.g.: npm run dev" ""
# Window 3: tests — test runner in watch mode
tmux new-window -t "$SESSION" -n "tests" -c "$PROJECT_DIR"
tmux send-keys -t "$SESSION:tests" "# Run tests here, e.g.: pytest -x --tb=short" ""
# Window 4: git — version control and misc shell work
tmux new-window -t "$SESSION" -n "git" -c "$PROJECT_DIR"
tmux send-keys -t "$SESSION:git" "git status" Enter
# Split the git window: left for git, right for a general shell
tmux split-window -h -t "$SESSION:git" -c "$PROJECT_DIR"
# Focus the editor window on attach
tmux select-window -t "$SESSION:editor"
# Attach
tmux attach-session -t "$SESSION"
chmod +x ~/bin/dev-session
# Start a Django project session:
dev-session myapp ~/projects/myapp
# Start a Node.js session:
dev-session webapp ~/projects/webapp
When you detach and reconnect later, the same dev-session myapp command reattaches instead of creating a duplicate — the tmux has-session check handles that.
SSH Persistence
The real power of tmux becomes clear for remote work. Here are two patterns:
Ad-hoc: one command to connect and always be in tmux
ssh user@myserver -t "tmux new -A -s main"
The -t flag forces a pseudo-terminal (required for interactive programs). new -A -s main creates a session named main if it does not exist, or attaches to it if it does. This is the safest single-command remote tmux workflow.
Automatic: SSH config RemoteCommand
Add this to ~/.ssh/config on your local machine to make tmux the default shell whenever you SSH to a host:
Host myserver
HostName myserver.example.com
User ubuntu
IdentityFile ~/.ssh/id_ed25519
RequestTTY yes
RemoteCommand tmux new -A -s main
Now ssh myserver automatically lands you in a persistent tmux session. If you have tmux-continuum installed on the server (see Plugins below), your session is also saved and restored automatically across server reboots.
Handling nested tmux (local inside remote)
If you run tmux locally and also connect to a remote tmux, you end up with nested sessions. To send a command to the inner tmux, press your prefix twice:
Ctrl+a Ctrl+a d → detach from the remote (inner) session
Neovim Integration: vim-tmux-navigator
The biggest friction point when using Neovim inside tmux is navigating between Neovim splits and tmux panes. Without integration, you need separate keybindings for each: Ctrl+w h inside Neovim, Prefix h inside tmux. With vim-tmux-navigator, a single set of keybindings — Ctrl+h, Ctrl+j, Ctrl+k, Ctrl+l — works seamlessly regardless of whether the adjacent split is a Neovim buffer or a tmux pane.
Step 1: Install the tmux side (via tpm)
The vim-tmux-navigator plugin is already included in the ~/.tmux.conf above:
set -g @plugin 'christoomey/vim-tmux-navigator'
After adding it, install plugins with Prefix I (capital I).
Step 2: Install the Neovim side
With lazy.nvim (the most common Neovim plugin manager in 2026):
-- In your lazy.nvim plugin spec:
{
"christoomey/vim-tmux-navigator",
cmd = {
"TmuxNavigateLeft", "TmuxNavigateDown",
"TmuxNavigateUp", "TmuxNavigateRight",
},
keys = {
{ "<c-h>", "<cmd>TmuxNavigateLeft<cr>" },
{ "<c-j>", "<cmd>TmuxNavigateDown<cr>" },
{ "<c-k>", "<cmd>TmuxNavigateUp<cr>" },
{ "<c-l>", "<cmd>TmuxNavigateRight<cr>" },
},
},
With vim-plug:
Plug 'christoomey/vim-tmux-navigator'
Then add keybindings to your init.vim:
nnoremap <silent> <C-h> :TmuxNavigateLeft<CR>
nnoremap <silent> <C-j> :TmuxNavigateDown<CR>
nnoremap <silent> <C-k> :TmuxNavigateUp<CR>
nnoremap <silent> <C-l> :TmuxNavigateRight<CR>
How it works
When you press Ctrl+h inside Neovim, the plugin checks whether there is a Neovim split to the left. If yes, it moves to that split. If no, it sends the move command to tmux, which moves focus to the tmux pane to the left. The result is a completely seamless experience — you stop thinking about whether you are crossing a Neovim split or a tmux pane boundary.
True color prerequisite
The ~/.tmux.conf above already sets the correct terminal overrides for true color. Inside Neovim, ensure your init.lua or init.vim has:
vim.opt.termguicolors = true
Without this, colorschemes will look wrong inside tmux even if they look correct in a plain terminal.
Plugin Management with tpm
tpm (tmux Plugin Manager) brings a one-line plugin system to tmux, similar to lazy.nvim for Neovim or apt for packages.
Install tpm
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
Then reload tmux (Prefix r or tmux source ~/.tmux.conf).
tpm keybindings (inside tmux)
| Action | Keybinding |
|---|---|
| Install new plugins | Prefix I |
| Update plugins | Prefix U |
| Remove unused plugins | Prefix Alt+u |
Recommended plugins
tmux-sensible (tmux-plugins/tmux-sensible) Sets a collection of sensible defaults that most users agree on: longer history, faster escape times, UTF-8 support. Think of it as the tmux equivalent of vim-sensible.
tmux-resurrect (tmux-plugins/tmux-resurrect) Saves your entire tmux environment — sessions, windows, panes, working directories, and running commands — to disk, and restores it on demand. After a reboot, instead of manually recreating your workspace:
Prefix Ctrl+s → Save session to disk
Prefix Ctrl+r → Restore session from disk
Configure it to also restore Neovim sessions (already in the config above):
set -g @resurrect-strategy-nvim 'session'
tmux-continuum (tmux-plugins/tmux-continuum) Builds on tmux-resurrect to automatically save every 15 minutes and automatically restore when tmux starts. Set-and-forget session persistence. Configuration is already in the .tmux.conf above.
tmux-yank (tmux-plugins/tmux-yank) Provides robust clipboard integration across macOS, Linux (X11 and Wayland), and WSL. After installing, y in copy mode copies to the system clipboard without any additional shell pipe configuration.
Essential Cheatsheet
Sessions
| Action | Command |
|---|---|
| New named session | tmux new -s name |
| List sessions | tmux ls / Prefix s |
| Attach to session | tmux a -t name |
| Detach | Prefix d |
| Kill session | tmux kill-session -t name |
Windows
| Action | Keybinding |
|---|---|
| New window | Prefix c |
| Next window | Prefix n |
| Previous window | Prefix p |
| Go to window N | Prefix N |
| Rename window | Prefix , |
| Kill window | Prefix & |
Panes
| Action | Keybinding (with this config) |
|---|---|
| Split vertical | Prefix \| |
| Split horizontal | Prefix - |
| Navigate (vim-style) | Prefix h/j/k/l |
| Zoom/unzoom | Prefix z |
| Kill pane | Prefix x |
| Resize | Prefix H/J/K/L |
| Show numbers | Prefix q |
Copy mode
| Action | Key |
|---|---|
| Enter copy mode | Prefix Enter |
| Begin selection | v |
| Copy and exit | y |
| Search forward | /pattern |
| Next match | n |
| Exit | q |
Plugins (tpm)
| Action | Keybinding |
|---|---|
| Install plugins | Prefix I |
| Update plugins | Prefix U |
| Save session (resurrect) | Prefix Ctrl+s |
| Restore session (resurrect) | Prefix Ctrl+r |
Putting It All Together
Here is the complete daily workflow once everything is configured:
- Start work —
dev-session myproject ~/projects/myprojectcreates your full environment (or reattaches to it). - Edit code — Neovim opens in the
editorwindow. Navigate between Neovim splits and tmux panes withCtrl+h/j/k/l. - Run servers — Switch to the
serverwindow (Prefix 2) and start your dev server. Switch back instantly (Prefix 1). - Watch tests —
Prefix 3takes you to the test runner without losing focus on your editor. - Check git —
Prefix 4for version control work. - Detach —
Prefix d. Your entire environment keeps running. - Return —
dev-session myprojectreattaches in under a second, everything exactly as you left it. - Survive reboots — tmux-continuum saved your session.
Prefix Ctrl+rrestores it after the machine comes back.
Further Reading
- tmux wiki — github.com/tmux/tmux/wiki — authoritative documentation and changelog
- man tmux —
man tmux— the complete reference, always available offline - The Tao of tmux by Tony Narlock — free online at leanpub.com/the-tao-of-tmux — the most thorough prose guide to tmux
- Ham Vocke's tmux guide — hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/ — the classic introductory post that got many developers started
- vim-tmux-navigator — github.com/christoomey/vim-tmux-navigator — plugin source and detailed configuration options
- tpm — github.com/tmux-plugins/tpm — plugin manager installation and usage