pmux (Project Multiplexer) is a lightweight tool for launching development projects into structured tmux sessions.
It is designed for two kinds of repositories:
- leaf projects: normal projects you work in directly
- container projects: repos that mainly organize and coordinate subprojects
pmux automatically:
- opens a tmux session for a project
- launches Neovim or your configured editor
- opens an interactive shell
- optionally runs project startup scripts
- supports container repos with subproject editor windows
- activates Python virtual environments
- activates Node versions via
.nvmrc
Related tools:
- pmux-run: detect and run likely project commands in the current tmux session
- pmux-cheat: open cht.sh lookups in tmux
Required:
- tmux
Required for interactive project picking:
- fzf
Optional:
- nvm (for
.nvmrcsupport) - jq (for better
package.jsonscript detection inpmux-run) - curl (for
pmux-cheat) - xclip (for the example tmux clipboard binding on X11)
Clone the repository and run:
make installThis installs user-local binaries to ~/.local/bin and bootstraps default configuration under ~/.config/pmux/.
Make sure ~/.local/bin is in your PATH.
Example:
export PATH="$HOME/.local/bin:$PATH"Remove installed binaries:
make uninstallRemove binaries and configuration:
make purgeLaunch the project picker:
pmuxOr open a project directly:
pmux ~/repos/myprojectIf a tmux session for that project already exists, pmux attaches to it or switches to it.
pmux detects project type based on:
.pmux/subprojects
- If it exists, the repo is treated as a container project
- If it does not exist, the repo is treated as a leaf project
A leaf project is a normal standalone project.
Example:
myapp/
├── .pmux/
│ └── launch.sh
├── src/
└── package.json
pmux creates:
| Window | Purpose |
|---|---|
| editor | opens the editor in the project root |
| shell | opens an interactive shell in the project root |
| run | runs .pmux/launch.sh, if present |
A container project is a repo that contains subprojects.
Example:
platform/
├── .pmux/
│ ├── launch.sh
│ └── subprojects
├── frontend/
├── backend/
└── worker/
Example .pmux/subprojects:
frontend
backend
worker
pmux creates:
| Window | Purpose |
|---|---|
| frontend | editor window for frontend/ |
| backend | editor window for backend/ |
| worker | editor window for worker/ |
| shell | root shell in the container project |
| run | runs root .pmux/launch.sh, if present |
Notes:
- container projects do not create a root editor window
- subprojects get editor windows only
- subprojects do not automatically get shell or run windows
pmux supports optional repo-local configuration under:
.pmux/
Optional startup script for the project root.
For leaf projects, this creates the run window.
For container projects, this creates a root-level run window.
Example:
#!/usr/bin/env bash
set -euo pipefail
make devOptional file that marks a repo as a container project.
Each non-empty, non-comment line should be a relative subdirectory path.
Example:
frontend
backend
worker
Comments and blank lines are allowed:
# app surfaces
frontend
backend
# jobs
worker
If .pmux/subprojects exists but contains no valid directories, pmux exits with an error.
Before launching commands in a window, pmux attempts to load local development environments.
pmux searches upward from the window directory toward the project root for:
.venv
venv
env
If found, it activates the nearest match.
pmux searches upward from the window directory toward the project root for:
.nvmrc
If found, and nvm is installed, pmux runs:
nvm useThis applies per window, so different subprojects in a container repo can use different environments.
pmux-run is a current-project command picker for tmux.
It inspects the current pane directory and suggests likely commands such as:
make <target>docker compose -f <file> updocker compose -f <file> downdocker build ...npm run <script>go test ./...go run .cargo runcargo testpython -m pytest
Each invocation creates a new tmux window named after the selected command (e.g. selecting make dev creates a window called dev).
Examples:
pmux-run
pmux-run --multi--multi lets you pick multiple commands and run them in split panes in a new window.
pmux-cheat opens quick cht.sh lookups in tmux.
It reads from:
~/.config/pmux/cheat/languages
~/.config/pmux/cheat/commands
and opens a new tmux window with the result.
User config lives at:
~/.config/pmux/config
Example:
PMUX_EDITOR_CMD='exec nvim .'
PMUX_SHELL_CMD='exec "$SHELL" -l'
PMUX_CHOOSER_CMD='fzf --prompt="Project > "'
PMUX_FIXED_PROJECTS=(
"$HOME/.dotfiles"
)
PMUX_PROJECT_ROOTS=(
"$HOME/repos"
)pmux builds its selectable project list from:
- directories in
PMUX_FIXED_PROJECTS - first-level child directories of
PMUX_PROJECT_ROOTS
Example:
~/repos/project1
~/repos/project2
~/repos/project3
All become selectable projects.
project/
├── .pmux/
│ └── launch.sh
├── .venv/
└── src/
Creates:
editor
shell
run
project/
├── .pmux/
│ ├── launch.sh
│ └── subprojects
├── backend/
│ └── .venv/
├── frontend/
│ └── .nvmrc
└── worker/
Creates:
backend
frontend
worker
shell
run
bind-key -r f display-popup -E pmux
bind-key -r r run-shell "~/.local/bin/pmux-run"
bind-key -r R run-shell "~/.local/bin/pmux-run --multi"
bind-key -r c run-shell "~/.local/bin/pmux-cheat"pmux aims to:
- launch projects quickly with minimal configuration
- create consistent tmux layouts across repositories
- support both standalone and multi-repo container projects
- automatically activate development environments
- remain lightweight and dependency minimal
MIT