Hi, I'm Mike. I'm a web developer. This is my story.

How I Use Tmux as a Development Environment

When I first started as an engineer at my current employer, I soon realized that I had to think a bit differently to keep things organized. At my previous employer, all code was basically in one codebase. We didn’t use any complex build steps, just vagrant for our backend/frontend and gulp to compile scss and CoffeeScript assets (yes, this was a loooong time ago). So I could run a Vim instance and gulp in another tab in my terminal and I was good.

When I moved on, things were a lot more complex. We had at least five different services that needed to be running at once. Three of them needed front-end builds on save via grunt. Things have changed drastically since then - we now use a whole different, more modern stack, but it was more about the challenge of working with different services with different persistent processes. How could I stay organized and understand which context I was in? Where do I put persistent processes that I need to keep an eye on? Tmux helped me solve this problem years ago in an elegant way.

What is Tmux?

Tmux Tmux in action with my fancy config

Tmux is short for terminal multiplexer. It is a command-line program that runs in your terminal. You can install it with your package manager. For MacOS I use Homebrew: brew install tmux.

You might be saying, “I can already do this with my terminal emulator. Why do I need a command-line wrapper to layout my command-line sessions?” Well, the killer feature in Tmux is that it runs as a daemon. This means when you start a session with tmux or tmux new-session -s my-session-name, you can “detach” from it with <prefix>d and later “attach” to it with tmux attach -s my-session-name to continue working in that session. It continues running in the background, even if you quit your terminal emulator. If you restart and attach to that session, it will still be there.

Tmux allows you to split up your terminal into different contexts: Sessions, windows, and panes. What are those?

Windows, Sessions, and Panes

Session

A session is a top-level context. I think of it like the company I’m working for. Currently I work full time, so my only sessions are Work and Home. You can only view one session at a time, but you can open a handy switcher to switch between sessions. You can start a new session with tmux for the default session name or tmux new-session -s Work for a specific session name. You can open the session switcher with <prefix>s. I will explain what <prefix> means and some other foundational concepts shortly.

Tmux session picker

Window

A window is what I consider more of a tab in Tmux. I put everything related to one codebase or context in a window.

Tmux windows and panes

For example, I use a blog codebase window with a Neovim pane, a Tig pane for git operations, and a pane to run Jekyll to preview and generate my blog on save.

Tmux blog window

I also use some windows not related to one codebase like notes and mysql where I run mycli, pspg, and Neovim for saved queries.

Finally, I run a config window with these panes:

Tmux config window

You can create a new window with <prefix>c. Close it with <prefix>&. Rename it with <prefix>,. Switch to next and previous with <prefix>n and <prefix>p. Switch to a specific, numbered window with <prefix>{number}. Or you could open the fancy window switcher to choose a window with arrows and enter with <prefix>w.

Pane

A pane is also known as a split. It’s a separate box in the current window that has its own shell running (e.g. bash or zsh). You can just have one pane, or you can have any number of panes, split up however you like.

There are even pre-defined pane layouts that you can cycle through with <prefix><space>. Some common pane shortcuts:

Some other useful panes I run for some codebases:

What does <prefix> mean?

Since Tmux wraps your other command-line usage, they don’t want to define a lot of keyboard shortcuts that could collide with what’s running in a pane. So they use a “prefix” keyboard shortcut before running any Tmux command. The default is <ctrl-b>. I like to remap it to <ctrl-a> which is the Gnu Screen default, just because it’s more ergonomic. So once I start a Tmux session, if I want to open a new window, I would type <ctrl-a> followed by c.

How do I configure Tmux?

You create/change keyboard shortcuts, change how Tmux looks, and more with a ~/.tmux.conf file. If you want you can read man tmux to see how this works, or take a look at my config.

My Tmux config is customized, which is why the status bar and colors look different. Tmux looks like this by default:

Tmux default

Some tools I use to make Tmux look and work the way it does in my screenshots:

It’s repetitive to set up Tmux windows and panes every time I use it. Is there a tool that automates this?

Yes, there are several. The one I use currently is called Smug. It allows you to write pre-defined YAML layouts and spin up new sessions with one of those layouts. My favorite feature is manual windows. You can define some windows that don’t get created by default, but you can run smug start my-session-name:my-window-name to add them to the session for the configured layout. I do this with a Tmux keyboard shortcut. This means I don’t have to start a session with every window/codebase ready to go. I can start some of them only when I need them, with all panes just how I like them. Saves a lot of memory usage.

Older alternatives to Smug:

Where can I learn more?

Thanks for reading!

comments powered by Disqus