wmux exposes a tmux session in the browser.
It runs a tmux control-mode client (tmux -CC), serves a small web UI, and lets you open a specific pane route like /p/0.
- Go
1.24+ tmuxinstalled and available inPATH
- Start (or create) a tmux session you want to control:
tmux new-session -d -s webui- Run wmux:
go run ./cmd/wmuxBy default it listens on 127.0.0.1:8080, targets session webui, and uses ghostty as the terminal renderer.
- Open pane links in your browser:
http://127.0.0.1:8080/api/state.htmlto list panes- Click a pane link (for example
/p/0) to open that pane terminal
Use a different tmux target session:
go run ./cmd/wmux --target-session devChange listen address:
go run ./cmd/wmux --listen 0.0.0.0:8080Use a custom tmux binary path:
go run ./cmd/wmux --tmux-bin /opt/homebrew/bin/tmuxAttach wmux to an existing tmux server/socket (for example Overmind):
go run ./cmd/wmux --target-session dev --tmux-socket-name overmindOr via explicit socket path:
go run ./cmd/wmux --target-session dev --tmux-socket-path /tmp/overmind.sock--listen(default127.0.0.1:8080)--target-session(defaultwebui; the only tmux session wmux manages and serves)--static-dir(optional override for web assets)--tmux-bin(defaulttmux)--tmux-socket-name(optional; maps totmux -L <name>)--tmux-socket-path(optional; maps totmux -S <path>)--term(defaultghostty; accepted values:ghostty,xterm)--restart-backoff(default500ms)--restart-max-backoff(default10s)
--tmux-socket-name and --tmux-socket-path are mutually exclusive.
Every flag can be provided by env var:
WMUX_LISTENWMUX_TARGET_SESSIONWMUX_STATIC_DIRWMUX_TMUX_BINWMUX_TMUX_SOCKET_NAMEWMUX_TMUX_SOCKET_PATHWMUX_TERMWMUX_RESTART_BACKOFFWMUX_RESTART_MAX_BACKOFF
Example:
WMUX_TARGET_SESSION=dev WMUX_LISTEN=127.0.0.1:9090 go run ./cmd/wmux- In default socket mode,
wmuxensures the configuredtarget-sessionexists (same behavior as before). - When
--tmux-socket-nameor--tmux-socket-pathis set,wmuxattaches to that tmux server and serves the existing target session without auto-creating it. wmuxalways runs on top of exactly one tmux session.- If the target socket/session is unavailable,
wmuxkeeps running and reportsunavailablein/api/state.jsonuntil tmux becomes reachable again. - Static web assets are embedded by default;
--static-diris only needed if you want to serve local asset files.
Run tests:
go test ./...Run headless end-to-end tests (real tmux + Playwright):
npm ci
npx playwright install chromium
npm run test:e2eThe E2E harness uses scripts/setup-e2e-tmux-fixture.sh to create a deterministic tmux session and pane worker.