xfetch has a theme system that separates visual appearance (colors, icons, layout) from module configuration, letting you switch looks without touching your module setup.
Themes operate at the config-loading layer, before any rendering or plugin execution. When you set "theme": "berlin" in config.jsonc, xfetch resolves the theme file, parses it, and merges three layers together:
config.jsonc (theme: "berlin", modules: [...])
|
v
1. Load default Config (hardcoded defaults)
|
v
2. Load user config.jsonc
|
v
3. Load theme/berlin.jsonc ← highest priority
|
v
4. Deep-merge: defaults → config.jsonc → theme
|
v
Final Config (used by renderer)
Starting from xfetch v0.2.0, the merge order gives the theme the highest priority:
| Layer | Source | Contains |
|---|---|---|
| 1. Core defaults | Hardcoded in config.rs | Default icons, colors, layout, modules |
| 2. User config | config.jsonc | modules, info_plugins, plus any visual overrides |
| 3. Theme file | themes/<name>.jsonc | colors, logo_color, layout, palette_style, show_colors, header_icons, footer_text, logo_path (no icons — they belong to the user config) |
A field in the theme file always wins over the same field in config.jsonc or defaults. This means the theme provides the final look, while config.jsonc handles module selection and plugin config.
Note: In v0.1.x the order was reversed (config.jsonc won over theme). If you're upgrading, you may need to move any visual overrides from config.jsonc into the theme file if you want the theme to control them.
The merge uses deep_merge() which works key-by-key:
{}: no-op — existing keys are preservedA theme file is a JSONC document containing only visual fields:
{
"layout": "section",
"show_colors": true,
"palette_style": "circles",
"logo_color": "Magenta",
"colors": {
"os": "Magenta",
"cpu": "Red",
"memory": "Yellow",
"disk": "Cyan",
"shell": "Green",
"wm": "Blue"
}
}
Themes declare only what they want to change; everything else (icons,
modules, fonts) comes from the user's config and the defaults. Icons
are not part of themes — they are a per-user font choice, so
exported and registry themes never include an icons block.
logo_color colors the ASCII logo (any color name listed
below).
| Field | Type | Description |
|---|---|---|
layout | string or null | Layout style: default, pacman, section, side-block, tree, compact, minimal, horizontal, bottom, box, line, dots, bottom-line |
colors | object | Per-module color mapping (labels + icons). Keys are module names, values are color names: Black, Red, Green, Yellow, Blue, Magenta, Cyan, White, Grey/Gray, and dark variants. Any module key works, including plugin:<name> entries. |
logo_color | string or null | Color for the ASCII logo (any color name listed above). |
logo_colors | array or null | Per-row logo colors: row i uses logo_colors[i % len], cycling for taller logos. Takes precedence over logo_color. Example: ["Red", "Yellow", "Green", "Cyan", "Blue", "Magenta"]. |
palette_style | string or null | Palette display: squares, circles, triangles, lines, dots |
show_colors | boolean | Show inline ANSI color swatches next to each module |
logo_path | string or null | Path to a logo file (ASCII, PNG, SVG) |
header_icons | array or null | Pac-Man layout top-border icons |
footer_text | string or null | Pac-Man layout bottom-border text |
When xfetch loads a config with "theme": "dracula", it searches in order:
/ or starts with ~, load it directly as a file path<name>.jsonc in ~/.config/xfetch/themes/If the theme is not found, the config loads without the theme (no error).
# List installed themes
xfetch theme list
# Activate a theme (writes "theme" field into config.jsonc)
xfetch theme set nord
# Remove a theme file
xfetch theme remove nord
# Export current visual config as a reusable theme file
xfetch theme export my-theme
xfetch theme export <name> captures the current runtime visual state (after all three layers are merged) and writes it to ~/.config/xfetch/themes/<name>.jsonc. This lets you share your look without exposing your module list or plugin config.
The exported file contains only visual fields: layout, colors, palette_style, header_icons, footer_text, logo_path, show_colors. Icons are never exported — they are a per-user font choice, filled from the defaults.
~/.config/xfetch/
config.jsonc # Modules, plugins, and theme reference
themes/
berlin.jsonc # Theme files: colors, layout
dracula.jsonc
nord.jsonc
catppuccin-mocha.jsonc
retro-pacman.jsonc
tree-compact.jsonc
In v0.1.x, config.jsonc won over the theme. If you had a detailed config with explicit colors/icons and then set a theme, nothing would visibly change.
To migrate to v0.2.0+:
xfetch theme export my-lookxfetch theme set my-lookcolors, icons, layout, etc.) from config.jsonc so the theme can fully control themmodules and info_plugins in config.jsoncconfig.jsoncconfig.jsoncxfetch theme export my-base