I made a Claude Code session manager for tmux

philips1 pts0 comments

I made a Claude Code session manager for tmux

Sign in<br>Subscribe

Hi, it's Takuya. I'm happy to introduce a tool for managing multiple Claude Code sessions in tmux. Here is a demo video:<br>First, let me share a bit about the journey that led me to build it. Or, you can just jump right to the repo here:<br>GitHub - craftzdog/tmux-claude-session-manager<br>Contribute to craftzdog/tmux-claude-session-manager development by creating an account on GitHub.<br>GitHubcraftzdog

Tightening the feedback loop so agents can move fast<br>Recently, I've read Christoph Nakazawa's blog post. He emphasizes the importance of the toolchain in boosting feedback loops and developer productivity to work efficiently with coding agents:<br>Working with coding agents is basically the same as working in a large organization: You drop new engineers without context on the codebase all the time, just like agents! The more constraints like lint rules, automated testing, and other methods of fast verification you put on the code, the faster people can iterate on their changes, and the faster they can get work done.<br>It inspired me to focus on updating my tool setup and DX in my project. First, I focused on improving tool performance.<br>For example, I recently migrated Inkdrop's build toolchain from webpack + Grunt to electron-vite@6-beta (Vite 8 + Rolldown). It made the production build 10x faster, and the dev build now launches almost instantly. Also, I installed @typescript/native-preview, a Go-based rewrite of TypeScript. It's super fast and has improved my AI development pipeline, because the AI often runs a typecheck on every task. Similarly, I migrated my linter from eslint to oxlint, and my formatter from prettier to oxfmt.<br>Next, the review process. I've been using the lazygit integration of snacks in Neovim. When I review changes across a lot of files, I use Yanuo's codediff.nvim. Since I often jump around files, I added an option to automatically open the diff when changing the selection in the explorer without pressing Enter (it got merged into codediff.nvim. Thanks, YanuoπŸ™).<br>These improvements have been great for boosting feedback loops in a single project (bonus: without ever leaving the terminal screen or touching the mouse). As Christoph says, working with coding agents is like working in a large organization. It means you have a bunch of engineers to manage.<br>Juggling multiple sessions is annoying<br>The next pain point in my workflow is managing multiple Claude Code sessions. I usually run multiple Claude sessions simultaneously, because I have a lot of modules and libraries to maintain, e.g., the desktop app, mobile app, theme module, markdown renderer, React Native libraries, etc. I shared a tmux tip on how to run Claude Code in a tmux popup window with persistent sessions. It allows me to have fewer tmux windows instead of separate windows for each Claude Code session. But it's been annoying to check whether any sessions are finished or need my answers by switching windows and opening each session in a popup window.<br>Introducing tmux-claude-session-manager<br>So, I created a tool to manage Claude Code sessions in tmux. I published it as a tpm plugin so you can quickly try it. It gives me a single fzf picker over all my running Claude sessions, so I can see which ones need me and jump straight to them instead of switching windows. In a nutshell, it supports:<br>πŸ”’ A central picker (prefix + u) listing every running Claude session.<br>🟒 Live status per session β€” working / waiting / idle β€” driven by<br>Claude Code hooks, so you instantly see which need you.<br>πŸ‘οΈ A live preview of each session's screen right in the picker.<br>🎯 Smart jump β€” selecting a session switches your client to the window it<br>was launched from, then resumes it in a popup over it.<br>πŸš€ A launcher (prefix + y) that opens/attaches a Claude session for the<br>current directory.<br>❌ Quick kill (ctrl-x) of finished sessions from the picker.<br>It's built entirely on tmux primitives and shell scripts β€” there's no background daemon or extra process to keep alive. Here's the gist:<br>Each session is a plain tmux session. When you launch one, the plugin starts a detached session named claude- running claude. Because the name is derived from the path, launching again from the same directory just re-attaches to the existing session instead of spawning a duplicate.<br>State lives on the session itself. The Claude Code hooks stamp a @claude_state option (working / waiting / idle) onto the tmux session whenever Claude changes state. Nothing polls in the background β€” the status is written the moment it changes.<br>The picker is fzf. It lists every claude-* session, reads each one's state for the status dot, and shells out to tmux capture-pane for the live preview. When you pick one, it switches your client to the window you originally launched it from (remembered in @claude_origin) and resumes the session in the popup.<br>Because everything is stored on the tmux sessions themselves, the state survives detaching,...

claude session tmux code sessions from

Related Articles