vmux
Appsvmux Daemon

Configuration File

Every supported key in the vmux config file, the search path, and the resolution order.

The vmux CLI is configured by a single JSON file. Both vmux and vmuxd read the same file. Each binary uses only the sections that apply to it, but the file's shape is shared.

Path resolution

The config path is resolved in this order; the first match wins:

  1. The --config PATH flag passed on the command line.
  2. The VMUX_CONFIG environment variable, if set and non-empty.
  3. $XDG_CONFIG_HOME/vmux/config.json, if XDG_CONFIG_HOME is set.
  4. ~/.config/vmux/config.json.
  5. ~/.vmux/config.json.

If none of these files exists, both binaries use built-in defaults — there is no error and no auto-creation. If a file is found at the resolved path but cannot be parsed, vmux and vmuxd exit 1 with vmux: invalidConfig(…) on stderr.

~ is expanded in any path-valued field using $HOME, so config files are portable between users on the same Mac.

File format

JSON. The schema is versioned. Currently only schemaVersion: 1 is accepted.

{
  "schemaVersion": 1,
  "shared": {
    "socketPath": "~/.vmux/run/vmuxd.sock"
  },
  "client": {
    "autoStartDaemon": true,
    "daemonExecutable": "/usr/local/bin/vmuxd",
    "connectRetryCount": 30,
    "connectRetryDelayMilliseconds": 100
  },
  "server": {
    "shell": "/bin/zsh",
    "cwd": "~/work",
    "environment": {
      "EDITOR": "nvim",
      "TERM": "xterm-256color"
    },
    "defaultSessionName": "main",
    "initialCols": 120,
    "initialRows": 36
  }
}

A missing top-level section is treated as if it were present and empty. Unknown keys are rejected by the JSON decoder — typos are caught at startup.

shared

Settings that apply to both client and server. Useful for the one setting that absolutely must agree on both sides: the socket path.

KeyTypeDefaultNotes
socketPathstring/tmp/vmux-<uid>.sockUnix socket path. ~ is expanded. Must not be empty.

If you set shared.socketPath and don't override it elsewhere, both vmux and vmuxd use it.

client

Settings used by the vmux CLI.

KeyTypeDefaultNotes
socketPathstringinherits shared.socketPath, then /tmp/vmux-<uid>.sockOverride the socket path for the client only.
autoStartDaemonbooltrueWhen the socket can't be reached (ENOENT or ECONNREFUSED), spawn vmuxd --daemonize. Set false for environments where you want the client to fail loudly instead.
daemonExecutablestringsibling of vmux, then vmuxd on PATH, then $VMUX_DAEMON_PATHPath to the vmuxd binary the client will spawn for auto-start. ~ expanded.
connectRetryCountint ≥ 030After auto-starting the daemon, how many times to retry connect(2) before giving up.
connectRetryDelayMillisecondsint ≥ 0100Delay between retries.

Auto-start is the most important client setting. If you manage the daemon yourself with launchd, turn it off so a stale or wrong-versioned binary cannot accidentally come up beside the managed one:

{
  "schemaVersion": 1,
  "client": {
    "autoStartDaemon": false
  }
}

server

Settings used by vmuxd.

KeyTypeDefaultNotes
socketPathstringinherits shared.socketPath, then /tmp/vmux-<uid>.sockOverride the socket path for the server only.
shellstring$SHELL, falls back to /bin/zshShell binary used when a new shell-role pane spawns. ~ expanded.
cwdstringinheritedWorking directory of new shells. ~ expanded.
environmentobject{}Extra environment variables added to every spawned shell.
defaultSessionNamestring"default"Session created on first attach when no name is given.
initialColsint > 080Columns of a freshly created session before any client attaches.
initialRowsint > 024Rows.

The environment object is merged into the spawned shell's environment after the daemon's own environ — your keys take precedence over inherited ones with the same name.

Resolution order

Within a single binary, the rule is "last writer wins" across these layers:

  1. Built-in defaults (e.g. socketPath = /tmp/vmux-<uid>.sock).
  2. shared.* from the config file.
  3. The binary's own section (client.* or server.*).
  4. Command-line flags (--socket, --shell, --cwd, --daemon).

So a typical override:

{
  "shared": { "socketPath": "/var/run/vmux.sock" },
  "server": { "shell": "/bin/bash" }
}

…can still be defeated for one invocation by passing --shell /bin/zsh on the vmuxd command line.

Validation is strict but minimal. Empty path strings, negative retry counts, non-positive initial sizes, and unsupported schemaVersion values raise invalidConfig(…).

Common recipes

Pin the socket to your home directory

The default /tmp path is fine for desktop use. If you want the socket on encrypted home-directory storage:

{
  "schemaVersion": 1,
  "shared": { "socketPath": "~/.vmux/run/vmuxd.sock" }
}

Make sure the parent directory exists — vmuxd does not create it.

Different daemons per project

Two configs, two daemons, no overlap:

# ~/.config/vmux/project-a.json
{
  "schemaVersion": 1,
  "shared": { "socketPath": "/tmp/vmux-projecta.sock" },
  "server": { "shell": "/bin/zsh", "defaultSessionName": "a" }
}
# ~/.config/vmux/project-b.json
{
  "schemaVersion": 1,
  "shared": { "socketPath": "/tmp/vmux-projectb.sock" },
  "server": { "shell": "/bin/bash", "defaultSessionName": "b" }
}

Then a per-shell wrapper:

alias vmux-a='VMUX_CONFIG=~/.config/vmux/project-a.json vmux'
alias vmux-b='VMUX_CONFIG=~/.config/vmux/project-b.json vmux'

vmux-a attach and vmux-b attach each auto-start their own daemon and never see each other's sessions.

Big initial size

For tiled-window setups where you know your real terminal is wide:

{
  "schemaVersion": 1,
  "server": { "initialCols": 200, "initialRows": 60 }
}

The first vmux attach from a real terminal still resizes the session to the client's actual size. This setting only matters when sessions are populated programmatically with pane create and pane launch before any client attaches.

Inject environment for every pane

{
  "schemaVersion": 1,
  "server": {
    "environment": {
      "EDITOR": "nvim",
      "PAGER": "less -R",
      "VMUX_FROM_DAEMON": "1"
    }
  }
}

Inside any shell pane: echo $VMUX_FROM_DAEMON prints 1. This is a clean way for shell rcfiles to detect they are running under vmuxd.

See also