exupero's blog

Tmux as development environment

I've relied on Tmux for software development for more than ten years now, and I consider it my preferred development environment. Calling it a development environment sounds like a stretch, since Tmux is only a terminal multiplexer, but because Tmux can use any terminal-based programs and is so easy to script, I tend to think of it as the main interface for my IDE. In this series, I'll document some of the ways I use it.

As a terminal multiplexer, Tmux organizes terminals into a hierarchy of sessions, windows, and panes. I use a session as a workspace for a project. On projects at work, where I might have several branches checked out to different Git worktrees, I'll have a session for each worktree.

Each session has its own list of windows. I typically make window #0 my text editor, window #1 a shell, and window #9 a set of build and server daemons. Assigning daemons to window #9 puts them out of the way but still accessible via the prefix 9 keystroke. By "out of the way", I mean that new windows are created in windows #2 through #8 and I can tab through my most commonly used terminals without as often coming across the daemons I'm not usually looking for.

I used to name most of my windows based on their purpose, rather than letting Tmux name them based on whatever program is currently running, but now I only name the windows I want to refer to in scripts or, when I end up with a lot of transient windows, the ones I often want but have trouble finding quickly.

At one time I had a window with utilities that I often wanted without having to switch sessions. I ran it from one session, then included it in any session where I needed it using the link-window command.

Tmux can also split windows into panes. When I run tests, it's useful to run them in a split next to my text editor, so I can compare the output to the code. When I don't need to see test output, I maximize the text editor with prefix z, which zooms the pane to take up the full window. I hit prefix z a second time to show all the panes.

While it's not part of Tmux, I consider Vim (actually Neovim) to be part of my development environment. Vim has tabs, akin to Tmux's windows, as well as splits, akin to Tmux's panes. When working on complex code, I often arrange tabs to put code higher in the stack in tabs further left, and code lower in the stack further to the right. Sometimes that means having multiple tabs open to different lines in a single file. Arranged this way, moving up and down in the stack is as easy as the built-in gt and gT keystrokes.

Navigating this hierarchy of Tmux sessions, windows, panes and Vim tabs and splits feels, to me, a like moving around in a physical space where it's easy to see exactly where you are, and I rarely feel lost in what to others probably looks like a maze of nearly identical terminals and instances of Vim. By comparison, even advanced IDEs like IntelliJ feel cramped. I don't have the same freedom of movement.

That's the high-level structure of how I use Tmux for software development, but it doesn't cover much of my day-to-day usage. I'll dive into those details in the posts that follow.