Skip to content

Themes

A theme is a YAML file that controls the colors and text styles the Polytoken TUI uses. Every color in the TUI comes from a design token, and a theme file can assign a value to any token; tokens the file omits keep their default colors. Polytoken ships with a built-in default theme, and you can write your own.

Two config keys control theming. tui.theme selects the mode: dark, light, or auto, which detects the mode from your terminal background. tui.theme-file names the theme file Polytoken loads; leave it unset and Polytoken uses the built-in default. The mode determines which palette section (dark: or light:) Polytoken reads from the theme file.

For the full list of tokens and their default values, see Theme Token Reference.

A minimal theme file looks like this:

version: 1
title: My Custom Theme
dark:
body:
fg:
rgb: "#dcdcdc"
app_background:
bg:
rgb: "#000000"
accent:
fg:
rgb: "#78c8ff"
b: true
light:
body:
fg:
rgb: "#1e1e1e"
app_background:
bg:
rgb: "#ffffff"

The top-level keys:

  • version: 1: the schema version. Always 1.
  • title:: the display name polytoken theme list shows.
  • dark:: the dark-mode palette.
  • light:: the light-mode palette.
  • palette:: optional reusable color definitions you reference with $ref.

Every theme file must include both dark: and light:. Each contains token entries. A token entry can set a foreground color, a background color, and text modifiers.

Each token under dark: or light: accepts these fields:

  • fg:: foreground color.
  • bg:: background color. Same shape as fg:.
  • b: true: bold.
  • i: true: italic.
  • u: true: underline.
  • s: true: strikethrough.

Color values accept three formats:

  • Hex string: rgb: "#78c8ff"
  • RGB triple: rgb: [120, 200, 255] (bytes 0 to 255, or floats 0.0 to 1.0 if any value has a decimal point)
  • HSV triple: hsv: [210, 0.531, 1.0] (hue 0 to 360 degrees, saturation and value 0.0 to 1.0)

For example, to set a blue foreground, write fg: { rgb: "#64b4ff" } or use the indented form:

link:
fg:
rgb: "#64b4ff"
u: true

Every palette section must define body.fg and app_background.bg. Polytoken uses body.fg as the default foreground color and app_background.bg as the default background color. A token entry that omits fg inherits the foreground from body. A token entry that omits bg stays transparent, so the surface behind the text, such as a card or sidebar, shows through. An absent token entry, or one that sets nothing, uses both default colors.

When several tokens share the same color, define the color once under palette: and reference the color with $ref. A $ref points to a same-file fragment using JSON Pointer syntax (#/palette/name):

palette:
accent_blue:
rgb: "#64b4ff"
dark:
link:
fg:
$ref: "#/palette/accent_blue"
u: true

A $ref object must stand alone: it cannot carry sibling keys in the same map. Put the $ref on the color entry (fg: or bg:) and apply any text modifiers at the token level.

A $ref must point to a target that exists in the same file. Polytoken does not support cross-file references or URL references. Circular references produce an error.

  1. Create the themes directory and copy the built-in default into it as a starting point:

    Terminal window
    mkdir -p ~/.config/polytoken/themes
    polytoken vfs cat polytoken://themes/default.yaml > ~/.config/polytoken/themes/my-theme.yaml

    Both commands use ~/.config/polytoken/themes, the default location for user themes. Polytoken stores user config under $XDG_CONFIG_HOME/polytoken (default: ~/.config/polytoken), the same on every platform. If you set XDG_CONFIG_HOME, substitute that directory in both commands.

  2. Edit the color values. Change the fg, bg, and modifier entries under dark: and light: to match your palette.

  3. Validate the file:

    Terminal window
    polytoken theme validate ~/.config/polytoken/themes/my-theme.yaml

    The command reports errors and warnings. Fix any errors before proceeding.

  4. Preview the theme at runtime with the /theme slash command in the TUI. See Switching themes at runtime.

  5. Set tui.theme-file to $USER_DIRECTORY/themes/my-theme.yaml in your config file to use the custom theme by default. Polytoken resolves $USER_DIRECTORY to your Polytoken config directory. The value must name the theme file by path, including the extension; for a built-in theme, use a URI such as polytoken://themes/default.yaml.

Polytoken discovers theme files from two locations:

  • Built-in VFS: polytoken://themes/ ships with Polytoken. Built-in theme paths must use this namespace, and trailing slashes do not change which theme Polytoken loads.
  • User config directory: the themes/ subdirectory under $XDG_CONFIG_HOME/polytoken/, alongside your config file. Polytoken discovers user theme files with either the .yaml or .yml extension.

Polytoken lists both built-in and user themes. The /theme command selects a theme by its file name without the extension and gives built-in themes precedence when names match. Give your custom theme a distinct file name so /theme can find it. Setting tui.theme-file to the custom file’s path selects that file directly.

The polytoken theme list command shows every discovered theme with its source and validity status:

Terminal window
polytoken theme list
NAME SOURCE VALID TITLE
boringcyberpunk built-in ✓ Boring Cyberpunk
default built-in ✓ Polytoken Default
rose-pine built-in ✓ Rose Pine

These two config keys vary independently:

  • tui.theme (auto, light, or dark) controls which palette section Polytoken uses. When you set tui.theme to auto, Polytoken detects the terminal background and picks dark or light.
  • tui.theme-file (optional) controls which theme file Polytoken loads. When you leave tui.theme-file unset, Polytoken uses the built-in default.

For example, set tui.theme to dark and tui.theme-file to $USER_DIRECTORY/themes/solarized.yaml to load the dark: section of that custom theme. The $USER_DIRECTORY variable resolves to your Polytoken config directory. Set tui.theme to light to use the same file’s light: section.

Terminal window
polytoken theme list

Shows every discovered theme with its name, source, validity status, and title. Add --format json for machine-readable output.

Terminal window
polytoken theme tokens

Shows every design token with its category, required status, and resolved dark and light default styles. Pass --format json for structured output.

Terminal window
polytoken theme validate

Run without arguments to validate the built-in default theme. Pass a path or a polytoken:// URI to validate a specific file:

Terminal window
polytoken theme validate ~/.config/polytoken/themes/my-theme.yaml
polytoken theme validate polytoken://themes/default.yaml

Add --all to validate every discovered theme:

Terminal window
polytoken theme validate --all

Polytoken reports per-file results and exits non-zero on any hard error. Unknown token names under dark: or light: produce warnings; Polytoken ignores those entries.

Type /theme in the TUI prompt to open a typeahead of discovered valid themes. The /themes alias opens the same typeahead.

  • Up / Down move through the candidates.
  • The TUI immediately redraws with the highlighted theme’s colors.
  • Tab inserts the highlighted theme’s name into the prompt and closes the typeahead without submitting the command.
  • Enter applies the highlighted theme for the current session.
  • Esc restores the previous theme and closes the typeahead.

Polytoken applies a theme you choose with /theme to the current session only and does not write the change to your config file. To make a theme permanent, set tui.theme-file in your config.

Polytoken ships the built-in default theme at polytoken://themes/default.yaml in the virtual filesystem. Inspect the theme, or copy it as a starting point:

Terminal window
polytoken vfs ls polytoken://themes
polytoken vfs cat polytoken://themes/default.yaml

For the full VFS documentation, see The Polytoken VFS.