Tmux Masterclass: Setting Up a Professional Terminal Workflow on macOS

Author: Muntai

Tmux Masterclass: Setting Up a Professional Terminal Workflow on macOS

Tmux: The Terminal Multiplexer You Can't Imagine Development Without (Apple Guide)

When you're working on complex Fullstack projects with Next.js and Django, your terminal is your flight control center. You need to simultaneously see server logs, running Docker containers, an open Neovim, and a database console.

Opening a dozen different terminal emulator windows is chaos and a pain when rebooting your system. The solution? Tmux.

Why do you need tmux and what is the profit?

Tmux (Terminal Multiplexer) is a program that allows you to create multiple tabs (windows) and split them into panes within a single terminal window.

But its main profit and "killer feature" is sessions. Imagine: you are working, your screen is split into 4 panes, pnpm dev is running, lazydocker is open, and you are connected via SSH to a VPS. Suddenly, you accidentally close your terminal (Ghostty or iTerm). Your reaction without tmux: panic, you have to launch everything all over again. Your reaction with tmux: you open the terminal, type tmux attach — and you see your entire workspace in the exact state you left it, right down to the cursor.

Step 1: Basic Installation

Tmux is easily installed via Homebrew:

Bash

brew install tmux

To comfortably work with plugins (for example, for a nice theme or auto-saving sessions), let's immediately install the official plugin manager (TPM):

Bash

git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

Step 2: The Perfect .tmux.conf Config

Out of the box, Tmux looks intimidating, and its default prefix (the key combination that starts all commands) is Ctrl+b. We are going to fix this.

Create a ~/.tmux.conf file and copy my config into it. It's tailored for speed, uses the Ctrl+a prefix (like pro developers do), supports the mouse, and is visually styled with the gorgeous Catppuccin theme.

Фрагмент коду

# =========================================================
# TERMINAL (BASIC TERMINAL SETTINGS)
# =========================================================

# Set 256-color support. Critically important for themes (e.g., Catppuccin).
set -g default-terminal "screen-256color"
# Enable True Color (RGB) support. Without this, Neovim might distort colors.
set -as terminal-features ',xterm-256color:RGB'

# Remove the delay when pressing ESC. Makes exiting insert mode in Vim instant.
set -s escape-time 0
# Allows apps inside tmux (Neovim) to know when the window gains or loses focus.
set -g focus-events on
# Increase history limit to 100,000 lines. Handy for Docker or pnpm logs.
set -g history-limit 100000
# tmux will adjust the window size to the active client.
set -g aggressive-resize on
# Allow sending text directly to the macOS system clipboard (pbcopy).
set -g set-clipboard on

# =========================================================
# PREFIX (MAIN PREFIX)
# =========================================================

# Change the default Ctrl+b prefix to Ctrl+a (faster and more ergonomic).
set -g prefix C-a
unbind C-b
bind C-a send-prefix

# =========================================================
# INDEXES & WINDOWS (INDEXING AND WINDOWS)
# =========================================================

# Start numbering windows and panes from 1, not 0.
set -g base-index 1
setw -g pane-base-index 1
# Automatically renumber windows if one is closed.
set -g renumber-windows on

# =========================================================
# UI / MOUSE (INTERFACE AND MOUSE)
# =========================================================

# Enable mouse support (allows text selection, resizing panes, scrolling).
set -g mouse on

# 's' to open the session list (opens a fullscreen tree and sorts alphabetically).
bind s choose-tree -sZ -O name

# =========================================================
# WINDOW MANAGEMENT
# =========================================================

# Open new windows in the current project directory (instead of ~).
bind c new-window -c "#{pane_current_path}"

# Quick window (tab) movement left and right (Shift + Arrows).
bind -n S-Left swap-window -t -1 \; previous-window
bind -n S-Right swap-window -t +1 \; next-window

# Detach and attach panes (Join / Break Pane).
bind j choose-window 'join-pane -h -s "%%"'
bind J break-pane -d

# =========================================================
# SPLITS (SCREEN / PANE SPLITTING)
# =========================================================

unbind %
unbind '"'

# Vertical split ('|'). Opens in the current directory.
bind | split-window -h -c "#{pane_current_path}"
# Horizontal split ('-'). Opens in the current directory.
bind - split-window -v -c "#{pane_current_path}"

# =========================================================
# RESIZE (RESIZING PANES)
# =========================================================

# Resize panes using Vim keys (h, j, k, l).
bind -r h resize-pane -L 5  # Expand left
bind -r j resize-pane -D 5  # Expand down
bind -r k resize-pane -U 5  # Expand up
bind -r l resize-pane -R 5  # Expand right

# 'm' key to maximize the current pane (Zoom).
bind -r m resize-pane -Z
# Quick jump to the previously active window (Alt-Tab equivalent).
bind Tab last-window

# =========================================================
# RELOAD CONFIG
# =========================================================

