Files
tmuxinator/README.md
Hans Schnedlitz 3586520c4a
Some checks failed
Integration Tests / test (3.2.10, 1.5) (push) Failing after 12s
Integration Tests / test (3.2.10, 1.6) (push) Failing after 7s
Integration Tests / test (3.2.10, 1.9) (push) Failing after 10s
Integration Tests / test (3.2.10, 1.7) (push) Failing after 9s
Integration Tests / test (3.2.10, 1.8) (push) Failing after 10s
Integration Tests / test (3.2.10, 2.0) (push) Failing after 9s
Integration Tests / test (3.2.10, 2.1) (push) Failing after 7s
Integration Tests / test (3.2.10, 2.2) (push) Failing after 9s
Integration Tests / test (3.2.10, 2.3) (push) Failing after 12s
Integration Tests / test (3.2.10, 2.4) (push) Failing after 10s
Integration Tests / test (3.2.10, 2.5) (push) Failing after 9s
Integration Tests / test (3.2.10, 2.6) (push) Failing after 13s
Integration Tests / test (3.2.10, 2.7) (push) Failing after 13s
Integration Tests / test (3.2.10, 2.8) (push) Failing after 10s
Integration Tests / test (3.2.10, 2.9) (push) Failing after 9s
Integration Tests / test (3.2.10, 2.9a) (push) Failing after 8s
Integration Tests / test (3.2.10, 3.0) (push) Failing after 7s
Integration Tests / test (3.2.10, 3.0a) (push) Failing after 7s
Integration Tests / test (3.2.10, 3.1) (push) Failing after 9s
Integration Tests / test (3.2.10, 3.1a) (push) Failing after 8s
Integration Tests / test (3.2.10, 3.1b) (push) Failing after 7s
Integration Tests / test (3.2.10, 3.1c) (push) Failing after 7s
Integration Tests / test (3.2.10, 3.2) (push) Failing after 7s
Integration Tests / test (3.2.10, 3.2a) (push) Failing after 8s
Integration Tests / test (3.2.10, 3.3) (push) Failing after 9s
Integration Tests / test (3.2.10, 3.3a) (push) Failing after 8s
Integration Tests / test (3.2.10, 3.4) (push) Failing after 7s
Integration Tests / test (3.2.10, 3.5) (push) Failing after 7s
Integration Tests / test (3.2.10, 3.5a) (push) Failing after 8s
Integration Tests / test (3.2.10, 3.6) (push) Failing after 8s
Integration Tests / test (3.2.10, 3.6a) (push) Failing after 8s
Integration Tests / test (3.3.10, 1.5) (push) Failing after 7s
Integration Tests / test (3.3.10, 1.6) (push) Failing after 8s
Integration Tests / test (3.3.10, 1.7) (push) Failing after 8s
Integration Tests / test (3.3.10, 1.8) (push) Failing after 7s
Integration Tests / test (3.3.10, 1.9) (push) Failing after 6s
Integration Tests / test (3.3.10, 2.0) (push) Failing after 8s
Integration Tests / test (3.3.10, 2.1) (push) Failing after 8s
Integration Tests / test (3.3.10, 2.2) (push) Failing after 8s
Integration Tests / test (3.3.10, 2.3) (push) Failing after 8s
Integration Tests / test (3.3.10, 2.4) (push) Failing after 8s
Integration Tests / test (3.3.10, 2.5) (push) Failing after 9s
Integration Tests / test (3.3.10, 2.6) (push) Failing after 9s
Integration Tests / test (3.3.10, 2.7) (push) Failing after 8s
Integration Tests / test (3.3.10, 2.8) (push) Failing after 8s
Integration Tests / test (3.3.10, 2.9) (push) Failing after 9s
Integration Tests / test (3.3.10, 2.9a) (push) Failing after 8s
Integration Tests / test (3.3.10, 3.0) (push) Failing after 9s
Integration Tests / test (3.3.10, 3.0a) (push) Failing after 9s
Integration Tests / test (3.3.10, 3.1) (push) Failing after 10s
Integration Tests / test (3.3.10, 3.1a) (push) Failing after 9s
Integration Tests / test (3.3.10, 3.1b) (push) Failing after 9s
Integration Tests / test (3.3.10, 3.1c) (push) Failing after 8s
Integration Tests / test (3.3.10, 3.2) (push) Failing after 9s
Integration Tests / test (3.3.10, 3.2a) (push) Failing after 8s
Integration Tests / test (3.3.10, 3.3) (push) Failing after 8s
Integration Tests / test (3.3.10, 3.3a) (push) Failing after 9s
Integration Tests / test (3.3.10, 3.4) (push) Failing after 8s
Integration Tests / test (3.3.10, 3.5) (push) Failing after 8s
Integration Tests / test (3.3.10, 3.5a) (push) Failing after 8s
Integration Tests / test (3.3.10, 3.6) (push) Failing after 9s
Integration Tests / test (3.3.10, 3.6a) (push) Failing after 8s
Integration Tests / test (3.4.8, 1.5) (push) Failing after 8s
Integration Tests / test (3.4.8, 1.6) (push) Failing after 9s
Integration Tests / test (3.4.8, 1.7) (push) Failing after 8s
Integration Tests / test (3.4.8, 1.8) (push) Failing after 8s
Integration Tests / test (3.4.8, 1.9) (push) Failing after 10s
Integration Tests / test (3.4.8, 2.0) (push) Failing after 9s
Integration Tests / test (3.4.8, 2.1) (push) Failing after 8s
Integration Tests / test (3.4.8, 2.2) (push) Failing after 8s
Integration Tests / test (3.4.8, 2.3) (push) Failing after 10s
Integration Tests / test (3.4.8, 2.4) (push) Failing after 9s
Integration Tests / test (3.4.8, 2.5) (push) Failing after 8s
Integration Tests / test (3.4.8, 2.6) (push) Failing after 7s
Integration Tests / test (3.4.8, 2.7) (push) Failing after 9s
Integration Tests / test (3.4.8, 2.8) (push) Failing after 8s
Integration Tests / test (3.4.8, 2.9) (push) Failing after 7s
Integration Tests / test (3.4.8, 2.9a) (push) Failing after 8s
Integration Tests / test (3.4.8, 3.0) (push) Failing after 10s
Integration Tests / test (3.4.8, 3.0a) (push) Failing after 8s
Integration Tests / test (3.4.8, 3.1) (push) Failing after 8s
Integration Tests / test (3.4.8, 3.1a) (push) Failing after 9s
Integration Tests / test (3.4.8, 3.1b) (push) Failing after 8s
Integration Tests / test (3.4.8, 3.1c) (push) Failing after 8s
Integration Tests / test (3.4.8, 3.2) (push) Failing after 10s
Integration Tests / test (3.4.8, 3.2a) (push) Failing after 8s
Integration Tests / test (3.4.8, 3.3) (push) Failing after 7s
Integration Tests / test (3.4.8, 3.3a) (push) Failing after 7s
Integration Tests / test (3.4.8, 3.4) (push) Failing after 9s
Integration Tests / test (3.4.8, 3.5) (push) Failing after 10s
Integration Tests / test (3.4.8, 3.5a) (push) Failing after 8s
Integration Tests / test (3.4.8, 3.6) (push) Failing after 9s
Integration Tests / test (3.4.8, 3.6a) (push) Failing after 8s
Integration Tests / test (4.0.1, 1.5) (push) Failing after 8s
Integration Tests / test (4.0.1, 1.6) (push) Failing after 10s
Integration Tests / test (4.0.1, 1.7) (push) Failing after 8s
Integration Tests / test (4.0.1, 1.8) (push) Failing after 9s
Integration Tests / test (4.0.1, 1.9) (push) Failing after 8s
Integration Tests / test (4.0.1, 2.0) (push) Failing after 8s
Integration Tests / test (4.0.1, 2.1) (push) Failing after 10s
Integration Tests / test (4.0.1, 2.2) (push) Failing after 9s
Integration Tests / test (4.0.1, 2.3) (push) Failing after 8s
Integration Tests / test (4.0.1, 2.4) (push) Failing after 9s
Integration Tests / test (4.0.1, 2.5) (push) Failing after 9s
Integration Tests / test (4.0.1, 2.6) (push) Failing after 9s
Integration Tests / test (4.0.1, 2.7) (push) Failing after 8s
Integration Tests / test (4.0.1, 2.8) (push) Failing after 9s
Integration Tests / test (4.0.1, 2.9) (push) Failing after 8s
Integration Tests / test (4.0.1, 2.9a) (push) Failing after 8s
Integration Tests / test (4.0.1, 3.0) (push) Failing after 8s
Integration Tests / test (4.0.1, 3.0a) (push) Failing after 7s
Integration Tests / test (4.0.1, 3.1) (push) Failing after 9s
Integration Tests / test (4.0.1, 3.1a) (push) Failing after 12s
Integration Tests / test (4.0.1, 3.1b) (push) Failing after 9s
Integration Tests / test (4.0.1, 3.1c) (push) Failing after 8s
Integration Tests / test (4.0.1, 3.2) (push) Failing after 7s
Integration Tests / test (4.0.1, 3.2a) (push) Failing after 8s
Integration Tests / test (4.0.1, 3.3) (push) Failing after 8s
Integration Tests / test (4.0.1, 3.3a) (push) Failing after 10s
Integration Tests / test (4.0.1, 3.4) (push) Failing after 9s
Integration Tests / test (4.0.1, 3.5) (push) Failing after 9s
Integration Tests / test (4.0.1, 3.5a) (push) Failing after 7s
Integration Tests / test (4.0.1, 3.6) (push) Failing after 7s
Integration Tests / test (4.0.1, 3.6a) (push) Failing after 8s
Integration Tests / finish (push) Failing after 9s
Add support for focus panes (#952)
* Try add focus pane config

* Add focused pane

* Update readme and sasmple

* Update changelog

* Add more tests

* Add deprecation message

* fix: coerce focused pane indices to integers

Metadata

- addresses review feedback on quoted numeric  values
- keeps the fix scoped to

Problem

Quoted YAML scalars like  were treated as integers for validation but returned as strings. That later caused  to add a string to , which raised  during rendering.

Solution

Convert validated numeric  values with  before returning them from , and add a spec that covers quoted indices so the regression stays fixed.

* fix: match focused pane names after escaping

Metadata

- addresses review feedback on named focused panes
- keeps the change limited to focused pane lookup logic and its specs

Problem

Named focused panes were compared against the raw YAML value, but pane titles are stored in escaped form. Pane names containing spaces or shell-sensitive characters therefore failed to match and incorrectly fell back to the first pane.

Solution

Compare the requested focused pane name using the same shell escaping used when pane titles are stored, and add a regression spec that covers a pane name containing spaces.

* chore: drop unrelated tool version pin

Metadata

- removes contributor-local environment pinning from the PR
- keeps the feature branch focused on `focused_pane` changes

Problem

The branch included `.tool-versions`, which does not affect the `focused_pane` feature and introduces an unreviewed repository-wide tooling decision.

Solution

Remove `.tool-versions` so the branch stays scoped to the pane-focus feature and its supporting tests and documentation.

* test: cover focused pane render paths

Metadata

- adds render-level coverage for normal and wemux templates
- verifies deprecated `startup_pane` output remains intact

Problem

The branch only tested helper methods for focused pane selection. It did not prove that the generated tmux scripts emitted the correct `select-pane` commands for normal renders, wemux renders, or the deprecated `startup_pane` compatibility path.

Solution

Add render assertions that exercise the generated scripts directly, covering `focused_pane` in the standard and wemux templates and `startup_pane` in the standard template.

* docs: clarify focused pane and startup pane behavior

Metadata

- updates README and sample configuration guidance for pane selection
- folds the prior docs-only follow-up commits into one coherent change

Problem

The documentation around pane selection was incomplete and then overstated the relationship between `focused_pane` and `startup_pane`. It did not clearly explain that `focused_pane` is window-scoped while `startup_window` and `startup_pane` still determine the final startup selection.

Solution

Document `startup_pane` as a supported top-level setting, clarify that `focused_pane` applies within a window, and explain how `focused_pane`, `startup_window`, and `startup_pane` interact during project startup.

* fix: preserve default startup pane selection

Metadata

- scope: startup pane fallback
- tests: rspec spec/lib/tmuxinator/project_spec.rb

Problem

When startup_pane is omitted, tmux_startup_pane_command returns an empty string. That lets a window-level focused_pane in the startup window control the final attached pane, which regresses the long-standing default of attaching to the first pane.

Solution

Make tmux_startup_pane_command explicitly select the first pane in startup_window when no global startup_pane is configured. Add a regression spec that renders a startup window with focused_pane set and verifies the final startup selection still targets pane 0, plus a direct unit spec for the fallback command.

* fix: treat blank startup pane as unset

Metadata

- scope: startup pane fallback
- tests: rspec spec/lib/tmuxinator/project_spec.rb spec/lib/tmuxinator/window_spec.rb

Problem

A blank startup_pane value is truthy in Ruby, so tmux_startup_pane_command treats it as configured and builds an invalid select-pane target. That leaves a remaining edge case even after restoring the default first-pane selection when startup_pane is omitted.

Solution

Treat blank startup_pane values as unset and fall back to the first pane in startup_window. Add a regression spec that covers startup_pane set to an empty string so the invalid target cannot reappear.

* chore: clean up focused pane review nits

Metadata

- scope: focused pane follow-up cleanup
- tests: rspec spec/lib/tmuxinator/project_spec.rb spec/lib/tmuxinator/window_spec.rb

Problem

The review surfaced a few low-risk cleanup issues around the focused pane changes: a shadowing local variable, a typo in a code comment, a sloppy spec description, and inconsistent tmux capitalization in the README.

Solution

Rename the local focused pane config variable to avoid shadowing the helper method, fix the typo in the fallback comment, tighten the spec description text, and normalize the README wording to tmux v2.6.

* fix: clamp invalid focused pane indexes

Metadata

- addresses review feedback for out-of-range  values
- scope:  pane selection and specs

Problem

Numeric  values were accepted without checking whether the pane existed. Invalid indexes generated  commands that tmux rejected, leaving focus on an arbitrary pane.

Solution

Validate numeric pane indexes against the parsed pane list and fall back to the first pane when the requested index is out of range. Add spec coverage for integer and quoted integer values that point past the available panes.

* fix: preserve startup pane defaults

Metadata

- addresses review feedback on `Project#startup_pane`
- scope: startup pane target selection and related specs

Problem

`Project#startup_pane` returned an invalid target ending in `.` when `startup_pane` was unset or blank. The helper method still existed and no longer preserved the long-standing default of selecting the first pane. The deprecation note on `tmux_startup_pane_command` also implied the method itself was deprecated, which was misleading.

Solution

Make `startup_pane` treat blank and unset values as a request for the first pane in the startup window, and have `tmux_startup_pane_command` consistently use that helper. Remove the misleading deprecation comment and add specs that cover the helper directly for configured, unset, and blank values.

* style: satisfy rubocop for startup pane helper

Metadata

- follows repo RuboCop enforcement for the startup pane changes
- scope: `Tmuxinator::Project#startup_pane`

Problem

The previous `startup_pane` fix introduced a line-length violation in `project.rb`, which would fail the repo's RuboCop check.

Solution

Rewrite the pane selection assignment in multiline form so the helper remains readable and passes the configured RuboCop rules without changing behavior.

* docs: restore readme yaml guidance

Metadata

- narrows README churn on the focused pane branch
- scope: user guidance around pane configuration examples

Problem

The branch removed the longstanding README warning about YAML indentation and the note about custom layout inconsistencies, even though those behaviors were not changed by the focused pane work. Those notes still help users debug common configuration mistakes.

Solution

Restore the YAML indentation warning and the existing custom layout note, keeping their prior external references while leaving the focused pane documentation intact.

* fix: harden focused pane index handling

Metadata

- Addresses unresolved PR #952 review comments for focused_pane validation and docs.
- Keeps the existing startup_pane behavior explicit in the user-facing examples.

Problem

- Negative focused_pane values were accepted because Ruby arrays support negative indexing, which could generate an invalid tmux target or focus the wrong pane.
- The local variable inside pane_index shadowed the method name, which made the control flow harder to read.
- The startup_pane comments in the README and sample config no longer stated the default first-pane behavior when unset.

Solution

- Reject negative integer focused_pane values before indexing panes and fall back to the first pane.
- Rename the local parsed index variable to idx and add specs for -1 and "-1" fallback behavior.
- Restore the startup-pane documentation note that the first pane is used when the setting is not provided.

* fix: restore public startup_pane API

Metadata

- Scope: startup_pane visibility
- Review: address P2 regression from the focus-pane patch

Problem

- The recent refactor moved startup_pane below the class private marker.
- Existing Ruby callers that invoke project.startup_pane now raise NoMethodError.
- The spec only exercised the method via send, so the visibility regression was not covered.

Solution

- Re-expose startup_pane as a public instance method.
- Update the project spec to call startup_pane directly so the public contract is enforced.

Signed-off-by: Andrew Kofink <ajkofink@gmail.com>

---------

Signed-off-by: Andrew Kofink <ajkofink@gmail.com>
Co-authored-by: Andrew Kofink <ajkofink@gmail.com>
2026-04-11 11:13:26 -04:00

16 KiB

Tmuxinator

Gem Version Integration Tests Coverage Status Code Climate Dependency Status Gitter

Create and manage tmux sessions easily.

Screenshot

Installation

RubyGems

gem install tmuxinator

Homebrew

brew install tmuxinator

Some users have reported issues when installing via Homebrew, so the RubyGems installation is preferred until these are resolved.

tmuxinator aims to be compatible with the currently maintained versions of Ruby.

Some operating systems may provide an unsupported version of Ruby as their "system ruby". In these cases, users should use RVM or rbenv to install a supported Ruby version and use that version's gem binary to install tmuxinator.

Editor and Shell

tmuxinator uses your shell's default editor for opening files. If you're not sure what that is type:

echo $EDITOR

For me that produces "vim". If you want to change your default editor simply put a line in ~/.bashrc that changes it. Mine looks like this:

export EDITOR='vim'

tmux

The recommended version of tmux to use is 1.8 or later, with the exception of 2.5, which is not supported (see issue 536 for details). Your mileage may vary for earlier versions. Refer to the FAQ for any odd behaviour.

Completion

Your distribution's package manager may install the completion files in the appropriate location for the completion to load automatically on startup. But, if you installed tmuxinator via Ruby's gem, you'll need to run the following commands to put the completion files where they'll be loaded by your shell.

bash

wget https://raw.githubusercontent.com/tmuxinator/tmuxinator/master/completion/tmuxinator.bash -O /etc/bash_completion.d/tmuxinator.bash

zsh

wget https://raw.githubusercontent.com/tmuxinator/tmuxinator/master/completion/tmuxinator.zsh -O /usr/local/share/zsh/site-functions/_tmuxinator

Note: ZSH's completion files can be put in other locations in your $fpath. Please refer to the manual for more details.

fish

wget https://raw.githubusercontent.com/tmuxinator/tmuxinator/master/completion/tmuxinator.fish -O ~/.config/fish/completions/tmuxinator.fish

Usage

A working knowledge of tmux is assumed. You should understand what windows and panes are in tmux. If not please consult the man pages for tmux.

Create a project

Create or edit your projects with:

tmuxinator new [project]

Create or edit a local project where the config file will be stored in the current working directory (in .tmuxinator.yml) instead of the default project configuration file location (e.g. ~/.config/tmuxinator):

tmuxinator new --local [project]

For editing you can also use tmuxinator open [project]. new is aliased to n,open to o, and edit to e. Please note that dots can't be used in project names as tmux uses them internally to delimit between windows and panes. Your default editor ($EDITOR) is used to open the file. If this is a new project you will see this default config:

# ~/.tmuxinator/sample.yml

name: sample
root: ~/

# Optional tmux socket
# socket_name: foo

# Note that the pre and post options have been deprecated and will be replaced by
# project hooks.

# Project hooks

# Runs on project start, always
# on_project_start: command

# Run on project start, the first time
# on_project_first_start: command

# Run on project start, after the first time
# on_project_restart: command

# Run on project exit ( detaching from tmux session )
# on_project_exit: command

# Run on project stop
# on_project_stop: command

# Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions.
# pre_window: rbenv shell 2.0.0-p247

# Pass command line options to tmux. Useful for specifying a different tmux.conf.
# tmux_options: -f ~/.tmux.mac.conf

# Change the command to call tmux. This can be used by derivatives/wrappers like byobu.
# tmux_command: byobu

# Specifies (by name or index) which window will be selected on project startup. If not set, the first window is used.
# startup_window: editor

# Specifies (by index) which pane of the startup window will be selected on project startup. If not set, the first pane is used.
# startup_pane: 1

# Controls whether the tmux session should be attached to automatically. Defaults to true.
# attach: false

# Enables the display of pane titles. For example "editor" below. Defaults to false.
# enable_pane_titles: true

# Configures pane title position. Can be: bottom, top, or "off". Note: "off" must be provided in quotes to avoid being interpreted as a boolean false. Defaults to top.
# pane_title_position: bottom

# Configures pane title format. Defaults to "#{pane_index}: #{pane_title}".
# Please see the tmux manpage for details, on valid formats.
# pane_title_format: " [ #T ] "

windows:
  - editor:
      layout: main-vertical
      panes:
        - editor: vim
        - guard
      # Focus a pane by name or index. Indices are based off zero and automatically adjusted to your pane-base-index.
      focused_pane: editor
      # Synchronize all panes of this window, can be enabled before or after the pane commands run.
      # synchronize: after
  - server: bundle exec rails s
  - logs: tail -f log/development.log

It's also possible to create a new tmuxinator project from an existing tmux session. This can be done by running the following command:

tmuxinator new [project] [session]

This will record the windows, along with their specified layout, panes, tmux session options, and project root based on the tmux default-path of the specified tmux session in the new tmuxinator project.

Windows

The windows option allows the specification of any number of tmux windows. Each window is denoted by a YAML array entry, followed by a name* and command to be run.

*Users may optionally provide a null YAML value (e.g. null or ~) in place of a named window key, which will cause the window to use its default name (usually the name of their shell).

windows:
  - editor: vim

Window specific root

An optional root option can be specified per window:

name: test
root: ~/projects/company

windows:
  - small_project:
      root: ~/projects/company/small_project
      panes:
        - start this
        - start that

This takes precedence over the main root option.

Panes

Note that if you wish to use panes, make sure that you do not have . in your project name. tmux uses . to delimit between window and pane indices, and tmuxinator uses the project name in combination with these indices to target the correct pane or window.

Panes are optional and are children of window entries, but unlike windows, they do not need a name. In the following example, the editor window has 2 panes, one running vim, the other guard.

windows:
  - editor:
      layout: main-vertical
      panes:
        - vim
        - guard

The layout setting gets handed down to tmux directly, so you can choose from one of the five standard layouts or specify your own.

Please note the indentation here is deliberate. YAML's indentation rules can be confusing, so if your config isn't working as expected, please check the indentation. For a more detailed explanation of why YAML behaves this way, see this Stack Overflow question.

Note: If you're noticing inconsistencies when using a custom layout it may be due #651. See this comment for a workaround.

Pane Titles

Starting with tmux v2.6 it is possible to give a title to panes. Pane titles will be shown only when enable_pane_titles: true is set.

enable_pane_titles: true

windows:
  - editor:
      layout: main-vertical
      panes:
        - editor: vim
        - guard: guard

Focus Pane

Focus a pane within a specific window by specifying focused_pane on that window. Focused panes can be specified by their index. Indices start with zero and are automatically adjusted to your tmux pane-base-index.

windows:
  - editor:
      layout: main-vertical
      panes:
        - vim
        - guard
        - devlog
      focused_pane: 2 # Focus the last pane

When using named panes, you may specify a pane by its name.

windows:
  - editor:
      layout: main-vertical
      panes:
        - editor: vim
        - guard: guard
      focused_pane: guard

focused_pane selects the active pane within that window when the window is configured. The top-level startup_window and startup_pane options still control which window and pane are finally selected when tmuxinator finishes starting the project.

Interpreter Managers & Environment Variables

To use tmuxinator with rbenv, RVM, NVM etc, use the pre_window option.

pre_window: rbenv shell 2.0.0-p247

These command(s) will run before any subsequent commands in all panes and windows.

Custom session attachment

You can set tmuxinator to skip auto-attaching to the session by using the attach option.

attach: false

If you want to attach to tmux in a non-standard way (e.g. for a program that makes use of tmux control mode like iTerm2), you can run arbitrary commands by using a project hook:

on_project_exit: tmux -CC attach

Passing directly to send-keys

tmuxinator passes commands directly to send keys. This differs from simply chaining commands together using && or ;, in that tmux will directly send the commands to a shell as if you typed them in. This allows commands to be executed on a remote server over SSH for example.

To support this both the window and pane options can take an array as an argument:

name: sample
root: ~/

windows:
  - stats:
    - ssh stats@example.com
    - tail -f /var/log/stats.log
  - logs:
      layout: main-vertical
      panes:
        - logs:
          - ssh logs@example.com
          - cd /var/logs
          - tail -f development.log

ERB

Project files support ERB for reusability across environments. Eg:

root: <%= ENV["MY_CUSTOM_DIR"] %>

You can also pass arguments to your projects, and access them with ERB. Simple arguments are available in an array named @args.

Eg:

$ tmuxinator start project foo
# ~/.tmuxinator/project.yml

name: project
root: ~/<%= @args[0] %>

...

You can also pass key-value pairs using the format key=value. These will be available in a hash named @settings.

Eg:

$ tmuxinator start project workspace=~/workspace/todo
# ~/.tmuxinator/project.yml

name: project
root: ~/<%= @settings["workspace"] %>

...

Starting a session

This will fire up tmux with all the tabs and panes you configured, start is aliased to s.

tmuxinator start [project] -n [name] -p [project-config]

If you use the optional [name] argument, it will start a new tmux session with the custom name provided. This is to enable reuse of a project without tmux session name collision.

If there is a ./.tmuxinator.yml file in the current working directory but not a named project file in ~/.tmuxinator, tmuxinator will use the local file. This is primarily intended to be used for sharing tmux configurations in complex development environments.

You can provide tmuxinator with a project config file using the optional [project-config] argument (e.g. --project-config=path/to/my-project.yaml or -p path/to/my-project.yaml). This option will override a [project] name (if provided) and a local tmuxinator file (if present).

Shorthand

The shell completion files also include a shorthand alias for tmuxinator that can be used in place of the full name*.

mux [command]

*The mux alias has been removed from the Zsh completion script because it was resulting in unexpected behavior in some setups. Including aliases in completion scripts is not standard practice and the Bash and Fish aliases may be removed in a future release. Going forward, users should create their own aliases in their shell's RC file (e.g. alias mux=tmuxinator).

Other Commands

Copy an existing project. Aliased to c and cp

tmuxinator copy [existing] [new]

List all the projects you have configured. Aliased to l and ls

tmuxinator list

Stop a project.

tmuxinator stop [project]

Stop all active projects.

tmuxinator stop-all

Remove a project. Aliased to rm

tmuxinator delete [project]

Remove all tmuxinator configs, aliases and scripts. Aliased to i

tmuxinator implode

Examines your environment and identifies problems with your configuration

tmuxinator doctor

Shows tmuxinator's help. Aliased to h

tmuxinator help

Shows the shell commands that get executed for a project

tmuxinator debug [project]

Shows tmuxinator's version.

tmuxinator version

Append a project's windows to the current session (instead of creating a new session)

tmuxinator start [project] --append

Project Configuration Location

Using environment variables, it's possible to define which directory tmuxinator will use when creating or searching for project config files. (See PR #511.)

Tmuxinator will attempt to use the following locations (in this order) when creating or searching for existing project configuration files:

  • $TMUXINATOR_CONFIG
  • $XDG_CONFIG_HOME/tmuxinator
  • ~/.tmuxinator

FAQ

Window names are not displaying properly?

Add export DISABLE_AUTO_TITLE=true to your .zshrc or .bashrc

Commands being lost or corrupted

If a lot of commands or long commands are sent to a pane, and commands or characters seem to be lost or corrupted, it could be that the TTY typeahead buffer is full and losing new characters. This may happen when an earlier command takes a long time to complete. This seems to affect macOS with zsh more than other platforms.

When this occurs, try putting your commands in a separate script and calling that from your tmuxinator configuration using e.g.: source.

Contributing

To contribute, please read the contributing guide.

Copyright (c) 2010-2025 Allen Bargi, Christopher Chow. See LICENSE for further details.