# How Omarchy Theme Templates Use `{{ Variable }}` Placeholders: Complete Guide

> Learn how Omarchy theme templates use {{ variable }} placeholders with colors.toml, supporting hex, RGB, and gradient parsing for easy customization.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: how-to-guide
- Published: 2026-09-13

---

**Omarchy replaces `{{ variable }}` placeholders in `.tpl` template files with color values from [`colors.toml`](https://github.com/omacom/omarchy/blob/main/colors.toml) through the `omarchy-theme-set-templates` script, supporting direct hex insertion, RGB conversion, hex stripping, interpolated color mixing, and gradient parsing.**

Omarchy’s theming engine transforms abstract color palettes into concrete application configurations by processing **template files** (`.tpl`) containing `{{ variable }}` placeholders. Located in the `omaccom/omarchy` repository, this system allows themes to define colors once in [`colors.toml`](https://github.com/omacom/omarchy/blob/main/colors.toml) and propagate them across diverse configuration formats including TOML, Lua, and shell scripts.

## Template Rendering Pipeline in Omarchy

The rendering process initiates when a user executes **`omarchy-theme-set <name>`**. This command orchestrates the theme activation through a specific lifecycle:

1. Creates a clean staging directory at `~/.local/state/omarchy/current/next-theme`
2. Copies the selected theme’s [`colors.toml`](https://github.com/omacom/omarchy/blob/main/colors.toml) and assets
3. Invokes **`bin/omarchy-theme-set-templates`** to process all `.tpl` files
4. Atomically moves the staging directory to the active theme location

This staging approach ensures that configuration files are fully rendered before becoming active, preventing partial state updates in running applications.

## How `{{ Variable }}` Placeholders Work

At the core of the system is **`bin/omarchy-theme-set-templates`**, a Bash script that constructs a **sed** substitution script from the palette defined in [`colors.toml`](https://github.com/omacom/omarchy/blob/main/colors.toml). The script populates an associative array `THEME_COLORS` by parsing the color file, then generates substitution rules for each key.

### Building the Palette Map

The script first loads all color definitions into memory:

```bash
while IFS=$'\t' read -r key value; do
  THEME_COLORS[$key]="$value"
done < <(omarchy-theme-color --file "$COLORS_FILE" --all)

```

Each key (e.g., `accent`, `background`) maps to a hex value (e.g., `#7aa2f7`), forming the lookup table for all subsequent placeholder resolutions.

### Simple Color Placeholders

For every entry in `THEME_COLORS`, the `add_template_value` function generates three distinct placeholder variants:

- **`{{ key }}`** — Inserts the raw hex value (e.g., `#7aa2f7`)
- **`{{ key_strip }}`** — Inserts the hex value without the leading `#` (e.g., `7aa2f7`)
- **`{{ key_rgb }}`** — Converts the hex value to decimal RGB format (e.g., `122,162,247`)

These variants are produced using `printf` statements that build sed substitution patterns, as documented in [`docs/theming.md`](https://github.com/omacom/omarchy/blob/main/docs/theming.md) and implemented at lines 100–107 of the rendering script.

## Advanced Placeholder Types

Beyond simple value insertion, Omarchy supports computed placeholders for dynamic color generation and gradient handling.

### Color Mixing with `{{ mix }}`

Templates can interpolate between two palette colors using the **`mix`** directive. The syntax follows `{{ mix[_strip|_rgb] <start_key> <end_key> <amount> }}`, where `<amount>` is a fraction or percentage (e.g., `20%`).

The `add_mix_values` function detects these tokens using `grep -Eo` (lines 49–51), then processes each match through `add_mix_value`:

1. Retrieves the start and end hex values from `THEME_COLORS`
2. Executes an **awk** function `mix_color` to linearly interpolate the two values based on the specified amount
3. Optionally strips the `#` prefix or converts to decimal RGB depending on whether `_strip` or `_rgb` suffixes are present
4. Appends a sed substitution rule to replace the entire token with the computed result

This enables smooth transitions between theme colors without manual hex calculation.

### Gradient Helpers (`hypr_gradient`, `gradient_start`, `shell_gradient`)

When a palette entry contains Hyprland-style gradient definitions (e.g., `rgba(33ccffee) rgba(00ff99ee) 45deg`), Omarchy exposes three specialized helpers:

- **`{{ hypr_gradient <key> <fallback> }}`** — Generates a Lua table structure: `{ colors = { "rgba(33ccffee)", "rgba(00ff99ee)" }, angle = 45 }`
- **`{{ gradient_start <key> <fallback> }}`** — Extracts the first solid color as a hex value (e.g., `#33ccff`)
- **`{{ shell_gradient <key> <fallback> }}`** — Returns the raw gradient string for shell consumption

These are implemented in `add_gradient_function_value` and helper functions spanning lines 54–78, with parsing logic at lines 84–90 that detects the specific helper patterns.

## Template Processing Flow

After collecting all substitution rules, the script applies them to template files found in `default/themed/` and `~/.config/omarchy/themed/`.

The rendering sequence follows this pattern:

```bash
for tpl in "${template_files[@]}"; do
  filename=$(basename "$tpl" .tpl)
  output_path="$NEXT_THEME_DIR/$filename"
  [[ ! -f $output_path ]] && sed -f "$sed_script" "$tpl" >"$output_path"
done

```

**User templates take precedence**: Files in `~/.config/omarchy/themed/` are processed first. If a generated file already exists from the default set, the script skips generation, effectively allowing user templates to override built-in defaults. This creates a cascading configuration system where customizations persist across theme updates.

## Practical Examples

### Example 1: Basic Color Substitution

**Input** (`default/themed/alacritty.toml.tpl`):

```toml
[colors]
foreground = "{{ foreground }}"
background = "{{ background_strip }}"
cursor = "{{ accent_rgb }}"

```

**Output** (assuming `foreground = "#a9b1d6"`, `background = "#1a1b26"`, `accent = "#7aa2f7"`):

```toml
[colors]
foreground = "#a9b1d6"
background = "1a1b26"
cursor = "122,162,247"

```

### Example 2: Color Mixing

**Input**:

```toml
[colors]
selection = "{{ mix background foreground 20% }}"

```

**Processing**: The script interpolates 20% of `foreground` into `background`, yielding a blended hex value like `#2f3a4f`.

**Output**:

```toml
[colors]
selection = "#2f3a4f"

```

### Example 3: Gradient Parsing

**Input**:

```toml
hyprland_active_border = "rgba(33ccffee) rgba(00ff99ee) 45deg"

```

**Template usage**:

```lua
local active_border = {{ hypr_gradient hyprland_active_border accent }}

```

**Output**:

```lua
local active_border = { colors = { "rgba(33ccffee)", "rgba(00ff99ee)" }, angle = 45 }

```

## Summary

- **Omarchy theme templates** use `.tpl` files with `{{ variable }}` placeholders that are processed by `bin/omarchy-theme-set-templates` during theme activation.
- **Three variants** of simple placeholders exist: `{{ key }}` for hex values, `{{ key_strip }}` for hex without `#`, and `{{ key_rgb }}` for decimal RGB tuples.
- **Color mixing** supports linear interpolation between two palette colors via `{{ mix }}`, with optional `_strip` or `_rgb` suffixes for format control.
- **Gradient helpers** parse Hyprland-style color lists into Lua tables, single colors, or raw strings using `hypr_gradient`, `gradient_start`, and `shell_gradient`.
- **User overrides** are respected: custom templates in `~/.config/omarchy/themed/` take precedence over defaults in `default/themed/`.

## Frequently Asked Questions

### Where are Omarchy theme templates stored?

Default templates reside in `default/themed/` within the repository, while user customizations belong in `~/.config/omarchy/themed/`. The rendering script processes both locations, with user-provided files taking precedence when filenames collide.

### How does Omarchy handle user customizations versus default templates?

The `omarchy-theme-set-templates` script processes user templates from `~/.config/omarchy/themed/` before default templates. It checks for existing output files and skips generation if a file already exists, ensuring that user configurations persist even when switching themes or updating the system defaults.

### What color formats do Omarchy variable placeholders support?

Placeholders support **hexadecimal values** with or without the `#` prefix, **decimal RGB tuples** (comma-separated), and **rgba() strings** for gradients. The system automatically converts between these formats using variant suffixes like `_strip` and `_rgb`, eliminating manual conversion in theme files.

### How are color mixtures calculated in Omarchy templates?

Mixtures use **linear interpolation** implemented in an `awk` function called `mix_color`. When processing `{{ mix start end amount }}`, the script extracts the two boundary colors from `THEME_COLORS`, converts the hex values to RGB components, interpolates each channel based on the fraction provided (e.g., `20%`), then reconverts to hexadecimal for insertion.