Each project is defined in a YAML file under the nux config directory:

$XDG_CONFIG_HOME/nux/projects/<name>.yaml

On most systems this is ~/.config/nux/projects/<name>.yaml. The file name (without .yaml) becomes the project name on the CLI.

Session name normalization#

The tmux session name is derived from the project name with these transformations:

  • Dots (.), colons (:), and spaces are replaced with underscores (_)
  • Leading dashes are stripped
  • Consecutive underscores are collapsed to one
  • Trailing underscores are stripped

For example, a file named my.cool-project.yaml produces the session name my_cool-project.

Fields#

root (string)#

Project root directory. Supports ~ expansion and {{var}} interpolation (see Custom variables). If relative, resolved against the first entry in project_dirs from global config. If omitted, defaults to <first_project_dirs>/<name>.

nux expands ~ (here and on window/pane root values) before invoking tmux so pane working directories are correct; tmux itself does not treat ~ as home in -c.

pane_init (list of strings)#

Commands run in every pane of this project before that pane’s own command, via tmux send-keys (same mechanism as global pane_init). Global pane_init entries run first; then project pane_init; then exports from session/window env; then the pane command.

Use this for per-project setup that should not apply to all nux sessions (for example a login shell or clear screen before each pane command).

default_shell (string)#

Shell passed to tmux as default-command for this session only (same as global default_shell). Supports ~ expansion and {{var}} interpolation.

If set on the project, it overrides the global value. If omitted, nux uses the global default_shell when that is set; otherwise tmux keeps its own default.

windows (list)#

Window definitions for the session. At least one window is required.

Each window object supports:

FieldRequiredDescription
nameyesWindow name shown in the tmux status bar
panesyesList of panes (at least one). Use panes: [""] for a bare shell.
rootnoWorking directory for this window. Relative paths resolve against the resolved project root. Paths with ~ are expanded to an absolute path before passing to tmux (tmux does not expand ~ in its -c directory flag).
layoutnoeven-horizontal, even-vertical, main-horizontal, main-vertical, tiled, or a custom tmux layout string
envnoEnvironment variables for all panes in this window. Merged with project-level env; window values take precedence. See Environment variables.

Panes#

Each pane may be:

  • A string (command shorthand) - e.g. - npm run dev
  • An object with optional fields:
FieldDescription
rootWorking directory override for this pane. Relative paths resolve against the window’s working directory; ~ is expanded.
commandCommand to run in this pane.

env (map)#

Environment variables applied to the tmux session via tmux set-environment. See Environment variables.

vars (map)#

Custom variables for {{var}} interpolation. See Custom variables.

on_start, on_stop, on_ready, on_detach (lists of strings)#

Shell commands run at lifecycle points for this project session. See Lifecycle hooks.

Example#

root: ~/projects/my-api

env:
  NODE_ENV: development
  PORT: "4000"

vars:
  log_level: debug

on_start:
  - docker compose up -d

on_stop:
  - docker compose stop

windows:
  - name: api
    panes:
      - npm run dev

  - name: workers
    layout: even-vertical
    panes:
      - npm run worker:email
      - npm run worker:jobs

  - name: db
    root: docker
    panes:
      - docker compose up postgres
      - command: docker compose logs -f postgres

Minimal configs#

For a single-command project, the simplest config is:

windows:
  - name: editor
    panes:
      - nvim

This creates one window with one pane running nvim, rooted at <project_dirs>/<name>.