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

> Discover how the Omarchy theme system dynamically generates UI configurations by parsing TOML color palettes and substituting template variables with a Bash driver.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: deep-dive
- Published: 2026-09-10

---

**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`](https://github.com/omacom/omarchy/blob/main/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`](https://github.com/omacom/omarchy/blob/main/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`](https://github.com/omacom/omarchy/blob/main/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.

```toml

# Example: themes/solarized/colors.toml

accent = "#268BD2"
background = "#002B36"
foreground = "#839496"
red = "#DC322F"
green = "#859900"

```

```qml
// Example: default/themed/status-bar.tpl
Rectangle {
    color: "{{ background }}"
    Text {
        text: "Omarchy"
        color: "{{ foreground }}"
    }
    Rectangle {
        width: 2
        color: "{{ accent }}"
    }
}

```

```bash

# 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`](https://github.com/omacom/omarchy/blob/main/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`](https://github.com/omacom/omarchy/blob/main/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`](https://github.com/omacom/omarchy/blob/main/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`](https://github.com/omacom/omarchy/blob/main/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`](https://github.com/omacom/omarchy/blob/main/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`](https://github.com/omacom/omarchy/blob/main/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`](https://github.com/omacom/omarchy/blob/main/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`](https://github.com/omacom/omarchy/blob/main/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.