Shell Integration
Wire vmux into your shell rcfiles, auto-attach on login, and use vmux state to power your prompt.
vmux is just a CLI, so shell integration is whatever you want it to be. This page collects useful patterns for zsh and bash. Adapt to fish, nushell, etc. by translating syntax.
Shorter aliases
A handful of one-letter aliases usually pays off:
# ~/.zshrc or ~/.bashrc
alias v='vmux'
alias va='vmux attach'
alias vls='vmux ls'
alias vps='vmux state | jq' # human-readable state dumpvmux already auto-resolves the daemon and the default session, so va is a complete "open my main session" command from any shell.
Auto-attach on login
If you want your default interactive shell to drop straight into vmux when you log in or open a new terminal window, gate it on a few interactivity checks.
zsh
# ~/.zshrc — top of file, before plugins
if [[ -o interactive ]] \
&& [[ -z "$VMUX_SESSION" ]] \
&& [[ -z "$INSIDE_EMACS" ]] \
&& [[ -z "$VSCODE_INJECTION" ]] \
&& [[ "$TERM_PROGRAM" != "vscode" ]]; then
exec vmux attach -s default
fiThe VMUX_SESSION guard exists so panes the daemon spawns don't recursively re-enter vmux attach. Set the variable in server.environment of your config:
{
"schemaVersion": 1,
"server": {
"environment": { "VMUX_SESSION": "1" }
}
}bash
# ~/.bashrc
case $- in
*i*) ;;
*) return ;;
esac
if [[ -z "$VMUX_SESSION" ]] && [[ -z "$INSIDE_EMACS" ]]; then
exec vmux attach -s default
fiexec replaces the login shell's process with vmux attach, so you don't end up with two layered shells.
Detecting vmux in your prompt
Shell rcfiles that need to behave differently inside a vmux pane can check the same environment variable used by the auto-attach guard:
if [[ -n "$VMUX_SESSION" ]]; then
PROMPT="%F{cyan}vmux%f $PROMPT"
fiIf you only set the variable through server.environment, the daemon controls when it appears — convenient for distinguishing daemon-spawned shells from vmux pane launch shells you intentionally launched without the env override.
Status line
Power-line-style prompts can show the active session and pane count by calling vmux state once per prompt. Cache aggressively — vmux state is cheap (a single round trip over a Unix socket) but not free.
# Zsh prompt fragment, refreshed by precmd
__vmux_status() {
vmux state 2>/dev/null \
| jq -r 'select(.) | "\(.name) [\(.tabs | length) tabs · \(.tabs[0].panes | length) panes]"' \
|| true
}
RPROMPT='%F{8}$(__vmux_status)%f'If you really want sub-prompt latency, use openObservationConnection via a small Swift helper rather than vmux state — but for most setups, one syscall per prompt is unmeasurable.
fzf-driven session picker
# Pick a session from the list and attach to it
vmuxp() {
local choice
choice=$(vmux ls | fzf --select-1 --exit-0 | cut -f1)
if [[ -n "$choice" ]]; then
vmux attach -s "$choice"
fi
}Bind it to a key in zsh:
zle -N vmuxp
bindkey '^G' vmuxp # Ctrl+GPer-pane environment
vmux always sets these inside spawned shell panes (in addition to whatever you put in server.environment):
| Variable | Set by | Notes |
|---|---|---|
TERM | the daemon's PTY | Fixed at xterm-256color for shell panes. Override per-pane via pane launch --env TERM=… if needed. |
LINES, COLUMNS | the PTY at spawn time | Updated automatically by the kernel when the daemon resizes the pane on SIGWINCH. |
SHELL | inherited from server.shell | Same value used to spawn the process. |
anything in server.environment | config | Wins over inherited values with the same name. |
There is no built-in VMUX_PANE_ID or VMUX_SESSION_ID exposed inside the pane today. If you want one, set it explicitly with pane launch --env:
PANE=$(vmux pane create -s ci --role shell)
vmux pane launch "$PANE" --env "VMUX_PANE_ID=$PANE" -- "$SHELL"Programmable workflows
The pane subcommands are designed to be scripted. A common pattern is "pre-build a session layout with two panes, one running a watcher, one running a shell":
#!/usr/bin/env bash
set -euo pipefail
vmux session create -s dev >/dev/null || true
SHELL_PANE=$(vmux state -s dev | jq -r '.tabs[0].panes[0].paneID')
# Split: add a watcher pane to the right
WATCH=$(vmux pane create -s dev --from "$SHELL_PANE" --axis vertical --title "watch")
vmux pane launch "$WATCH" --cwd "$PWD" -- npm run watch
# Drop in interactively on the shell pane
vmux attach -s devSourcing this from ~/bin/dev-up and aliasing it to dev gives you a one-command project-startup workflow.
tmux co-existence
vmux and tmux have no shared state; you can run both side by side. A common setup is:
tmuxoutside, splitting your terminal into windows.vmux attachinside a single tmux pane for cross-device session continuity.
vmux does not assume it owns the terminal — it puts the terminal in raw mode on attach and restores the original termios on detach, so handing control back and forth is clean.
You should not alias tmux to vmux. They are different multiplexers with different keybinds and prefix keys; aliasing only causes confusion.
SSH agent forwarding inside vmux panes
Panes inherit the daemon's environment. Make sure vmuxd was started with the right SSH_AUTH_SOCK — for example, when vmuxAgent is in use:
# In your login shell, before vmux starts the daemon
export SSH_AUTH_SOCK="$HOME/.ssh/vmux-agent.sock"Then any pane that runs ssh, git, or scp will use vmuxAgent for signing — your iPhone holds the private key.
If you launch the daemon via launchd, set the variable in the plist's EnvironmentVariables block instead.
See also
vmux attach— how the client takes over your terminal.- Configuration file — the right place to set
server.environment. - vmuxAgent — companion SSH agent that pairs especially well with daemon-launched shells.