# 'r' to reload the config on the fly.
unbind r
bind r source-file ~/.tmux.conf \; display-message "tmux.conf reloaded!"

# =========================================================
# COPY MODE (VIM-STYLE COPY MODE)
# =========================================================

# Enable Vim-style navigation in copy mode.
setw -g mode-keys vi
bind-key -T copy-mode-vi v send -X begin-selection
bind-key -T copy-mode-vi y send -X copy-selection-and-cancel \; display-message "Copied"
# Disable clearing selection when releasing the mouse button.
unbind -T copy-mode-vi MouseDragEnd1Pane

# =========================================================
# 🔥 PRO WORKFLOW BINDINGS
# =========================================================

# Quick creation of a new session.
bind C-c command-prompt -p "New session name:" "new-session -A -s '%%'"

# Quick lazygit launch in a popup window (center of the screen).
bind g display-popup -E -w 90% -h 90% -d "#{pane_current_path}" "lazygit"

# Resource monitoring (btop).
bind H new-window -n "📊 System" "btop"

# Smart SSH connection to servers.
bind S command-prompt -p "SSH Host (e.g., user@ip):" "new-window -n '🌐 %1' 'ssh %1'"

# Floating Scratchpad (Quick console).
bind Space display-popup -E -w 80% -h 80% -d "#{pane_current_path}" "$SHELL"

# Sync panes ("Broadcast" mode).
bind * set-window-option synchronize-panes \; display-message "Sync: #{?pane_synchronized,ON,OFF}"

# =========================================================
# TPM PLUGINS (MANAGER AND PLUGINS)
# =========================================================

set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'christoomey/vim-tmux-navigator'

# Catppuccin Theme
set -g @plugin 'catppuccin/tmux'
set -g @catppuccin_flavor 'mocha'

# Session saving
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @continuum-restore 'on'
set -g @resurrect-capture-pane-contents 'on'
set -g @resurrect-save-file '~/.tmux/resurrect'

# Utilities
set -g @plugin 'omerxx/tmux-sessionx'
set -g @sessionx-bind 'O'
set -g @plugin 'tmux-plugins/tmux-yank'
set -g @plugin 'laktak/extrakto'
set -g @plugin 'tmux-plugins/tmux-prefix-highlight'
set -g @plugin 'sainnhe/tmux-fzf'
set -g @plugin 'fcsonline/tmux-thumbs'
set -g @plugin 'tmux-plugins/tmux-open'
set -g @plugin 'tmux-plugins/tmux-battery'
set -g @plugin 'tmux-plugins/tmux-cpu'
set -g @plugin 'joshmedeski/tmux-which-key'

# TPM Initialization
run '~/.tmux/plugins/tpm/tpm'

# =========================================================
# CATPPUCCIN STATUS BAR OVERRIDE (CUSTOMIZATION)
# =========================================================

set -g status on
set -g status-interval 5
set -g status-position bottom
set -g status-justify left
set -g status-right-length 100
set -g status-left-length 100
set -g status-left ""

set -g pane-active-border-style fg=green
set -g pane-border-style fg=colour238

set -g status-right "#{E:@catppuccin_status_application}"
set -agF status-right "#{E:@catppuccin_status_cpu}"
set -agF status-right "#{E:@catppuccin_status_ram}"
set -ag status-right "#{E:@catppuccin_status_session}"
set -ag status-right "#{E:@catppuccin_status_uptime}"
set -agF status-right "#{E:@catppuccin_status_battery}"

run ~/.tmux/plugins/tmux-cpu/cpu.tmux
run ~/.tmux/plugins/tmux-battery/battery.tmux

Step 3: Installing Plugins (The magic of prefix + I)

After saving the config, open tmux (type tmux in the terminal). Then press our prefix Ctrl+a, release it, and press a capital I (Shift+i). This will launch TPM, which will download all the plugins from the list.

Step 4: The Apple M1 Nuance (Compiling from source)

The Darwin_arm64 architecture of Apple Silicon chips sometimes plays cruel jokes with certain plugins. For example, the tmux-thumbs plugin (written in Rust for fast copying) often fails to pull the correct binary for the M1.

If you see an error installing the binary for tmux-thumbs during plugin loading, you'll have to compile it yourself. It's very simple to do. Go to the plugin folder and run the build script:

Bash

cd ~/.tmux/plugins/tmux-thumbs
cargo build --release

(For this, Rust must be installed on your system: brew install rust).

After that, everything will work perfectly.

Summary

You've gained an incredibly powerful tool. Try pressing Ctrl+a and then Space — and a quick floating Scratchpad will appear in front of you. Press Ctrl+a and g — the lazygit menu flies out. And after rebooting your Mac, your tmux sessions will resurrect themselves thanks to tmux-resurrect.

This is what true productivity at your fingertips looks like.

Write to me
Please fill out the form below to start a conversation with me.

This site is protected by reCAPTCHA. The Google Privacy Policy and Terms of Service apply.