---
date: "2021-06-18T19:55:00Z"
title: "Tmuxinator: simple terminal workspaces for your projects"
description: "How to use tmuxinator to manage your tmux based project workspaces."
tags: [100daystooffload, technology]
---

## Living without workspaces

IDEs and richly-featured text editors - such as [VS Code](https://code.visualstudio.com) and [Sublime Text](https://www.sublimetext.com) - support many great features. One of these is the notion of _projects_ or _workspaces_.

Such workspaces let you save your project's development configuration to disk - things like the project directory, open files, editor layout, integrated terminal commands, and more. Often, each project can have its own workspace, too.

If you use workspaces then you don't need to go through the tedious process of setting everything back up again each time you switch project, re-open your editor, or reboot your computer.

However, if, like me, you use the terminal as a primary development environment, things don't work quite so nicely out of the box. For example, I use [tmux](https://github.com/tmux/tmux/wiki) as my primary development environment, and make use of multiple windows and panes for things like Vim, source control, logs, and running commands.

At any given time, I might have a handful of tmux sessions running (one for each project). A single small session project might consist of a web API service and a separate front-end - each comprising Vim editor panes, and a mix of other things. Context switching is super easy, as I can just detach from a session, and then re-attach to another one that tmux has kept running for me in the background.

However, the pain point comes when rebooting. Once the tmux server process terminates, all of the running sessions are lost. This means setting each session up again individually each time you want to begin working on a different project after rebooting.

It certainly feels like a blocker to performing system upgrades that require reboots, and is also extra friction that may prevent one from working on specific projects if the set-up is too painstaking. Both of these are clearly not good.

However, there is a solution: [tmuxinator](https://github.com/tmuxinator/tmuxinator).

## Tmuxinator

Tmuxinator is a program that partly aims to try and fix the workspace problem for tmux-based workflows, and my life is so much easier because of it.

The program does not interfere with the tmux server directly, and neither does it maintain individual explicit tmux session data - tmux sessions are still lost after reboot.

However, what it _does_ do is make workspace session management so much easier by storing your project window and pane layout in a simple YAML file on disk.

For example, a simple API and separate web front-end project (as mentioned above) could be described as the following tmuxinator project:

```yaml
name: cool-project
root: ~/project/my-cool-web-project

windows:
  - api:
      root: ~/project/my-cool-web-project/api
      layout: main-vertical
      panes:
        - vim
        - app:
          - source .venv/bin/activate
          - source .envfile
          - flask run
        - zsh
  - frontend:
      root: ~/project/my-cool-web-project/web
      layout: main-vertical
      panes:
        - vim
        - yarn start
        - zsh
```

This project represents two tmux windows, each with three panes: an editor, a server (or watcher), and an empty shell pane that can be used for issuing commands (like `git`). The inbuilt `main-vertical` layout automatically provides a nice, big Vim window (in these cases) for editing, and then a vertically-split extra pair of panes.

Each window has a separate root directory, and the project as a whole has its own root directory too, to provide better automatic working directories in case new windows are later created when inside the session. Each session and window also gets its own name (e.g. `api` and `frontend` above) to make identification easier later on.

If this file is stored in `~/.config/tmuxinator/cool-project.yml`, one can simply run `tmuxinator start cool-project` to get started. If the project is already running it will attach you to it as-is. If the project is not currently up and running, tmuxinator will go ahead and create all your windows and panes, run the commands you specify, and connect you to the new session.

Once inside the session, it's just controlled by plain old tmux. To detach from the session, just use the usual tmux sequence (by default `ctrl-B-D`). You can then connect back to the same session or another one.

## Creating more project configurations

Tmuxinator comes with lots of other commands to make set-up easier. For example, running `tmuxinator new <project name>` will open up your editor on a template YAML file for you to edit and then save.

If you have lots of similar types of projects with the same layouts then the copy command is useful for duplicating projects as a convenient start-point: `tmuxinator cp <existing> <new>`. You can also list and delete projects in a similar way: `tmuxinator ls` and `tmuxinator rm <project name>`.

Definitely take a look through the [documentation](https://github.com/tmuxinator/tmuxinator) to learn more about these and other commands.

## Installing tmuxinator

Many distributions include tmuxinator in their repos. On macOS it's a simple `brew install tmuxinator`.

Take a look at the [installation instructions](https://github.com/tmuxinator/tmuxinator#installation) for more information.

## Backing-up and syncing projects

Being able to recover tmux sessions is great, but what if you want to sync projects between devices, or back them up?

There are various approaches for this. I store my configuration files in my personal [Nextcloud](https://nextcloud.com), which means I can hydrate any new devices with a simple link:

```shell
ln -s ~/Nextcloud/dotfiles/.config/tmuxinator ~/.config/tmuxinator
```

That way, if I use `tmuxinator new` to create a new project configuration it will automatically get synced to my Nextcloud. This approach also works if you use software like [Syncthing](https://syncthing.net).

If you work in a team and want to share your setup through version control, you could also commit the project-specific YAML file to your repo. The `tmuxinator start` command will look in `./.tmuxinator.yml` before anywhere else, and so this offers a nice way to get your whole team using a consistent setup. However, in my experience the workspace setup can be quite a personal thing!

If you have any other thoughts for maintaining terminal-based workspace sessions, then I'd love to hear them. Please let me know.
