/mʌks.rʌn/
Managing multiple processes across terminals gets messy: scattered tabs, no clear picture of what's running where, and manual restarts every time you switch branches or worktrees.
muxrun keeps it simple — muxrun up to start everything, muxrun ps to see what's running and from which directory, muxrun up again to restart.
- Install muxrun:
Homebrew (macOS / Linux):
brew install --cask tkuramot/tap/muxrunOr via go install:
go install github.com/tkuramot/muxrun@latest- Create
muxrun.tomlin your project directory:
[[group]]
name = "myapp"
dir = "."
[[group.app]]
name = "server"
cmd = "go run main.go"- Run:
muxrun upThis starts the server app inside a tmux session named muxrun-myapp. Use muxrun down to stop it.
muxrun organizes applications into groups. Each group becomes a tmux session, and each app becomes a window within that session.
muxrun
├── Group A (tmux session)
│ ├── App 1 (tmux window)
│ └── App 2 (tmux window)
└── Group B (tmux session)
└── App 3 (tmux window)
- tmux 3.0+
muxrun looks for a config file in the following order:
--config / -cflag (explicit path, skips other lookup)muxrun.tomlin the current directory, then parent directories up to the filesystem root
[[group]]
name = "backend"
dir = "."
[[group.app]]
name = "api"
cmd = "go run main.go"[[group]]
name = "backend"
dir = "."
[[group.app]]
name = "api"
cmd = "go run main.go"
watch = { enabled = true, exclude = ["_test\\.go$"] }
[[group.app]]
name = "worker"
cmd = "go run worker.go"
restart = "on-failure"
[[group]]
name = "frontend"
dir = "./frontend"
[[group.app]]
name = "dev"
cmd = "npm run dev"See docs/config.md for the full field reference, watch and restart configuration, and validation rules.
When watch is enabled or restart = "on-failure" is set, muxrun starts a background daemon for the group. It restarts apps on file changes, and brings back an app that fails — backing off up to 30s and giving up after 5 consecutive failures, which muxrun ps reports as failed. An app you stop yourself with Ctrl-C stays stopped. The daemon starts with muxrun up and stops with muxrun down.
muxrun up # Start all groups
muxrun up backend # Start a specific group
muxrun up backend frontend # Start multiple groupsdown accepts the same arguments as up.
muxrun down # Stop all groups
muxrun down backend # Stop a specific groupWarning
Use muxrun down to stop sessions. Killing sessions directly with tmux kill-session may leave daemons running.
$ muxrun ps
GROUP APP STATUS PID DIR
backend api running 12345 /home/user/repo/cmd/api
backend worker running 12346 /home/user/repo/cmd/worker
frontend dev stopped - /home/user/repo/frontendmuxrun logs backend api # Show buffered output for an app
muxrun logs -f backend api # Stream output in real-time (Ctrl-C to stop)Tip
If you're familiar with tmux, each app runs in its own window inside a muxrun-<group> session — attach directly for full scrollback and search.
muxrun checkWhen dir is a relative path, it is resolved relative to the muxrun.toml location. Copy muxrun.toml into each worktree at creation time to treat each worktree as an independent environment.
[[group]]
name = "backend"
dir = "." # resolved relative to muxrun.toml location
[[group.app]]
name = "api"
cmd = "go run main.go"With the same group name across worktrees, running muxrun up always restarts the apps for the current worktree — even if the session is already running from a different one:
# working in worktree-A
cd ~/repo-worktree-A && muxrun up # muxrun-backend starts in A
# switch to worktree-B
cd ~/repo-worktree-B && muxrun up # same session restarts in BCopying muxrun.toml on worktree creation can be automated with a post-checkout hook or a worktree management tool like git-worktree-runner.
If you use Claude Code, you can install the muxrun plugin to author and operate muxrun.toml with skills.
Install
Run these inside Claude Code:
/plugin marketplace add tkuramot/muxrun
/plugin install muxrun@muxrun
The first command registers this repo as a marketplace; the second installs the muxrun plugin from it. Update later with /plugin marketplace update muxrun.
Skills
| Skill | Description |
|---|---|
/muxrun-init |
Analyze your project structure and generate a tailored muxrun.toml |
/muxrun-import-compose |
Convert an existing docker-compose.yml / Procfile into muxrun.toml |
/muxrun-doctor |
Diagnose tmux/daemon/PID/config issues in the local environment |
/muxrun-triage-failure |
Find failing apps via muxrun ps, fetch logs, and pinpoint the cause |
/muxrun-tail |
Follow an app's logs and surface anomalies (panics, 5xx, restart loops) |
/muxrun-perf |
Diagnose slow startup / restart storms / over-broad watch and tune exclude |
/muxrun-bisect |
Drive git bisect for runtime regressions reproducible only with the dev stack up |
muxrun supports tab completion for zsh. Subcommands, flags, and group names are completed dynamically.
eval "$(muxrun completion zsh)"To make it persistent, add the line to ~/.zshrc.
go test ./... # Unit tests
go test -tags=integration ./... # Integration tests
go test -tags=e2e ./... # E2E testsMIT