cmux reads your existing ~/.config/ghostty/config. you don't write a separate config for it — but there are specific things it cares about, a few gotchas that will silently break things, and one setting that makes the whole notification system work (or not).
here's everything that matters.
how cmux actually reads your config (dual-layer)
cmux has two config layers running at the same time:
layer 1: swift parser (GhosttyConfig.swift) — reads exactly 15 keys. used for UI chrome, sidebar styling, font selection, split dividers, opacity. this is cmux's own parser, independent of Ghostty.
layer 2: libghostty (C library) — reads ALL Ghostty config keys. handles actual terminal rendering, runtime config updates, the full feature set. this is the same engine Ghostty.app uses.
the split matters because layer 1 has quirks (see: font-family below) that layer 2 doesn't.
config file search order
cmux checks all four locations in order. later values override earlier ones:
~/.config/ghostty/config ← first
~/.config/ghostty/config.ghostty
~/Library/Application Support/com.mitchellh.ghostty/config
~/Library/Application Support/com.mitchellh.ghostty/config.ghostty ← lastthe 15 keys cmux's swift parser reads
everything else is handled by libghostty. these are the keys that affect cmux's UI chrome directly:
| key | default | what cmux uses it for |
|---|---|---|
font-family | "Menlo" | sidebar text, UI chrome font |
font-size | 12 | UI font sizing |
theme | nil | theme file loading + color extraction |
working-directory | nil | initial directory |
scrollback-limit | 10000 | scrollback buffer size |
background | #272822 | window/chrome background |
background-opacity | 1.0 | chrome transparency |
foreground | #fdfff1 | text color |
cursor-color | #c0c1b5 | cursor rendering |
cursor-text | #8d8e82 | text under cursor |
selection-background | #57584f | selection highlight |
selection-foreground | #fdfff1 | selected text color |
palette | (none) | 16-color ANSI palette |
unfocused-split-opacity | 0.7 | dimming of unfocused splits |
unfocused-split-fill | nil | dimming overlay color |
split-divider-color | nil | split border color (auto-calculated if nil) |
split divider auto-calculation (when split-divider-color is not set):
light backgrounds (luminance > 0.5): darken by 8%
dark backgrounds: darken by 40%
luminance formula: 0.299R + 0.587G + 0.114B
the gotchas
font-family: use exactly one line
this is the single most important compatibility detail.
cmux's swift parser does this on each font-family line:
case "font-family":
fontFamily = value // OVERWRITES — takes LAST valueghostty's C library chains multiple font-family values (first = primary, rest = fallbacks).
so if your config has:
font-family = JetBrains Mono ← ghostty uses this (primary)
font-family = Fira Code ← ghostty fallback #1
font-family = Hack ← ghostty fallback #2, cmux uses this!ghostty renders with JetBrains Mono. cmux's sidebar uses Hack for font calculations. they're different.
fix: use a single `font-family` line.
font-family = JetBrains Monodesktop-notifications: must be true
cmux's entire notification system depends on OSC 9/99/777 escape sequences. the blue rings, sidebar badges, Cmd+Shift+U to jump to latest unread — all of it.
if desktop-notifications = false, cmux never detects when AI agents need your attention.
desktop-notifications = trueset it and forget it.
keybind precedence: cmux wins
cmux intercepts keybinds at the AppKit level before they reach libghostty. Cmd+N, Cmd+T, Cmd+1-8, etc. all take precedence over anything in your Ghostty config. you cannot override cmux's shortcuts from ~/.config/ghostty/config.
shell integration layering
cmux has its own .zshenv that restores ZDOTDIR after Ghostty's shell integration injection. if you have HISTFILE path issues or zsh wrapper recursion, this is why.
the flow:
GhosttyKit sets ZDOTDIR to the Ghostty integration directory
cmux .zshenv restores from $GHOSTTY_ZSH_ZDOTDIR or $CMUX_ZSH_ZDOTDIR
your /etc/zshrc and ~/.zprofile load normally
you don't need to do anything here — just know it's happening so you don't fight it.
themes: paired light/dark
cmux supports the same paired theme syntax as Ghostty:
theme = light:Catppuccin Latte,dark:Catppuccin Mochaauto-switches based on NSAppearance (macOS light/dark mode). cmux monitors appearance changes at runtime and invalidates the config cache when you switch.
theme search paths (6 locations, in order):
$GHOSTTY_RESOURCES_DIR/themes/{name}
app bundle: ghostty/themes/{name}
$XDG_DATA_DIRS/ghostty/themes/{name}
/Applications/Ghostty.app/Contents/Resources/ghostty/themes/{name}
~/.config/ghostty/themes/{name}
~/Library/Application Support/com.mitchellh.ghostty/themes/{name}
builtin alias expansion:
Solarized Light also tries iTerm2 Solarized Light
Solarized Dark also tries iTerm2 Solarized Dark
Builtin X prefix is stripped and retried
environment variables cmux sets
useful to know if you're debugging shell behavior:
GHOSTTY_RESOURCES_DIR → bundled Ghostty resources (themes, terminfo)
XDG_DATA_DIRS → appended for theme search paths
TERM → "xterm-ghostty"
TERM_PROGRAM → "ghostty"the full config (copy-paste ready)
this works in both Ghostty.app and cmux. every setting verified against the source.
# dual-use: ghostty.app + cmux
# [cmux] = read by swift parser for UI chrome
# everything else = handled by libghostty
# [cmux] theme — auto-switches light/dark
theme = light:Catppuccin Latte,dark:Catppuccin Mocha
# [cmux] font — single font-family line (critical)
font-family = JetBrains Mono
font-size = 16
# font styling (C library only — safe to use)
font-style = Medium
font-thicken = true
font-thicken-strength = 200
adjust-cell-height = 2
# cursor
cursor-style = bar
cursor-style-blink = true
cursor-click-to-move = true
# [cmux] background
background-opacity = 1
# [cmux] splits
unfocused-split-opacity = 0.75
# split-divider-color auto-calculated from background luminance if unset
# [cmux] scrollback
scrollback-limit = 20000000
# [cmux] CRITICAL: powers notification rings + sidebar badges
desktop-notifications = true
# shell integration
shell-integration = detect
shell-integration-features = cursor,sudo,title,ssh-env,ssh-terminfo,path
term = xterm-ghostty
# macos
macos-option-as-alt = true
copy-on-select = clipboard
clipboard-write = allowquick checklist
single font-family line only
desktop-notifications = true (non-negotiable for notifications)
paired theme = light:X,dark:Y for auto light/dark switching
don't try to override cmux shortcuts via ghostty keybinds — they won't apply
if shell behavior is weird around ZDOTDIR, check $GHOSTTY_ZSH_ZDOTDIR — cmux is managing it