How the Omarchy Theme System Handles Templates, Colors, and Variables

The Omarchy theme system generates runtime UI configurations by parsing TOML color palettes and performing in-place substitution of double-brace placeholders in template files using a Bash driver script.

The Omarchy theme system in the omacom/omarchy repository implements a lightweight, data-driven architecture that separates visual styling from application logic. By storing color definitions in structured TOML files and UI markup in template files with {{ variable }} syntax, the system enables declarative theming without external dependencies. A single Bash script orchestrates the build process, loading palettes into associative arrays and expanding templates into the user's configuration directory.

Core Components of the Omarchy Theme System

The architecture relies on three distinct resource types that interact during the configuration generation phase.

Template Files (.tpl)

Template files reside in default/themed/**/*.tpl and contain UI markup—such as QML or CSS—with placeholder variables using double-brace syntax. These files serve as blueprints for the final configuration, maintaining the directory hierarchy when processed. Each placeholder references a key defined in the color palette, allowing the same template to render different visual styles based on the active theme.

Color Palettes (colors.toml)

Color definitions are stored in themes/<theme-name>/colors.toml, providing named values like accent, background, and foreground. The TOML format enables human-readable palette management where designers can add custom variables without modifying parsing logic. Because the theme system dynamically reads all keys from this file, new color variables automatically become available to templates.

The Theme-System Script

The theme-system script at install/config/theme-system.sh executes the transformation pipeline. This Bash script performs three critical operations: determining the active theme via the OMARCHY_THEME environment variable (defaulting to default), loading the TOML palette into a Bash associative array, and iterating through all template files to perform string substitution.

The Template Processing Pipeline

When Omarchy initializes or receives a theme refresh command, theme-system.sh executes the following logical workflow:

  1. Determine the active theme. The script checks the OMARCHY_THEME environment variable and falls back to the built-in default theme if unset.
  2. Load the color palette. Using a minimal TOML parser, the script reads themes/<active-theme>/colors.toml into a Bash associative array declared as declare -A palette.
  3. Expand templates. For each file matching default/themed/**/*.tpl, the script reads the content, replaces every occurrence of {{ key }} with ${palette[$key]}, and writes the result to $HOME/.config/... while preserving the original file hierarchy.

Because substitution occurs at the string level, templates that do not reference specific keys remain unchanged when new variables are added to colors.toml, making the system forward-compatible and safe to extend.

Variable Substitution Mechanics

The substitution engine uses standard Bash text processing to inject values. The script iterates over the associative array keys, applying sed to replace placeholders with concrete color values.


# Example: themes/solarized/colors.toml

accent = "#268BD2"
background = "#002B36"
foreground = "#839496"
red = "#DC322F"
green = "#859900"
// Example: default/themed/status-bar.tpl
Rectangle {
    color: "{{ background }}"
    Text {
        text: "Omarchy"
        color: "{{ foreground }}"
    }
    Rectangle {
        width: 2
        color: "{{ accent }}"
    }
}

# Simplified excerpt from install/config/theme-system.sh

declare -A palette
while IFS='=' read -r key value; do
    palette[$key]="${value//\"/}"
done < "$theme_dir/colors.toml"

while IFS= read -r -d '' tmpl; do
    out="${tmpl%.tpl}"
    cp "$tmpl" "$out"
    for k in "${!palette[@]}"; do
        sed -i "s/{{ *$k *}}/${palette[$k]}/g" "$out"
    done
done < <(find "$OMARCHY_PATH/default/themed" -name '*.tpl' -print0)

Running omarchy-refresh-config theme executes this pipeline, generating concrete UI descriptions in the user's home directory where all placeholders have been resolved to the selected theme's color values.

File Locations and Architecture

Understanding the repository structure clarifies how the components interact:

  • install/config/theme-system.sh — Core orchestration script that reads palettes and expands templates.
  • themes/*/colors.toml — Theme-specific color definitions (one per theme directory).
  • default/themed/**/*.tpl — Source templates containing placeholder variables.
  • ~/.config/... — Runtime output directory receiving the processed configuration files.

Testing and Error Handling

The Omarchy repository includes shell tests to ensure theme system reliability. The file test/shell.d/theme-install-guards-test.sh verifies that missing variables trigger clear error messages rather than silent failures. Meanwhile, test/shell.d/theme-staging-test.sh performs end-to-end validation, confirming that substitution works correctly across the entire template set. These tests prevent runtime configuration errors by catching undefined palette keys before they reach the UI layer.

Summary

  • The Omarchy theme system uses template files with {{ variable }} syntax stored in default/themed/, TOML color palettes located in themes/<name>/colors.toml, and a Bash processing script at install/config/theme-system.sh to generate configurations.
  • The substitution pipeline loads color values into a Bash associative array and processes templates using sed to replace placeholders before writing results to ~/.config/.
  • The architecture supports forward compatibility—adding new variables to colors.toml does not break existing templates that lack those references.
  • Built-in tests in test/shell.d/ guard against missing variables and validate correct template expansion.

Frequently Asked Questions

How do I create a custom theme in Omarchy?

Create a new directory under themes/ containing a colors.toml file with your color definitions. Define any variable names your templates require, then set OMARCHY_THEME to your directory name before running the refresh command. The system will automatically pick up your new palette and substitute the values into all template files.

What happens if a template references a missing variable?

The theme-install-guards-test.sh test suite validates that missing variables trigger explicit errors. While the current substitution logic using sed would leave the placeholder unchanged if a key is absent in the palette array, the guard tests ensure the build process fails early with a clear message rather than producing broken configuration files.

Where are the generated theme files stored?

After processing, expanded templates are written to the user's runtime configuration directory under $HOME/.config/, preserving the relative directory structure from default/themed/. This allows the Omarchy desktop environment to read concrete UI definitions without parsing templates at runtime, improving startup performance.

Can I use variables for values other than colors?

Yes. While the default colors.toml files define hex color codes, the theme system treats all values as opaque strings. You can define variables for font names, opacity values, or paths in your TOML file, and reference them as {{ variable_name }} in templates. The Bash parser simply performs literal string substitution without type validation.

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 →