A single-keypress session picker that works with multiple terminal session managers. Press a number, you're in.
zp gives you a fast TUI for listing, creating, attaching, and killing sessions — even from inside an existing session. It doesn't care which session manager you use. Pick whichever you like:
| Backend | What it is |
|---|---|
| tmux | The standard terminal multiplexer |
| zellij | Modern terminal workspace with panes and tabs |
| zmosh | Session persistence with UDP remote support |
| zmx | Lightweight session manager (zmosh is forked from this) |
| shpool | Shell session pooling daemon |
zp auto-detects which backends you have installed. If you have more than one, it asks you to pick on first run and saves your choice.
Download a pre-built binary from GitHub Releases. Builds are available for macOS and Linux, both arm64 and amd64.
You can also use the install script:
curl -fsSL https://raw.githubusercontent.com/nerveband/zpick/main/install.sh | bashThe installer automatically adds a shell hook to your config (.zshrc, .bashrc, or fish conf.d/). The hook is required — it lets zp attach sessions in your current shell, enables autorun, and enables in-session switching. On macOS it also creates a /usr/local/bin/zp symlink for system-wide PATH access.
zp upgrade keeps the hook up to date automatically.
To remove the hook:
zp remove-hookzp upgradeDownloads the latest release binary directly. No package manager needed.
The guard is optional but useful. It wraps specific commands so that if you run them outside a session, you get a quick prompt:
⚡ Not in a tmux session. Press ENTER to pick one (10s) esc skip
Press Enter to pick a session (the original command auto-launches inside it). Or just wait 10 seconds and the command runs normally. This is handy for AI coding tools where losing your session halfway through is annoying.
To install the guard (this also installs the hook if it's missing):
zp install-guardBy default, the guard covers claude, codex, and opencode. You can change that:
zp guard --add aider # start guarding aider
zp guard --remove codex # stop guarding codex
zp guard --list # see what's guardedTo remove just the guard wrappers (keeps the shell hook):
zp remove-guardRun zp guard with no arguments for a full explanation of how it works.
Run zp inside an active session and it detects you're already in one. The header shows which session you're in (marked with ←), and picking a different session auto-detaches and reattaches — no need to remember backend-specific detach commands or shortcuts.
This works across all backends. The flow:
- You're in session
api-server, runzp - Pick
frontend(or create a new session) - zp detaches from
api-serverand attaches tofrontend
Everything is single-press. No typing session names, no confirming.
| Key | Action |
|---|---|
1-9 |
Attach to that session |
a-y |
Sessions 10 and up |
Enter |
New session named after current directory |
c |
Custom name, then pick where to create it |
z |
Pick a directory with zoxide, create session there |
d |
New session with today's date as suffix |
k |
Kill mode, pick a session to remove |
h |
Help and config screen |
Esc |
Skip, get a normal shell |
| Key | Format | Example |
|---|---|---|
Enter |
<dirname> or <dirname>-N |
api-server, then api-server-2 |
c |
whatever you type | my-thing |
d |
<dirname>-MMDD |
api-server-0220 |
z |
<picked-dir> or <picked-dir>-N |
frontend, then frontend-2 |
First session gets the bare name. The counter only appears when there's a conflict.
* (green) means someone is connected to that session. Probably you, on another device. . means idle.
By default, sessions are labeled 1-9 then a-y. If you're on a mobile keyboard where letters are the default view, switch to letters-first mode:
Press h for the help screen, then l to toggle between numbers and letters mode. The setting is saved to ~/.config/zpick/keys.
zp Interactive TUI picker (default)
zp list List sessions (--json for machine-readable)
zp check Check dependencies (--json for machine-readable)
zp attach <n> Attach or create session
zp kill <name> Kill a session
zp guard Explain session guard and show commands
zp install-hook Add shell hook to .zshrc/.bashrc/.config/fish
zp install-guard Add guard wrappers (installs hook if missing)
zp remove-hook Remove shell hook and guard wrappers
zp remove-guard Remove guard wrappers only (keeps hook)
zp upgrade Upgrade to the latest version
zp version Print version
The TUI renders to /dev/tty so it works even when stdout is piped. Only the final shell command goes to stdout, where it gets eval'd by the shell hook.
# The hook adds this to your shell config:
zp() { eval "$(command zp)"; }Selecting a session outputs something like exec tmux new-session -A -s myproject, which the eval picks up. Pressing Escape outputs nothing, so your shell just continues.
| Tool | What it adds |
|---|---|
| zoxide | Directory picker for the z key |
| fzf | Fuzzy finder, used by zoxide |
# macOS
brew install zoxide fzfzp is a Go binary that runs on:
- macOS (arm64, amd64)
- Linux (arm64, amd64)
- zsh, bash, and fish
The layout fits about 30 characters wide. No wasted space on session names. Works fine over SSH on a phone.
- zmosh - Session persistence with UDP remote support
- zmx - The session tool zmosh is forked from
- zellij - Terminal workspace with batteries included
- tmux - Terminal multiplexer
- shpool - Shell session pooling
MIT