tmux windows are not just tabs in a terminal; they’re independent command environments that can be detached and reattached, allowing you to keep long-running processes alive even after you close your laptop.
Let’s see this in action. Imagine you’re setting up a new project. You’d typically open a terminal, cd into your project directory, and start your development server.
# In your first terminal window
$ cd ~/projects/my-awesome-app
$ npm run dev
But what if you need to run tests, manage your database, or SSH into a remote server, all related to this project? Instead of opening multiple terminal windows on your OS, you can do it all within one tmux session.
Here’s how you’d create new windows for these tasks within your existing tmux session.
First, the keybinding to create a new window is Ctrl-b c. This splits your current pane into a new window. Your terminal prompt will appear, and you can then navigate to your project directory and start your next task.
# In your second tmux window
$ cd ~/projects/my-awesome-app
$ npm run test
Let’s create another window for database management.
# In your third tmux window
$ cd ~/projects/my-awesome-app
$ psql my_awesome_app_db
Now you have three distinct environments, all within a single tmux session. You can switch between them using Ctrl-b n (next window) and Ctrl-b p (previous window), or by directly referencing their index, like Ctrl-b 0 for the first window, Ctrl-b 1 for the second, and so on.
The real power comes when you start renaming these windows to be more descriptive. By default, windows are named after the command running in them, which can be confusing. To rename the current window, use Ctrl-b ,.
# In tmux, press Ctrl-b then ,
# A prompt will appear at the bottom: "rename-window 'npm run dev' \" \" "
# Type "dev server" and press Enter.
Now, your first window is labeled "dev server". You can rename the others similarly: "tests" for the second, and "db" for the third.
# In tmux, press Ctrl-b then ,
# Type "tests" and press Enter.
# In tmux, press Ctrl-b then ,
# Type "db" and press Enter.
You can see a list of all your windows with their names and indices by pressing Ctrl-b w. This brings up a scrollable list at the bottom of your screen.
# In tmux, press Ctrl-b then w
# You'll see something like:
# 0:dev server * 1:tests 2:db
# The '*' indicates the currently active window.
What if you decided "tests" should come before "dev server"? You can reorder windows by dragging them in the Ctrl-b w list, or more programmatically, by using the swap-window command. To swap the current window with the next one, you’d use Ctrl-b Ctrl-a (which is an alias for swap-window -t +1). To swap with the previous, Ctrl-b Ctrl-z (swap-window -t -1).
Let’s say your "tests" window is currently index 1 and "dev server" is index 0. To move "tests" to index 0, you’d select the "tests" window (index 1) and then swap it with the previous window:
# In tmux, press Ctrl-b then Ctrl-z (swaps with previous window)
# If "tests" was window 1 and "dev server" was window 0, they will now be:
# 0:tests * 1:dev server 2:db
This ability to create distinct, named, and reorderable workspaces within a single terminal session is what makes tmux so powerful for managing complex workflows. You’re not just managing processes; you’re orchestrating a series of interconnected tasks that can persist independently.
The window index is not fixed; it’s a sequential number assigned based on the order windows are created and their positions relative to each other. When you reorder windows, their indices change to reflect their new positions, which can be a source of confusion if you’re relying on hardcoded indices for scripting.
The next concept you’ll likely explore is how to split these windows into panes, creating even finer-grained control within a single window.