sess — Fuzzy Tmux Session Manager in 3 Scripts
The Problem
Every developer who uses tmux hits the same wall: sessions pile up, names get forgotten, and tmux ls becomes a wall of text you scroll through while alt-tabbing between terminals.
What most people do
1
tmux new -s “work” — create a session
2
tmux new -s “kri-dev” — another one
3
tmux ls — see 12 sessions, none named intuitively
4
tmux attach -t 3 — which one was 3 again?
5
Give up, open a new terminal
The core issue: tmux gives you sessions but no good way to navigate them. tmux ls is a list, not an interface.
The Solution: 3 Scripts
A complete session management layer on top of tmux. Three files, under 150 lines total, zero config required.
sess
fzf
Session picker with preview
tm
1 cmd
Auto-name from directory
tmux.conf
Ctrl-a
Sane prefix + splits
Why fzf? It gives you fuzzy filtering, live preview, and keyboard-only navigation. Type a few letters, hit enter, you’re in. No scrolling through output.
Before & After
Before
| Commands to switch | 3–5 per switch |
|---|---|
| Session naming | Ad hoc, forgotten |
| New session | tmux new -s name -c dir |
| Session visibility | tmux ls (text dump) |
| Panes | Ctrl-b % and ” (awkward prefix) |
After
| Commands to switch | 1 (sess → pick) |
|---|---|
| Session naming | Auto from cwd |
| New session | tm (one word) |
| Session visibility | fzf with live preview |
| Panes | Ctrl-a | and Ctrl-a - |
sess — The Fuzzy Session Picker
Type sess and get an fzf interface showing all tmux sessions. Attached sessions show ●, detached show ○. Type to filter, hit enter to switch.
sess flow — animated
Key features
- Live preview — hover a session to see its last 20 lines of output
- Attached/detached indicator — ● for attached, ○ for detached
- Tab to create — press TAB to create a new session inline
- Ctrl-r to refresh — re-scans sessions without leaving fzf
- Works inside tmux — uses
display-popupas a floating window
The script
#!/usr/bin/env bash
# sess — fzf-powered tmux session picker
sessions=()
while IFS= read -r line; do
sessions+=("$line")
done < <(tmux list-sessions 2>/dev/null | sort)
# Build fzf input: ● attached / ○ detached
fzf_input=""
for s in "${sessions[@]}"; do
name=$(echo "$s" | cut -d: -f1)
windows=$(echo "$s" | grep -oP '\d+ windows?' | head -1)
attached=$(tmux list-clients -t "$name" &>/dev/null && echo "●" || echo "○")
fzf_input+="${attached} ${name} ${windows}"$'\n'
done
# Run fzf with preview
selected=$(echo "$fzf_input" | fzf \
--prompt="sess > " \
--header="● attached ○ detached [TAB] new session" \
--expect=tab \
--preview="tmux capture-pane -t {2} -p | head -20" \
--preview-window=right:50%:hidden \
--height=40% --reverse --border=rounded)
tm — One-Word Session Creation
Type tm in any directory and it creates a session named after that directory. Type tm kri to create a named session. That’s it.
Usage patterns
# In ~/Documents/git/kri — auto-names to "kri"
$ tm
Creating session: kri
# Explicit name
$ tm atlas
Creating session: atlas
# Name + start dir
$ tm monitoring /etc/prometheus
Creating session: monitoring
# Kill a session
$ tm -k old-project
Killed session 'old-project'
# List sessions (plain text)
$ tm -l
kri: 3 windows (created Thu Jul 17 10:00:00 2026)
atlas: 5 windows (created Thu Jul 17 09:30:00 2026)
The magic: tm auto-detects your current directory and uses it as the session name. cd ~/Documents/git/kri && tm creates session “kri” — no typing required.
tmux.conf — Sane Defaults
The config that makes everything work together. Ctrl-a as prefix (screen-style), visual splits, and session management bindings.
Key bindings
| Binding | Action |
|---|---|
| Ctrl-a | | Vertical split (current path) |
| Ctrl-a - | Horizontal split (current path) |
| Ctrl-a c | New window (current path) |
| Ctrl-a s | Open fzf session picker (popup) |
| Ctrl-a S | Create named session (prompt) |
| Ctrl-a K | Kill current session (confirm) |
| Ctrl-a r | Reload tmux.conf |
| Alt-arrow | Switch pane direction |
| Ctrl-a 1-5 | Quick switch to session N |
Status bar
A minimal dark bar showing the session name, current time, and hostname. Window names are compact: 1:bash format.
kri │ 1:bash 2:vim 3:lazygit 14:30 │ machine
Daily Workflow
How a typical day looks with sess + tm.
Morning startup
# SSH into your box — land in tmux automatically
$ ssh lab
$ tm # creates "lab" session
$ tm kri # creates "kri" session
# Switch between projects
$ sess # fzf picker → pick "kri"
# Inside tmux: Ctrl-a s opens the picker as a popup
# Type "av" → filters to "atlas" → Enter → switch
Project work
# cd into any project, tm auto-names it
$ cd ~/Documents/git/persona
$ tm # session "persona" created
# Inside tmux: split, work, detach
Ctrl-a | # vertical split
Ctrl-a - # horizontal split
Ctrl-a d # detach
# Later: sess → pick "persona" → resume
Cleanup
# Kill a specific session
$ tm -k old-experiment
# Kill all sessions (nuclear option)
$ tmux kill-server
Key Bindings Cheat Sheet
Shell
| sess | Fuzzy session picker |
|---|---|
| tm | Create/attach (auto-name) |
| tm name | Create/attach named |
| tm -k name | Kill session |
| tm -l | List sessions |
| tl | Alias for tmux ls |
| ta name | Alias for tmux attach |
Inside tmux
| Ctrl-a s | Fzf picker (popup) |
|---|---|
| Ctrl-a S | Create session (prompt) |
| Ctrl-a K | Kill session |
| Ctrl-a | | Vertical split |
| Ctrl-a - | Horizontal split |
| Alt-arrows | Switch pane |
| Ctrl-a r | Reload config |
Architecture
How the pieces fit together.
Component overview — animated
Install
30 seconds to set up. Copy the scripts, add one line to your shell rc.
Quick install
# 1. Clone or copy the scripts
$ git clone https://github.com/you/sess.git ~/sess
$ cd ~/sess && bash install.sh
# 2. Add to ~/.bashrc or ~/.zshrc
$ echo 'source ~/.config/tmux/sess.sh' >> ~/.bashrc
$ source ~/.bashrc
# 3. Verify
$ which sess tm
~/.local/bin/sess
~/.local/bin/tm
Prerequisites
| Tool | Required | Install |
|---|---|---|
| tmux | Yes | apt install tmux |
| fzf | Yes | apt install fzf |
| xclip/pbcopy | Optional | For clipboard integration |
Cheat Sheet
| Session Management |
|---|
| tm |
| tm name |
| sess |
| tm -l |
| tm -k name |
| Inside tmux (prefix: Ctrl-a) |
| Ctrl-a s |
| Ctrl-a S |
| Ctrl-a | |
| Ctrl-a - |
| Ctrl-a c |
| Ctrl-a d |
| Ctrl-a r |
| Alt-arrows |
| Ctrl-a 1-5 |
Enjoyed this post?
Get the next one in your inbox — only when I ship something worth reading.
Newsletter form not configured.
Or follow on Substack for the newsletter.
Comments via GitHub Discussions
Comments not configured. Set GISCUS env vars to enable.