Course Lessons
Session management with Tmux
So now that we've solved a lot of the key stumbling blocks (keybindings and navigation) and gotten a great workflow between Tmux and Neovim, there's one more elephant in the room.
How can we manage our sessions?
Having to stand up multiple servers, getting Neovim in the right project folder etc. — these are all things you can do with a handful of keystrokes. The problem is that it's the same thing over and over and it should be easier to manage standing up our environments OR going back to a session we had setup previously.
If you've learned nothing else from this course, it should be this. If you're doing something repetitive or something that should have a better/faster/easier way to do it, you're probably right.. That's true for session management in Tmux. Let's dig into it.
Enter tmuxifier
.
With it, you can create, edit, and manage Tmux sessions. Sure it's old but it is maintained. The best part is that it's very simple. All it does is run shell scripts but that's perfect. We have no external dependencies and the setup is straightforward.
The Install
First you'll want to clone the repo into a specific folder.
git clone https://github.com/jimeh/tmuxifier.git ~/.tmuxifier
Clone It!
Of course, you'll want to add a couple lines to your config files for your shell. Specifically, you'll want to make sure you have tmuxifier
in your path. Check the link above for the specific lines for your shell.
export PATH="$HOME/.tmuxifier/bin:$PATH"
For Bash and ZSH
Also, we need to init
tmuxifier. That's done with this line. If you use something other than bash or zsh, refer to the link for your shell.
# for bash and zsh
eval "$(tmuxifier init -)"
Now with this in place, you can setup templates to setup a tmux session.
Let's build one together.
tmuxifier new-session awesome-sauce
# Set a custom session root path. Default is `$HOME`.
# Must be called before `initialize_session`.
#session_root "~/Projects/awesome-sauce"
# Create session with specified name if it does not already exist. If no
# argument is given, session name will be based on layout file name.
if initialize_session "awesome-sauce"; then
# Create a new window inline within session layout definition.
#new_window "misc"
# Load a defined window layout.
#load_window "example"
# Select the default active window on session creation.
#select_window 1
fi
# Finalize session creation and switch/attach to it.
finalize_and_go_to_session
Default setup
Let's break down this file so we can understand what each part does.
The first section is about what the root of the project is. This will help when navigating to paths relative to this session root.
# Set a custom session root path. Default is `$HOME`.
# Must be called before `initialize_session`.
#session_root "~/Projects/awesome-sauce"
Next we attempt to initialize_session
with the line if initialize_session "awesome-sauce"; then
.
If this fails because the session already exists, we skip all of the following steps and go to the session in-progress with the last line of this boilerplate — finalize_and_go_to_session
.
Now we come to the setup of our windows. Let's start one and call it ping
. We'll use this to ping
Google's DNS servers.
We'll then create another window that does a DNS lookup of our domain learn.typecraft.dev
. For whatever reason, we want to do this every time we load this session.
First, we'll want to create two new windows.
new_window "ping"
new_window "dns_lookup"
This is straightforward enough.
If we load this layout with tmuxifier load-session awesome-sauce
, we should see something like this.

So how can we automatically run commands for each?
To do this, we need to do the following.
- Select a window
- Run the command
Let's do that now.
# Set a custom session root path. Default is `$HOME`.
# Must be called before `initialize_session`.
#session_root "~/Projects/awesome-sauce"
# Create session with specified name if it does not already exist. If no
# argument is given, session name will be based on layout file name.
if initialize_session "awesome-sauce"; then
new_window "ping"
new_window "dns_lookup"
select_window 0
run_cmd "ping 8.8.8.8"
select_window 1
run_cmd "dig learn.typecraft.dev"
fi
# Finalize session creation and switch/attach to it.
finalize_and_go_to_session
Now when you launch a new session, you should see this.


This is fine but I realize that I don't want two windows for this. I'd like to see it in one window in two separate vertical panes.
Let's update the layout file.
# Set a custom session root path. Default is `$HOME`.
# Must be called before `initialize_session`.
#session_root "~/Projects/awesome-sauce"
# Create session with specified name if it does not already exist. If no
# argument is given, session name will be based on layout file name.
if initialize_session "awesome-sauce"; then
new_window "healthcheck"
split_h 60
select_pane 1
run_cmd "ping 8.8.8.8"
select_pane 0
run_cmd "dig learn.typecraft.dev"
select_pane 0
fi
# Finalize session creation and switch/attach to it.
finalize_and_go_to_session
Here we create one new window called healthcheck
. We split this horizontally with split_h 60
. You don't have to add a number here, but doing so will set the percentage of the split. The default is 50
.
split_h
and split_v
are confusingly named. I'd expect that a horizontal split would result in two panes sitting on top of each other. I imagine the word horizontal
describes the direction of a knife cutting through the screen. That's the wrong way to think about it. You should consider what the directional flow of the panes after they've been split. If you have two panes sitting on top of each other, they are flowing vertically. If you have two side by side, they are flowing horizontally.
Just like us, the panes care about the flow.
<leader>+ %
. Here, the analogy of a knife cutting vertically is correct. A vertical split (using %) would result in two panes sitting side-by-side while a horizontal split (using ") would have one pane sitting on top of another. Now that we have two panes, we can select one at a time and run our commands just like before.
# Set a custom session root path. Default is `$HOME`.
# Must be called before `initialize_session`.
#session_root "~/Projects/awesome-sauce"
# Create session with specified name if it does not already exist. If no
# argument is given, session name will be based on layout file name.
if initialize_session "awesome-sauce"; then
new_window "healthcheck"
split_h 60
select_pane 1
run_cmd "ping 8.8.8.8"
select_pane 0
run_cmd "dig learn.typecraft.dev"
fi
# Finalize session creation and switch/attach to it.
finalize_and_go_to_session
Let's give this a shot.

Now I can detach with (Ctrl+s) + d
and whenever I want to come back, I just load the session again.
tmuxifier load-session awesome-sauce
and it's like I never left.
Awesome sauce.
F
You've completed this lesson!
You completed this lesson less than a minute ago.