What Is tsm?
tsm is a terminal session manager built by adibhanna, designed for developers who need persistent shell sessions without tmux's window/pane complexity. tsm runs one daemon per session with a dedicated PTY, supports detach/reattach from any terminal, and integrates native splits via tsm mux backends like cmux, kitty, Ghostty, and WezTerm. With 90 GitHub stars as of October 2024, tsm is one of the best Terminal Multiplexers for terminal-heavy developers managing project-specific shells and full-screen editors like Neovim.
It restores terminal state on reattach, using Ghostty's VT engine for visible screen recovery in editor sessions. Sessions switch via CLI or TUI palette, with agent-aware status for tools like Codex or Claude.
Quick Overview
| Attribute | Details |
|---|---|
| Type | Terminal Multiplexers |
| Best For | terminal-heavy developers |
| Language/Stack | Go |
| License | MIT |
| GitHub Stars | 90 as of Oct 2024 |
| Pricing | Open-Source |
| Last Release | N/A — latest commit 81efd58 on recent date |
Who Should Use tsm?
- Project-focused devs running long-lived Neovim or shell sessions per repo, needing detach during SSH or laptop suspends.
- Multitaskers switching between 5-10 named sessions via palette without pane nesting.
- Terminal enthusiasts on kitty, Ghostty, or WezTerm who prefer native GPU rendering and ligatures over emulated splits.
- Minimalists avoiding tmux config overhead for simple daemon-per-session persistence.
Not ideal for:
- Teams requiring shared sessions across remote users, as tsm lacks multi-client attach.
- Users needing deep pane nesting beyond native terminal splits.
- Beginners unfamiliar with TOML manifests or Go binaries.
Key Features of tsm
- Per-session daemon — Each session runs an independent background process with its own PTY, surviving terminal closes; reattach resumes exact state including cwd and environment vars.
- TUI session palette — Compact picker displays session names, status (including AI agent activity), and attaches in under 100ms; supports full-screen and simplified layouts.
- Native multiplexing (tsm mux) — Defines workspaces in TOML with [[surface]] arrays specifying sessions, cwd, commands, and split directions; auto-detects kitty, Ghostty, WezTerm, or cmux backends for GPU-accelerated panes.
- Ghostty VT restoration — Preferred build restores visible Neovim screen on reattach via direct VT parsing, avoiding blank redraws; supports ligatures and scrollback natively.
- CLI switching —
tsm list,tsm attach <name>,tsm kill <name>commands manage 20+ sessions; integrates fish completions symlinked into config. - Workspace manifests — TOML files like dev.toml declare editor/shell splits with startup commands;
tsm mux open devlaunches full layout in one step. - Agent status — TUI shows live checks for Codex/Claude processes before switching, reducing context loss in AI-assisted coding.
tsm vs Alternatives
| Tool | Best For | Key Differentiator | Pricing |
|---|---|---|---|
| tsm | Native terminal splits per project | Per-PTY daemons + TOML workspaces, no VT wrap | Open-Source |
| tmux | Pane-heavy workflows | Server-wrapped emulation, multi-client sharing | Open-Source |
| zellij | Modern tiled layouts | Rust-based tiling with plugins | Open-Source |
| screen | Basic detach/reattach | Minimal, no multiplexing | Open-Source |
Tmux excels in collaborative setups with multiple attaches to one session but emulates VT layers, adding 50-200ms latency on reattach compared to tsm's native PTY handoff. Pick zellij for automatic tiling and plugin ecosystem if you need layout persistence beyond native terminals; its Rust core handles 100+ panes efficiently but lacks tsm's Ghostty screen restore. Screen suits ultra-minimal persistence without any splitting, though it misses modern TUI pickers. For related options, check browse all Terminal Multiplexers.
How tsm Works
tsm's architecture centers on a one-daemon-per-session model: each session spawns a Go process binding a PTY, daemonized via syscall fork. Detach sends SIGHUP to the terminal but keeps the daemon alive; reattach opens a new PTY, ioctl-attaches the daemon's PTY, and copies terminal modes (icanon, echo) for seamless resume. No central server like tmux—sessions are firewalled by name in ~/.config/tsm/sessions/.
tsm mux parses TOML workspaces into terminal-specific APIs: kitty protocol for remote control (kitty @ launch --type=tab), Ghostty/WezTerm stdin pipes, or cmux for generic muxing. Surfaces map to panes with independent PTYs, preserving full GPU acceleration—no bitmap forwarding. This delegates layout to the emulator, cutting overhead to <10ms per split.
State persists in memory-mapped files for cwd, env, and screen if Ghostty-enabled. Here's a workspace example:
name = "dev"
version = 1
[[surface]]
name = "editor"
session = "editor"
cwd = "~/Developer/myproject"
command = "nvim ."
[[surface.split]]
name = "shell"
session = "shell"
direction = "right"
cwd = "~/Developer/myproject"
Run tsm mux open dev: tsm creates/attaches sessions, sends emulator commands for splits, executes nvim . and shell init. Expect native panes with scrollback; detach closes splits but daemons persist.
Pros and Cons of tsm
Pros:
- Zero-config persistence for 10+ sessions, with PTY handoff under 50ms reattach latency.
- Native splits leverage terminal GPU/ligatures, outperforming tmux by 2-5x in render speed for Neovim.
- TOML manifests version workspaces, enabling git-tracked layouts for teams.
- Ghostty backend restores exact screen pixels, ideal for editor state recovery post-suspend.
- Fish completions and conf.d symlinks auto-integrate into sessions without manual sourcing.
- Go binary ships standalone, no runtime deps beyond libc.
Cons:
- Lacks multi-user attach; sessions are local-user only.
- Mux backends require specific emulators (kitty/Ghostty/WezTerm); falls back to cmux on others.
- No built-in logging or session search beyond
tsm list. - Early-stage: 46 commits, potential for mux bugs in edge splits.
- TOML parsing errors halt workspace opens without graceful fallback.
Getting Started with tsm
Build from source since no prebuilts: clone repo, make build. Or go install github.com/adibhanna/tsm/cmd/tsm@latest. Ensure kitty/Ghostty/WezTerm installed for mux.
# Create config dir
mkdir -p ~/.config/tsm/workspaces
# Sample workspace
cat > ~/.config/tsm/workspaces/dev.toml <<EOF
name = "dev"
version = 1
[[surface]]
name = "main"
session = "dev-main"
cwd = ~/projects/myapp
command = "zsh"
EOF
# Start workspace
./tsm mux open dev
This spawns dev-main daemon, opens native split/tab in your terminal, attaches PTY, and drops into zsh at ~/projects/myapp. List with tsm list, detach Ctrl+C (daemon survives), reattach tsm attach dev-main. Configure symlinks via tsm config init for fish.
Verdict
ts m is the strongest option for solo terminal-heavy developers managing per-project sessions with native multiplexing when avoiding tmux overhead. Its PTY-per-daemon and Ghostty restore deliver sub-100ms reattaches with full screen fidelity. Use it unless needing shared sessions—strong pick for Neovim workflows.



