A tmux session management tool for fast project switching. It combines fuzzy directory selection, automatic session creation, and optional per-project tmux layout hydration.
- Features
- Quick Start
- Prerequisites
- Installation
- Configuration
- Usage
- Testing
- Troubleshooting
- FAQ
- How It Works
- Contributing
- Acknowledgment
- Fast fuzzy selection for projects across one or more root directories
- Automatic tmux session creation and switching from selected directories
- Session naming that sanitizes project directory names for tmux safety
- Optional per-project
.tmux-sessionizerfiles for custom window/pane layouts - Optional shell helpers for toggling session persistence and cleanup routines
- Flexible discovery source precedence: CLI args,
SEARCH_DIRS, config file, then defaults
Common use cases:
- Jump between client repos in seconds from one picker
- Bootstrap the same pane layout whenever you open a project
- Keep temporary sessions lightweight while preserving important ones
- Launch session switching directly from i3 or tmux keybindings
If you already have tmux and fzf installed:
git clone https://github.com/kyleorman/tmux-sessionizer.git
cd tmux-sessionizer
mkdir -p ~/.config
cp examples/tmux-sessionizer.conf.simple ~/.config/tmux-sessionizer.conf
./tmux-sessionizer.shThat gives you a working setup immediately from the repo checkout. See Installation for global install options.
Required tools:
bash4.0+tmuxfzffd(preferred) orfind
Notes:
- macOS ships Bash 3.2 by default; install a newer Bash (4.0+) for full compatibility.
Optional tools/features:
zshfor.tmux-functions.zshsession lifecycle helpersshellcheckfor local linting- BATS (or the bundled downloader in
test/run-tests.sh) for test execution
Install the main script:
sudo curl -o /usr/local/bin/tmux-sessionizer.sh https://raw.githubusercontent.com/kyleorman/tmux-sessionizer/main/tmux-sessionizer.sh
sudo chmod +x /usr/local/bin/tmux-sessionizer.shInstall zsh helper functions (optional but recommended):
curl -o ~/.tmux-functions.zsh https://raw.githubusercontent.com/kyleorman/tmux-sessionizer/main/.tmux-functions.zshgit clone https://github.com/kyleorman/tmux-sessionizer.git
cd tmux-sessionizer
chmod +x tmux-sessionizer.sh
./tmux-sessionizer.shCreate ~/.config/tmux-sessionizer.conf to define search roots (one directory per line):
$HOME
$HOME/projects
$HOME/work
# Lines beginning with # are ignoredYou can also use SEARCH_DIRS (colon-separated):
export SEARCH_DIRS="$HOME:$HOME/projects:$HOME/work"Precedence order:
- Command-line directory arguments
SEARCH_DIRSenvironment variable~/.config/tmux-sessionizer.conf- Built-in default directories
tmux-sessionizer.sh supports runtime overrides via environment variables.
By default, fzf height is automatically determined:
- Inside tmux: 40% height (compact popup style)
- Outside tmux: 100% height (full terminal, ideal for WM hotkeys)
Override with:
export TMUX_SESSIONIZER_FZF_HEIGHT="50%"Create .tmux-sessionizer inside a project directory to apply tmux commands when a new session is created for that project.
Example:
rename-window -t 0 editor
split-window -h -t 0 -c "#{pane_current_path}"
new-window -n tools -c "#{pane_current_path}"You can start with the provided template:
cp examples/.tmux-sessionizer.example /path/to/project/.tmux-sessionizerAdd to ~/.zshrc:
source ~/.tmux-functions.zsh
# Start a generated tmux session when launching an interactive shell outside tmux
if [[ $- == *i* ]]; then
if command -v tmux >/dev/null 2>&1 && [[ -z "${TMUX:-}" ]]; then
SESSION_NAME="session-$(date +%s)"
tmux new-session -As "$SESSION_NAME"
tmux set-option -t "$SESSION_NAME" @persistent 0
fi
fi
cleanup_old_sessionsAdd keybindings to your ~/.tmux.conf (or copy from examples/tmux.conf.snippet):
bind-key C-f run-shell "/usr/local/bin/tmux-sessionizer.sh"
bind-key m run-shell "~/.tmux-functions.zsh toggle"
bind-key R run-shell "~/.tmux-functions.zsh rename"
bind-key Q run-shell "~/.tmux-functions.zsh force-cleanup"Add this to your i3 config (also in examples/i3-config-snippet) for fullscreen picker behavior:
bindsym $mod+backslash exec --no-startup-id "alacritty --class tmux-sessionizer -e zsh -lc 'tmux-sessionizer.sh; exec zsh'"
for_window [class="tmux-sessionizer"] fullscreen enableCopy-paste-ready examples are available in examples/:
examples/tmux-sessionizer.conf.simpleexamples/tmux-sessionizer.conf.advancedexamples/.tmux-sessionizer.exampleexamples/i3-config-snippetexamples/wm-hotkeys-guide.mdexamples/tmux.conf.snippet
Launch with configured search roots:
tmux-sessionizer.shOr pass directories directly for one-off sessions:
tmux-sessionizer.sh "$HOME/projects" "$HOME/work"Workflow:
- Run
tmux-sessionizer.sh. - Select a directory in the
fzfpicker. - The script creates a session when needed and switches/attaches to it.
- Toggle persistence:
prefix + m - Rename generated session:
prefix + R - Force cleanup non-persistent generated sessions:
prefix + Q
- Temporary sessions can be generated from shell startup logic
- Generated sessions can be marked persistent with
@persistent - Inactive temporary sessions can be cleaned up automatically
- Per-project
.tmux-sessionizerconfig is loaded when creating a new session
From the project root:
./test/run-tests.shRun only unit tests:
./test/run-tests.sh tests/unit/Run only integration tests:
./test/run-tests.sh tests/integration/Run a specific test file:
./test/run-tests.sh tests/unit/test_functions.batstest/run-tests.shchecks for systembatsfirst.- If missing, it downloads
bats-coreintotest/tmp/bats/. - It also downloads
bats-supportandbats-assertwhen missing. - First run may require network access.
- Put shared helpers in
tests/test_helper/common.bash. - Add unit tests in
tests/unit/. - Add integration tests in
tests/integration/. - In BATS files, load shared helpers:
load '../test_helper/common.bash'- Use
setup_mock_environmentandteardown_mock_environmentfor isolated tests.
- Use
./test/run-tests.shin CI for consistent local/CI behavior. - Cache
test/tmp/bats/between runs to avoid repeated downloads. - Combine tests with lint checks:
shellcheck tmux-sessionizer.sh
shellcheck -s bash .tmux-functions.zsh
shellcheck test/run-tests.shInstall tmux and confirm it is on PATH:
command -v tmux- Check
~/.config/tmux-sessionizer.conffor valid existing paths. - Verify
SEARCH_DIRSuses:separators. - Try explicit directories:
tmux-sessionizer.sh "$HOME"- Confirm configured roots actually contain subdirectories.
- Check permissions on configured roots.
- If using
fd, verify it is returning expected directories.
- Confirm file is named exactly
.tmux-sessionizerin project root. - Verify tmux commands in that file are valid.
- Test manually:
tmux source-file /path/to/project/.tmux-sessionizer- Confirm
~/.tmux-functions.zshexists and is executable by your shell. - Reload tmux config after changes:
tmux source-file ~/.tmux.confNo. The main script is Bash. zsh is only needed for the optional helper file .tmux-functions.zsh.
Priority is: CLI directory args > SEARCH_DIRS > ~/.config/tmux-sessionizer.conf > built-in defaults.
Yes, with tmux/fzf installed. If your environment defaults to Bash 3.2, use a newer Bash for full compatibility.
The script exits cleanly without switching sessions.
Use the examples/ directory in this repository for configuration and integration snippets.
- Directory discovery:
- Reads search roots from args/env/config/defaults
- Uses
fdwhen available, falls back tofind - Aggregates and de-duplicates root directories plus first-level children
- Selection and session naming:
- Uses
fzffor interactive selection (or auto-selects when only one option exists) - Converts selected directory basename to a tmux-safe session name
- Uses
- Session handling:
- Creates session if missing, then switches or attaches
- Loads project-level or home-level
.tmux-sessionizerfile when present
See CONTRIBUTING.md for setup, workflow, testing expectations, and submission guidelines.
This script and setup was inspired by ThePrimeagen's tmux-sessionizer workflow.