Ternux
Advanced

Themes

How the Ternux theme system works and how to create custom themes.

Ternux uses a JSON-based theme engine. Each theme is a standalone JSON file that defines color tokens, applied at runtime via CSS custom properties. This makes themes portable, user-creatable, and easy to maintain.

How it works

  1. Built-in themes live in src/themes/*.json and are bundled at build time.
  2. Custom themes live in ~/.config/ternux/themes/*.json and are loaded on startup.
  3. The active theme's tokens are written to <html> via element.style.setProperty().
  4. All components consume colors via Tailwind utilities like bg-(--color-bg), text-(--color-text), etc. — zero component changes needed for new themes.

Theme JSON structure

Each theme file carries its own mode (dark OR light) — there is no separate dark/light toggle.

{
  "id": "my-theme",
  "name": "My Theme",
  "description": "A custom dark theme",
  "mode": "dark",
  "author": "Your Name",
  "colors": {
    "accent": "#EEEEEE",
    "bg": "#121213",
    "panel": "#09090a",
    "card": "#191a1b",
    "line": "#212224",
    "text": "#EAEDF5"
  }
}

Required color keys

Only 6 keys are required:

KeyPurpose
accentPrimary brand color (buttons, active states, selection rings)
bgMain window background
panelSidebar / tab-strip background
cardCard and panel surfaces
lineBorders and dividers
textPrimary text color

All other tokens (surfaces, borders, text variants, syntax, terminal ANSI palette) are derived automatically at apply-time from these 6 core values. Theme authors can override any derived token by including it explicitly in the colors object.

Optional token groups

  • Syntax highlighting (13 tokens): syntax-keyword, syntax-string, syntax-comment, etc.
  • Terminal ANSI palette (20+ tokens): terminal-bg, terminal-fg, terminal-cursor, terminal-red, terminal-green, etc.
  • Status colors: danger, warn, indigo
  • Overlay: overlay

See src/core/theme/theme-schema.ts for the complete schema.

Adding a custom theme

  1. Create a JSON file matching the schema above.
  2. Drop it into ~/.config/ternux/themes/.
  3. Restart Ternux (or the theme loads automatically on next startup).
  4. The theme appears in Settings → Appearance → Theme gallery.

No code changes or config file edits required.

Built-in themes

IDNameModeDescription
ternux-darkTernux DarkdarkDefault monochrome dark
ternux-lightTernux LightlightDefault monochrome light
one-dark-proOne Dark ProdarkVS Code inspired
atom-one-lightAtom One LightlightVS Code inspired light

Technical details

  • Engine: src/core/theme/apply-theme.ts — pure element.style.setProperty() loop, no class toggles or <style> injection.
  • Registry: src/core/theme/theme-registry.ts — merges built-in + custom themes.
  • Migration: Old theme + colorScheme config fields are automatically mapped to an equivalent themeId on first load.
  • Splash screen: Critical colors are cached to localStorage so the splash renders with the correct theme before JS loads.
  • Terminal: resolveTerminalTheme() in LocalTerminal.tsx reads from the active theme's resolved palette — one code path for all themes.

All component styles must use CSS variable references (--color-*), never hardcoded color values. This rule applies to both Tailwind utilities and inline styles.

On this page