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.tomluses 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
TextFileparsing or template{{ substitution }} - Source paths:
themes/<theme>/colors.tomlwithshell/shell.qmlas 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →