Configuration
March 2, 2026 · View on GitHub
Nunchux uses an INI-style configuration file with typed sections.
Config Location
Nunchux searches for config in this order:
- Local
.nunchuxrc- searches upward from current directory (like.gitignore) NUNCHUX_RC_FILE- environment variable override~/.config/nunchux/config- user config
This allows per-project configs. Place a .nunchuxrc in your project root to have
project-specific apps and taskrunners appear when you're in that directory.
Config Format
Sections use [type:name] syntax to declare their type explicitly:
[settings]
popup_width = 90%
[app:lazygit]
cmd = lazygit
[menu:system]
desc = System tools
[app:system/htop]
cmd = htop
[dirbrowser:configs]
directory = ~/.config
[taskrunner:just]
enabled = true
Settings
The [settings] section controls global behavior:
| Setting | Default | Description |
|---|---|---|
icon_running | ● | Icon shown next to running apps |
icon_stopped | ○ | Icon shown next to stopped apps |
menu_width | 60% | Width of the app selector menu |
menu_height | 50% | Height of the app selector menu |
popup_width | 90% | Default width for app popups |
popup_height | 90% | Default height for app popups |
max_popup_width | (none) | Maximum popup width in columns |
max_popup_height | (none) | Maximum popup height in rows |
primary_key | enter | Key for primary action |
secondary_key | ctrl-o | Key for secondary action |
primary_action | popup | Default primary action (see below) |
secondary_action | window | Default secondary action (see below) |
fzf_prompt | | Prompt shown in fzf |
fzf_pointer | ▶ | Pointer for selected item |
fzf_border | rounded | Border style (rounded, sharp, double, etc.) |
label | nunchux | Label shown in borders and popup titles |
fzf_colors | (see below) | fzf color scheme |
cache_ttl | 60 | Seconds before cache refresh (0 to disable) |
exclude_patterns | (see below) | Patterns to exclude from directory browsers |
show_cwd | true | Show current working directory in menu label |
toggle_shortcuts_key | ctrl-/ | Key to toggle shortcut column visibility |
Dimensions
Dimensions can be specified as percentages or absolute values:
[settings]
menu_width = 60 # 60 columns (use 60% for percentage)
menu_height = 50% # 50% of terminal height
popup_width = 90%
popup_height = 90%
max_popup_width = 160 # Cap app popups at 160 columns
max_popup_height = 50 # Cap app popups at 50 rows
On large screens, percentage-based dimensions can result in overly large app popups. Use max_popup_* settings to cap dimensions. The percentage is calculated against the current tmux window size, then clamped to the maximum if exceeded. This applies to app popups and dirbrowser popups, not to the menu itself.
Action Types
| Action | Description |
|---|---|
popup | Open in a tmux popup overlay |
window | Open in a new tmux window with focus |
background_window | Open in a new tmux window, stay in current pane |
pane_right | Open in a pane to the right |
pane_left | Open in a pane to the left |
pane_above | Open in a pane above |
pane_below | Open in a pane below |
Different item types have different default actions:
| Type | Primary Default | Secondary Default |
|---|---|---|
| Apps | popup | window |
| Taskrunners | window | background_window |
| Dirbrowsers | popup | window |
You can override the default actions globally in [settings], or per-item.
Direct Action Shortcuts
In addition to primary/secondary keys, you can configure dedicated shortcuts that always trigger a specific action:
| Setting | Description |
|---|---|
popup_key | Always open in popup |
window_key | Always open in window |
background_window_key | Always open in background window |
pane_right_key | Always open in pane to the right |
pane_left_key | Always open in pane to the left |
pane_above_key | Always open in pane above |
pane_below_key | Always open in pane below |
These are disabled by default (empty). Enable the ones you want:
[settings]
popup_key = ctrl-p
window_key = ctrl-w
background_window_key = ctrl-b
pane_right_key = ctrl-right
pane_left_key = ctrl-left
pane_above_key = ctrl-up
pane_below_key = ctrl-down
When configured, these shortcuts appear in the help header (toggle with Ctrl-/).
These keys are reserved and cannot be used as item shortcuts.
Action Menu
Press Ctrl-J (default) to open a menu for selecting how to launch the highlighted item. This provides quick access to all launch modes without configuring individual shortcuts.
| Setting | Default | Description |
|---|---|---|
action_menu_key | ctrl-j | Key to open action selection menu |
Set to empty to disable:
[settings]
action_menu_key =
Note: ctrl-m cannot be used as it's equivalent to Enter in terminals.
Default fzf_colors
fg+:white:bold,bg+:-1,hl:cyan,hl+:cyan:bold,pointer:cyan,marker:green,header:gray,border:gray
Default exclude_patterns
.git, node_modules, Cache, cache, .cache, GPUCache, CachedData, blob_storage,
Code Cache, Session Storage, Local Storage, IndexedDB, databases, *.db, *.db-*,
*.sqlite*, *.log, *.png, *.jpg, *.jpeg, *.gif, *.ico, *.webp, *.woff*, *.ttf,
*.lock, lock, *.pid
Patterns starting with * match filenames. Others exclude both directories and files with that name.
Keyboard Shortcuts
Assign keyboard shortcuts to launch items directly from the menu without navigating:
[app:lazygit]
cmd = lazygit
shortcut = ctrl-g
[menu:system]
shortcut = ctrl-s
[dirbrowser:configs]
directory = ~/.config
shortcut = ctrl-c
Press the shortcut key while the menu is open to launch the item immediately.
Viewing Shortcuts
Press Ctrl-/ (configurable via toggle_shortcuts_key) to toggle the shortcut column visibility. When shown, shortcuts appear on the left:
[ctrl-g] │ ○ lazygit Git TUI
│ ○ htop Process viewer
[ctrl-s] │ ▸ system System tools
Reserved Keys
These keys cannot be used as shortcuts:
enter,esc,ctrl-x- Used by fzf/nunchux/- Used for jump mode- Your configured
primary_keyandsecondary_key
Validation
Nunchux validates shortcuts at startup:
- Invalid keys - Keys not supported by fzf (e.g.,
shift-enter) - Reserved keys - Keys used by nunchux itself
- Duplicates - Same shortcut assigned to multiple items
If any shortcuts are invalid, an error screen shows all issues.
Supported Keys
Common shortcut keys: ctrl-a through ctrl-z, alt-a through alt-z, f1 through f12, tab, space.
Note: shift-enter and ctrl-enter are not supported by most terminals.
Window Switcher
Type > in the menu to switch to tmux window/session mode. Configure with [switcher]:
[switcher]
preview = true # Show preview of window content (default: true)
prefix = > # Character to activate switcher (default: >)
| Option | Default | Description |
|---|---|---|
preview | true | Show live preview of window content below the list |
prefix | > | Character prefix that activates window switching mode |
When preview is enabled, you'll see the bottom portion of each window's content as you navigate.
Ordering
Use [order] sections to control item order declaratively:
[order]
lazygit
config
taskrunner:just
system
taskrunner:npm
docker
htop
# Items not listed appear alphabetically after these
Items are displayed in the order listed. Unlisted items are appended alphabetically.
Taskrunners use the taskrunner:name format (e.g., taskrunner:just). All tasks for that runner appear at that position. Individual tasks within each runner remain in their discovery order.
Submenu Ordering
Control item order within submenus:
[order:system]
duf
ncdu
btop
journalctl
Ordering Notes
- Items not listed in
[order]appear alphabetically after ordered items - Non-existent items in
[order]sections are silently ignored - Apps, dirbrowsers, submenus, and taskrunners can all be listed in
[order]
Apps
Use [app:name] to define an app:
[app:lazygit]
cmd = lazygit
desc = Git TUI
width = 95
height = 95
status = n=$(git status -s 2>/dev/null | wc -l); [[ $n -gt 0 ]] && echo "($n changed)"
on_exit = echo "done"
| Option | Required | Description |
|---|---|---|
cmd | Yes | Command to run |
desc | No | Description shown in menu |
width | No | Popup width (overrides global) |
height | No | Popup height (overrides global) |
status | No | Shell command for dynamic status text |
status_script | No | Path to script for complex status |
on_exit | No | Command to run after app exits |
primary_action | No | Override primary action for this app |
secondary_action | No | Override secondary action for this app |
shortcut | No | Keyboard shortcut (e.g., ctrl-g) |
Variables in cmd and on_exit
| Variable | Description |
|---|---|
{pane_id} | Parent tmux pane ID (for tmux send-keys -t {pane_id}) |
{tmp} | Fresh temp file path (for passing data to on_exit) |
{dir} | Starting directory |
Submenus
Use [menu:name] for the parent menu and [app:parent/child] for children:
[menu:system]
desc = System tools
status = echo "load: $(cut -d' ' -f1 /proc/loadavg)"
[app:system/htop]
cmd = htop
desc = Process viewer
[app:system/ncdu]
cmd = ncdu
desc = Disk usage
The [menu:system] appears in the main menu. Selecting it opens a submenu with its children.
Menu sections support:
status- Dynamic status textdesc- Descriptioncache_ttl- Override cache duration for this submenushortcut- Keyboard shortcut (e.g.,ctrl-s)order- Explicit sort order (lower = first)
Directory Browsers
Use [dirbrowser:name] to create a file browser:
[dirbrowser:configs]
directory = ~/.config
depth = 2
sort = modified-folder
sort_direction = descending
glob = *.conf
cache_ttl = 300
width = 90 # Use 90% for 90%. 90 will be columns
height = 80
| Option | Default | Description |
|---|---|---|
directory | (required) | Path to browse |
depth | 1 | How many levels deep to search |
sort | modified | Sort mode (see below) |
sort_direction | descending | ascending or descending |
glob | (none) | Filter files by pattern (e.g., *.conf) |
cache_ttl | 300 | Cache duration in seconds |
width | 90 | Popup width (percentage or columns) |
height | 80 | Popup height (percentage or columns) |
primary_action | popup | Override primary action |
secondary_action | window | Override secondary action |
shortcut | (none) | Keyboard shortcut (e.g., ctrl-c) |
Sort Modes
| Mode | Description |
|---|---|
modified | Files sorted by modification time |
modified-folder | Folders grouped by most recent file, then files by recency |
alphabetical | Sorted by folder/filename |
Selected files open in $VISUAL, $EDITOR, or nvim (first available).
Task Runners
Use [taskrunner:name] to enable task runners for project automation:
[taskrunner:just]
enabled = true
icon = 🤖
[taskrunner:npm]
enabled = true
icon = 📦
[taskrunner:task]
enabled = false
Task runners are disabled by default and must be explicitly enabled.
| Option | Default | Description |
|---|---|---|
enabled | false | Whether to show this task runner |
icon | (runner default) | Icon shown in divider line |
label | (runner name) | Label shown in menu |
primary_action | window | Override primary action |
secondary_action | background_window | Override secondary action |
Available Task Runners
| Name | Description | Detection |
|---|---|---|
just | just command runner | justfile in current directory |
npm | npm scripts | package.json with scripts |
task | Task runner | Taskfile.yml in current directory |
Taskrunner Window Behavior
Task runner commands run in dedicated tmux windows (not popups by default):
- Primary action (Enter): Runs task and switches to its window
- Secondary action (Ctrl-O): Runs task in background, stay in current pane
- Ctrl-X: Kills the task's window
Window titles show the task name and status:
just » build 🔄(running)just » build ✅(success)just » build ❌(failed)
Re-running the same task reuses its existing window instead of creating a new one.
You can change this behavior per-taskrunner:
[taskrunner:npm]
enabled = true
primary_action = popup # Run npm tasks in a popup instead
Taskrunner Status Icons
Use the [taskrunner] section (without a name) to configure status icons globally:
[taskrunner]
icon_running = 🔄
icon_success = ✅
icon_failed = ❌
| Option | Default | Description |
|---|---|---|
icon_running | 🔄 | Icon while task is running |
icon_success | ✅ | Icon when task completes successfully |
icon_failed | ❌ | Icon when task fails |
This is useful if you prefer icons from the nerd font you are using.