In this episode we prepare a production-ready setup: a version-controlled dotfiles repo, cross-machine bootstrap scripts, conditional config for Linux/macOS, and a safe, deterministic config checklist.

In episode 25 we covered integration with editors & the developer ecosystem — connecting tmux to Neovim/VS Code, lazygit, and the fzf session switcher. All that setup is valuable, but one question remains unanswered: how do you bring it to another machine? A great setup means nothing if it can't be reproduced — and reproducibility is the working definition of "production-ready".
This is the problem every engineer who changes machines experiences: a new laptop, an office workstation, a new server, or a CI container. Without preparation, every move means rebuilding the config from scratch, repeating the same mistakes, and losing keybindings you'd gotten comfortable with. A config that isn't version-controlled is knowledge lost every time a machine changes.
In this episode we'll build the foundation that solves all of that: storing ~/.tmux.conf and plugins in a dotfiles repo, an automatic install (bootstrap) script ready to run on a bare machine, conditional config to handle Linux/macOS differences, then a production-ready checklist — session backup/restore, safe and deterministic config, team workflow standardization, and keybinding documentation for onboarding.
~/.tmux.conf is an asset as valuable as application code — it stores hours of decisions: customized keybindings, the chosen theme, curated plugins. Treat it like code:
The core principle is simple: never rely on a config that only lives on one machine. A file that never leaves its original machine is a file ready to disappear.
Dotfiles don't have to be one giant file. Config split by section is easier to maintain and review. For tmux, the conf.d pattern sourced in order is very effective: the 10-basics.conf file loads first, then 20-theme.conf, then 30-platform-*.conf — numbered names give an explicit, deterministic order.
A new machine should be ready in minutes: git clone the repo, run one script, done. The bootstrap script does three things: create symlinks from the repo into ~, install TPM along with its plugins, and verify that tmux loads the config without errors. If any step fails, the script stops — no half measures.
One identical config for all OSes rarely runs smoothly. The most common differences: clipboard (on macOS, pbcopy/pbpaste; on Linux, xclip/xsel), and sometimes differences in default-terminal and copy bindings. The solution isn't two totally different files, but one identical core config on all machines, plus one small platform-specific file loaded conditionally.
if-shell lets tmux load different config based on external conditions — e.g. the result of uname -s:
~/.dotfiles/
├── .tmux.conf
├── .tmux/
│ ├── conf.d/
│ │ ├── 10-basics.conf
│ │ ├── 20-theme.conf
│ │ ├── 30-platform-macos.conf
│ │ └── 30-platform-linux.conf
│ └── plugins/
├── install.sh
├── bin/
│ └── tmux-cleanup.sh
└── README.mdRead left to right: the repo stores one ~/.tmux.conf holding the core config; conf.d holds the sections sourced in order; if-shell picks the right platform file; and each platform file only contains small differences — in this example, the copy command that writes to the system clipboard. The core config stays single, differences are isolated into small, easy-to-review files.
Warning
Test the config on both platforms before saving it. pbcopy doesn't exist on Linux and xclip isn't always present on macOS. The correct pattern: platform files only contain commands available on that platform, and if a command depends on an external package (xclip), make sure it's installed in that machine's bootstrap section. A config that assumes one OS is a config that will fail on another machine.
A reproducible config is the beginning; a config you can rely on in production is the goal. Here are the areas you must cover.
A tmux session is your work state — and state must be salvageable. Two plugins we touched in episode 12:
Both are installed via TPM like any other plugin. What's often forgotten: test the restore. A restore config that was never tested is a config that will fail at the moment you need it most — exactly like a database backup whose restore was never tested.
Deterministic means: same machine, same steps, same result. Practices that support it:
10-, 20-, 30- naming in conf.d guarantees order without ambiguity.~ and $HOME so the config is portable across users and machines.renumber-windows on: windows are always numbered consecutively, independent of creation order — scripts that depend on window numbers become more stable.When tmux is used collectively by a team (e.g. for shared access to production servers, episode 17), standardization reduces errors. Establish one config as the reference, review changes like code review, and keep it in the team repo (or fork from personal dotfiles). Small differences between members are fine as long as prefix, core keybindings, and session naming patterns are consistent — because those are what get used during collaboration and when onboarding new people.
Undocumented keybindings are hidden knowledge. For teams, create a short cheatsheet in the dotfiles repo README: a table of prefix, pane navigation, window/session, copy mode, and custom bindings. For yourself, there's a great automatic way — tmux itself can print all bindings:
tmux list-keys > ~/.dotfiles/docs/tmux-keys.txttmux list-keys prints every active keybinding. Save the output into the repo as a reference that's always in sync with the config — never stale like manual documentation.
Use the following checklist as a measure of your setup's readiness:
conf.d sourced in order, explicit and deterministic.30-platform-*.conf and tested on both OSes.tmux list-keys) for onboarding.tmux source-file without errors before use./home/arman/.tmux.conf inside config or scripts make the setup fail for other users. Solution: use ~ and $HOME, and make the repo path a variable in scripts.bind-key ... copy-pipe-and-cancel "pbcopy" directly in ~/.tmux.conf breaks Linux. Solution: separate it into a platform file and load it with if-shell.tmux list-keys the source, or update the README in the same commit as the config change.In episode 26, you prepared tmux toward a production standard: version-controlled dotfiles with a clear conf.d structure, a one-command bootstrap script that sets up symlinks and TPM, if-shell-based conditional config to handle Linux/macOS differences, session backup/restore with resurrect/continuum, safe and deterministic config, team workflow standardization, and keybinding documentation for onboarding.
Key points to take away:
if-shell + platform files separate OS differences from the core config.With a reproducible setup in hand, you're almost at the summit of this series. In episode 27, the closing episode, we'll cover the alternative ecosystem & final reflection — an honest comparison of tmux against Zellij and GNU Screen, when to use each, a migration guide from GNU Screen to tmux, plus a recap of the journey and a daily-driver checklist for building lasting muscle memory. Stay sharp!