Omarchy `colors.toml` Structure: Complete Guide to Theme Configuration

The colors.toml file in Omarchy is a flat TOML configuration that defines a theme's complete color palette through five logical sections: meta, core accents, background variants, foreground variants, and a basic color set with bright equivalents.

Every theme in the Omarchy desktop environment ships its own colors.toml under themes/<theme>/. This single file drives the visual appearance across all UI components, from status bars to application menus. Understanding its structure is essential for custom theme development.

Flat Key-Value Design Philosophy

Omarchy's colors.toml intentionally avoids nesting or TOML tables. All entries are simple key = "hex" assignments. This flat design prioritizes parsing speed in the QML runtime that renders the desktop shell.

The layout remains identical across all themes—only hex values change. Whether you're working with the built-in white, nord, or catppuccin themes, you'll find the same keys in every file.

The Five Structural Sections

1. Meta Information

The mode key declares the theme's brightness profile:

mode = "dark"  # or "light"

This boolean-like flag tells UI components whether to apply dark-mode or light-mode logic for automatic contrast adjustments.

2. Core Accent & UI Helpers

Three foundational colors define interactive states:

Key Purpose
accent Primary highlight color for focused elements
selection Background for selected text or items
muted De-emphasized UI elements

From themes/nord/colors.toml:

accent = "#81a1c1"
selection = "#434c5e"
muted = "#4c566a"

3. Background Family

Four progressive shades handle layered surfaces:

background = "#2e3440"        # Default surface

dark_background = "#222730"   # Panels, sidebars

darker_background = "#1e222a" # Tooltips, overlays

lighter_background = "#3b4252" # Elevated cards

The white theme inverts this progression—dark_background becomes #f5f5f5 (off-white) rather than a darker shade, because the base background is pure #ffffff.

4. Foreground Family

Text colors adapt to different surface contrast needs:

foreground = "#d8dee9"        # Primary text

dark_foreground = "#667080"   # Text on light surfaces

light_foreground = "#e5e9f0"  # Text on dark surfaces

bright_foreground = "#eceff4" # Emphasized text

5. Basic Color Set & Bright Variants

Sixteen colors (eight base + eight bright) complete the palette:


# Base colors

red = "#bf616a"
yellow = "#ebcb8b"
green = "#a3be8c"
cyan = "#88c0d0"
blue = "#5e81ac"
magenta = "#b48ead"

# Bright equivalents

bright_red = "#bf616a"
bright_yellow = "#ebcb8b"

# ... etc

Note: In many themes, bright variants duplicate base colors. Omarchy's design treats "bright" as a semantic label for active/highlighted states rather than requiring distinct values.

Complete File Example: Nord Theme

themes/nord/colors.toml demonstrates full structure:

mode = "dark"

accent = "#81a1c1"
selection = "#434c5e"
muted = "#4c566a"

background = "#2e3440"
dark_background = "#222730"
darker_background = "#1e222a"
lighter_background = "#3b4252"

foreground = "#d8dee9"
dark_foreground = "#667080"
light_foreground = "#e5e9f0"
bright_foreground = "#eceff4"

red = "#bf616a"
yellow = "#ebcb8b"
green = "#a3be8c"
cyan = "#88c0d0"
blue = "#5e81ac"
magenta = "#b48ead"

bright_red = "#bf616a"
bright_yellow = "#ebcb8b"
bright_green = "#a3be8c"
bright_cyan = "#8fbcbb"
bright_blue = "#81a1c1"
bright_magenta = "#b48ead"

Consuming colors.toml in QML

The shell loads this palette at runtime. Here's how shell/shell.qml parses it:

import QtQuick 2.15

property var themePath: Quickshell.env("OMARCHY_PATH") + "/themes/" + currentTheme + "/colors.toml"
property var palette: {}

Component.onCompleted: {
    const file = new TextFile(themePath, TextFile.ReadOnly)
    const lines = file.readAll().split("\n")
    for (let line of lines) {
        const match = line.match(/^(\w+)\s*=\s*"([^"]+)"/)
        if (match) palette[match[1]] = match[2]
    }
    file.close()
}

// Applied in components
Rectangle {
    color: palette.background
    Text {
        color: palette.foreground
        text: "Omarchy Desktop"
    }
}

The regex ^(\w+)\s*=\s*"([^"]+)" exploits the flat structure—no nested tables means line-by-line parsing suffices.

Template Integration

Non-QML files consume the same palette through default/themed/*.tpl templates:


# In default/themed/bar.tpl

background: {{ background }};
border-color: {{ accent }};
color: {{ bright_foreground }};

The template engine substitutes {{ key }} placeholders with hex values from the active theme's colors.toml.

Key File Reference

Path Purpose
themes/<theme>/colors.toml Theme palette definition (e.g., themes/nord/colors.toml, themes/white/colors.toml)
default/themed/*.tpl Template files using {{ key }} substitution
shell/shell.qml Core loader that parses colors.toml into the palette object
docs/theme.md Official theming documentation

Summary

  • colors.toml uses a flat key-value structure—no tables, no nesting—for QML parsing performance
  • Five logical sections: meta (mode), core accents (accent, selection, muted), backgrounds, foregrounds, and basic/bright colors
  • Identical key names across all themes; only hex values vary
  • Runtime consumption via QML TextFile parsing or template {{ substitution }}
  • Source paths: themes/<theme>/colors.toml with shell/shell.qml as the primary consumer

Frequently Asked Questions

How do I create a custom Omarchy theme?

Create a new directory under themes/ with a colors.toml file containing all standard keys. Copy an existing theme like nord as a template, then modify hex values. No registration is required—the theme becomes available by directory name immediately.

Why are bright colors sometimes identical to base colors in colors.toml?

Omarchy treats bright_ prefixes as semantic state markers rather than color modifiers. Many themes reuse identical hex values because the UI distinguishes "active" versus "normal" through opacity or layering rather than hue shift. You may customize these independently if your design requires distinct bright variants.

Can I add custom keys to colors.toml?

Additional keys won't break parsing, but they won't be utilized by core Omarchy components. The QML loader in shell/shell.qml captures all key-value pairs into the palette object, so custom QML components can access extended keys. Standard templates in default/themed/ only reference the documented key set.

Does mode = "light" change automatic behavior?

Yes—the mode key enables adaptive contrast logic. Components reading the palette can switch calculation strategies: light-mode themes may invert shadow directions, adjust overlay opacity, or select alternative text colors for readability without hardcoding theme names.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →