Skip to content

Latest commit

 

History

History
184 lines (146 loc) · 8.51 KB

File metadata and controls

184 lines (146 loc) · 8.51 KB

Themes Guide

xfetch has a theme system that separates visual appearance (colors, icons, layout) from module configuration, letting you switch looks without touching your module setup.

Architecture

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)

Merge Order (last wins)

Starting from xfetch v0.2.0, the merge order gives the theme the highest priority:

LayerSourceContains
1. Core defaultsHardcoded in config.rsDefault icons, colors, layout, modules
2. User configconfig.jsoncmodules, info_plugins, plus any visual overrides
3. Theme filethemes/<name>.jsonccolors, 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.

Merge details

The merge uses deep_merge() which works key-by-key:

  • Objects: merged recursively — each key is resolved independently
  • Strings, numbers, booleans: overlay replaces base
  • Empty strings: an empty string does not override a non-empty string (prevents themes from accidentally clearing icons)
  • Empty objects {}: no-op — existing keys are preserved

Theme File Format

A 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).

Supported Fields

FieldTypeDescription
layoutstring or nullLayout style: default, pacman, section, side-block, tree, compact, minimal, horizontal, bottom, box, line, dots, bottom-line
colorsobjectPer-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_colorstring or nullColor for the ASCII logo (any color name listed above).
logo_colorsarray or nullPer-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_stylestring or nullPalette display: squares, circles, triangles, lines, dots
show_colorsbooleanShow inline ANSI color swatches next to each module
logo_pathstring or nullPath to a logo file (ASCII, PNG, SVG)
header_iconsarray or nullPac-Man layout top-border icons
footer_textstring or nullPac-Man layout bottom-border text

Theme Resolution

When xfetch loads a config with "theme": "dracula", it searches in order:

  1. Direct path — If the value contains / or starts with ~, load it directly as a file path
  2. Themes directory — Look for <name>.jsonc in ~/.config/xfetch/themes/

If the theme is not found, the config loads without the theme (no error).

CLI Commands

# 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

Export Behavior

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.

Directory Structure

~/.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

Migrating from v0.1.x

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+:

  1. Export your current look: xfetch theme export my-look
  2. Set it: xfetch theme set my-look
  3. Remove visual fields (colors, icons, layout, etc.) from config.jsonc so the theme can fully control them
  4. Keep modules and info_plugins in config.jsonc

Best Practices

  • Keep visual fields (colors, icons, layout) in theme files, not in config.jsonc
  • Keep structural fields (modules, info_plugins) in config.jsonc
  • Create a separate theme file for each visual variant you want
  • Export your current config as a starting point: xfetch theme export my-base