App Theming
Noctalia can render the resolved theme colors into external app config files whenever the palette changes. This lets terminals, editors, browsers, launchers, and other apps follow the same colors as the shell.
Templates always render the variant selected by [theme].mode, never shell_mode, so pinning Noctalia to dark keeps your apps on whatever mode resolves to.
To rerender enabled templates for the current palette without changing the theme, use Media & UI → Theme.
Built-in Templates
Section titled “Built-in Templates”Built-in templates ship with Noctalia. Enable the built-in catalog, then opt in to the template IDs you want:
[theme.templates]enable_builtin_templates = truebuiltin_ids = [] # opt-in; run: noctalia theme --list-templatesbuiltin_ids selects which shipped templates run. An empty array means no built-in templates are applied.
In Settings → Templates, click a built-in template’s external-link button (tooltip: Documentation) to open its setup guide in your default browser. Opening the guide does not enable or disable the template.
Hover highlights the external-link button separately from its template tile, including on enabled templates. The entry stays highlighted while the pointer is over its link button, with a continuous highlight when moving between them. The link glyph follows the tile’s text color when hovering or pressing the surrounding entry. Link tooltips are positioned at the link button rather than the center of the tile.
Disabling a built-in template removes its generated Noctalia theme file and undoes any Noctalia-owned include or theme selection that the template added to the application’s config. Disabling enable_builtin_templates performs the same cleanup for every selected built-in template.
Application configs must be writable for Noctalia to remove those integrations. For declaratively managed configs such as Home Manager symlinks into the Nix store, remove the Noctalia include or theme selection from the declarative source.
For Alacritty, foot, and kitty, the built-in template can create a user config that includes the Noctalia theme. These applications stop reading their other config locations once a user config exists, so the template skips this step and logs a warning when another config is present, for example /etc/xdg/foot/foot.ini written by the NixOS programs.foot.settings option. Add the include named in the warning to that config to apply the Noctalia theme.
List available built-in and configured template IDs:
noctalia theme --list-templatesCompositor Configuration
Section titled “Compositor Configuration”Compositor templates generate their theme files and automatically add an include or theme selection to an existing, writable user config. They never create a missing primary compositor config: doing so could hide the system, packaged, or custom config that your compositor currently uses.
If the primary user config is absent, the generated theme is still available. A dismissible banner in Settings explains the problem and the manual setup. Long messages scroll inside the banner. The instructions are also logged, including when Settings is closed. Add the include or theme selection to the config your compositor actually loads, then reapply the template to retry. For a read-only or declaratively managed config, make that change in its source, such as your Home Manager configuration.
The examples below use the default config directory and an example home directory. Replace /home/you/.config with your resolved $XDG_CONFIG_HOME, or $HOME/.config when it is unset. Config files do not necessarily expand environment variables; use the resolved path. Absolute paths also avoid resolving an include beside a system or custom config instead of beside the generated theme.
| Compositor | Primary user config, relative to the config directory | Generated theme, relative to the config directory | Manual integration |
|---|---|---|---|
| Umbriel | umbriel/config.toml | umbriel/noctalia.toml | Add the path to [include.optional].files, as shown below. |
| Niri | niri/config.kdl | niri/noctalia.kdl | include "/home/you/.config/niri/noctalia.kdl" |
| Sway | sway/config | sway/noctalia | include "/home/you/.config/sway/noctalia" |
| Scroll | scroll/config | scroll/noctalia | include "/home/you/.config/scroll/noctalia" |
| Mango | mango/config.conf | mango/noctalia.conf | source=/home/you/.config/mango/noctalia.conf |
| Hyprland (Hyprlang) | hypr/hyprland.conf | hypr/noctalia.conf | source = /home/you/.config/hypr/noctalia.conf |
| Hyprland (Lua) | hypr/hyprland.lua | hypr/noctalia.lua | dofile("/home/you/.config/hypr/noctalia.lua").apply_theme() |
| Labwc | labwc/rc.xml | labwc/noctalia.conf | Select the noctalia theme as shown below. |
For Umbriel, append the generated path to the existing files array, or add this section if it is absent:
[include.optional]files = ["/home/you/.config/umbriel/noctalia.toml"]For Labwc, the template also installs the theme in ${XDG_DATA_HOME:-$HOME/.local/share}/themes/noctalia/openbox-3/themerc. Set the name inside the existing <theme> element, or add this element inside <labwc_config>:
<theme> <name>noctalia</name></theme>If an earlier Noctalia version created a primary config containing only its theme integration, inspect that file before moving it aside manually. Moving it aside lets the compositor discover its previous config again. Preserve any settings you added, then add the theme integration to the config you intend to use. Noctalia does not delete primary configs automatically.
Community Templates
Section titled “Community Templates”Community templates are fetched from https://api.noctalia.dev/templates and cached locally:
[theme.templates]enable_community_templates = truecommunity_ids = [] # opt-in; fetched from api.noctalia.dev/templatescommunity_ids selects which community templates run. In Settings → Templates, enable community templates and use Browse Templates to search and filter the catalog (by category or enabled-only). Metadata and files are stored in ~/.local/state/noctalia/community-templates/ (honoring NOCTALIA_STATE_HOME, then XDG_STATE_HOME).
Setup instructions for each community template live in its README.md in the community-templates repository. Template tiles show an external-link button with the Readme tooltip; click it to open those instructions in your default browser without changing the template’s enabled state. With a template selected in the catalog grid, F1 opens its README.
Cached community template files are treated as editable local copies. Sync updates files only while their content still matches the last Noctalia-written md5; local edits are preserved until you delete the edited cached file.
Disabling a community template, or disabling enable_community_templates, runs the undo_hook of each entry in its cached template.toml, so the template can remove an include or theme selection its post_hook added. A failed undo hook is retried on the next theme application. Templates without an undo_hook leave their files in place.
Community template discovery and updates require network access unless the selected template is already cached. shell.offline_mode prevents outgoing HTTP requests, including community template requests.
Firefox
Section titled “Firefox”Firefox is themed through the Pywalfox browser extension and the pywalfox community template. The template writes a Pywal-compatible colors.json and requests the built-in firefox-theme post-action. Noctalia itself acts as the extension’s native-messaging host, so no python-pywalfox package or separate daemon is needed.
On the first theme application, Noctalia installs a user-local native-messaging manifest at ~/.mozilla/native-messaging-hosts/pywalfox.json that points at the noctalia binary. Restart Firefox once after that so it picks up the host. Noctalia refreshes manifests it owns when the executable path changes, including across NixOS store generations; manifests installed by other Pywalfox hosts are left untouched.
Each open Firefox profile runs its own host process, and theme pushes reach all of them. If only some profiles update after upgrading Noctalia, restart each profile once.
The host can also be driven by hand:
noctalia firefox-theme install # write the native-messaging manifestnoctalia firefox-theme update # push colors to all running profile hostsnoctalia firefox-theme uninstall # remove the Noctalia-owned manifestnoctalia firefox-theme --helpTo migrate from the Python Pywalfox host, uninstall python-pywalfox if nothing else needs it. If ~/.mozilla/native-messaging-hosts/pywalfox.json still points at the Python host, remove it, since Noctalia does not overwrite a foreign manifest. Then enable pywalfox, re-apply templates, and restart Firefox.
User Templates
Section titled “User Templates”User templates are declared directly in Noctalia config:
[theme.templates.user.my_app]input_path = "$XDG_CONFIG_HOME/noctalia/templates/my-app.css"output_path = "$XDG_CONFIG_HOME/my-app/theme.css"post_hook = "my-app --reload-theme"Defining [theme.templates.user.<id>] enables that user template. Set enabled = false on an entry to keep it available but inactive.
Relative paths resolve from the Noctalia config directory. A leading $XDG_CONFIG_HOME, $XDG_DATA_HOME, $XDG_STATE_HOME, or $XDG_CACHE_HOME token is expanded using the XDG base directory defaults when the matching environment variable is not set.
User template entries support the same fields documented in Template Entries, including input_path_modes, output_path_dynamic, colors_to_compare, compare_to, pre_hook, post_hook, post_action, and index.
Example: Terminal Escape Sequences
Section titled “Example: Terminal Escape Sequences”Terminals that cannot reload their config, such as foot, can be recolored live by writing OSC escape sequences to every open terminal. The sequences work in most terminals (kitty, WezTerm, foot, Alacritty, GNOME Terminal, Konsole, and others) and match the colors of the built-in foot template.
Add the user template:
[theme.templates.user.terminal-sequences]input_path = "~/.config/noctalia/templates/terminal-sequences"output_path = "~/.cache/terminal-sequences"post_hook = "tee /dev/pts/[0-9]* < ~/.cache/terminal-sequences"Then create its input file:
mkdir -p ~/.config/noctalia/templates{ printf '\033]10;{{colors.terminal_foreground.default.hex}}\007' printf '\033]11;{{colors.terminal_background.default.hex}}\007'
printf '\033]4;0;{{colors.terminal_normal_black.default.hex}}\007' printf '\033]4;1;{{colors.terminal_normal_red.default.hex}}\007' printf '\033]4;2;{{colors.terminal_normal_green.default.hex}}\007' printf '\033]4;3;{{colors.terminal_normal_yellow.default.hex}}\007' printf '\033]4;4;{{colors.terminal_normal_blue.default.hex}}\007' printf '\033]4;5;{{colors.terminal_normal_magenta.default.hex}}\007' printf '\033]4;6;{{colors.terminal_normal_cyan.default.hex}}\007' printf '\033]4;7;{{colors.terminal_normal_white.default.hex}}\007'
printf '\033]4;8;{{colors.terminal_bright_black.default.hex}}\007' printf '\033]4;9;{{colors.terminal_bright_red.default.hex}}\007' printf '\033]4;10;{{colors.terminal_bright_green.default.hex}}\007' printf '\033]4;11;{{colors.terminal_bright_yellow.default.hex}}\007' printf '\033]4;12;{{colors.terminal_bright_blue.default.hex}}\007' printf '\033]4;13;{{colors.terminal_bright_magenta.default.hex}}\007' printf '\033]4;14;{{colors.terminal_bright_cyan.default.hex}}\007' printf '\033]4;15;{{colors.terminal_bright_white.default.hex}}\007'
printf '\033]19;{{colors.terminal_selection_fg.default.hex}}\007' printf '\033]17;{{colors.terminal_selection_bg.default.hex}}\007' printf '\033]12;{{colors.terminal_cursor.default.hex}}\007'} > ~/.config/noctalia/templates/terminal-sequencesThe hook only recolors terminals that are already open. To color new terminals too, without the built-in foot template, add this to ~/.bashrc:
[[ -f ~/.cache/terminal-sequences ]] && cat ~/.cache/terminal-sequencesConfig Location
Section titled “Config Location”Put dotfile-managed templates in ~/.config/noctalia/*.toml:
[theme.templates]enable_builtin_templates = trueenable_community_templates = truebuiltin_ids = []community_ids = []
[theme.templates.user.my_app]input_path = "$XDG_CONFIG_HOME/noctalia/templates/my-app.css"output_path = "$XDG_CONFIG_HOME/my-app/theme.css"The same tables are valid in settings.toml because it is the final config overlay, but that file is managed by the GUI and runtime actions. Use ~/.config/noctalia/ for templates you want to keep in dotfiles.
Template Reference
Section titled “Template Reference”For template syntax, color tokens, filters, hooks, dynamic output paths, and CLI rendering, see the Template Reference.