Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration Overview

Jay is configured through a single TOML file located at:

~/.config/jay/config.toml

If this file does not exist, Jay uses built-in defaults that provide a reasonable starting configuration with common shortcuts, a US QWERTY keymap, and other sensible settings.

Warning

Once config.toml exists, the entire built-in default configuration is replaced – not merged. Even a completely empty file means no shortcuts, no startup actions, nothing. Always start from a full config rather than writing one from scratch.

Initializing the config

The easiest way to get started is to let Jay write the defaults for you:

~$ jay config init

This creates ~/.config/jay/config.toml pre-populated with the full default configuration. You can then edit it to suit your needs.

If you already have a config file and want to reset it:

~$ jay config init --overwrite

The old file will be backed up to config.toml.1 (or .2, .3, etc.) before being replaced.

Other config subcommands

Print the path to the config file:

~$ jay config path

Open the config directory in your file manager:

~$ jay config open-dir

Reloading the configuration

By default, Jay does not automatically reload config.toml when it changes on disk. To apply changes, trigger a reload manually:

  • Press alt-shift-r (the default shortcut), or
  • Use the reload-config-toml action in any other action context (e.g. a named action or a window rule).

Most settings take effect immediately on reload. A few exceptions (like log-level, explicit-sync, and initial drm-devices settings) only apply at compositor startup.

Automatic reloading

To have Jay watch config.toml for changes and reload automatically, add:

auto-reload = true

When enabled, Jay uses inotify to monitor the config file and its parent directories. Changes are debounced — the config is reloaded 400 ms after the last write, so rapid successive saves don’t cause multiple reloads. If the file contents haven’t actually changed, the reload is skipped.

Setting auto-reload = false will stop the watcher. Removing the key entirely leaves the watcher state unchanged (if it was running, it keeps running until the compositor restarts).

Named actions

You can define reusable actions in the [actions] table and reference them anywhere an action is accepted by prefixing the name with $:

[actions]
launch-terminal = { type = "exec", exec = "alacritty" }
launch-browser = { type = "exec", exec = "firefox" }

[shortcuts]
alt-Return = "$launch-terminal"
alt-b = "$launch-browser"

Named actions can reference other named actions. The max-action-depth setting controls the maximum recursion depth to prevent infinite loops (default: 16):

max-action-depth = 32

Composable actions

Anywhere an action is accepted, you can use an array of actions instead. This applies to shortcuts, startup hooks, named actions, and any other action field:

[shortcuts]
alt-q = [
    { type = "exec", exec = ["notify-send", "Goodbye!"] },
    "quit",
]

Advanced: shared library configuration

For users who need programmatic configuration beyond what TOML offers, Jay also supports configuration via a compiled Rust shared library using the jay-config crate. This is an advanced option – the TOML config is sufficient for the vast majority of use cases.

Full specification

This book covers the most common configuration options with explanations and examples. For an exhaustive listing of every field, type, and action, see the auto-generated specification.