How the Omarchy Theming System Generates Templates and Applies Theme Tokens

TLDR: Omarchy’s theming system operates in two distinct stages—template rendering and theme activation—where bin/omarchy-theme-set-templates processes colors.toml palettes into concrete configuration files via sed-based substitution, and bin/omarchy-theme-set orchestrates atomic theme swaps with IPC notifications to the running shell.

The Omarchy desktop environment by Basecamp uses a declarative theming pipeline that transforms simple color palettes into fully rendered configuration files for Alacritty, Hyprland, and the Quickshell. By analyzing the source code in basecamp/omarchy, this article explains how template placeholders, color mixing, and gradient generation work together to apply theme tokens consistently across the entire desktop.

Template Rendering Architecture

The first stage of the Omarchy theming system is handled by bin/omarchy-theme-set-templates. This script reads a theme’s colors.toml file and builds a comprehensive substitution map called THEME_COLORS.

Color Palette Parsing and Token Mapping

When bin/omarchy-theme-set-templates executes, it parses the theme’s colors.toml to extract all color keys. For every key (such as accent, background, or foreground), the script generates three variants:

  • {{ key }} – The raw hexadecimal value (e.g., #7aa2f7)
  • {{ key_strip }} – The hex value without the hash symbol (e.g., 7aa2f7)
  • {{ key_rgb }} – An RGB tuple formatted for specific consumers (e.g., 122, 162, 247)

These placeholders are stored in a sed script that will process all template files.

Placeholder Substitution and Mix/Gradient Helpers

Beyond simple value replacement, the Omarchy theming system supports dynamic color manipulation through helper functions within the template syntax:

  • Mix helpers – {{ mix background foreground 15% }} blends two colors using a Bash-awk routine named mix_color. Variants include {{ mix_strip … }} and {{ mix_rgb … }} for different output formats.
  • Gradient helpers – {{ hypr_gradient … }} parses Hyprland-style gradient strings and resolves theme references to produce Lua tables. Similarly, {{ shell_gradient … }} generates plain CSS gradients, while {{ gradient_start … }} extracts the first stop as a hex value.

These helpers allow a single colors.toml palette to generate complex, interpolated color schemes for multiple config formats simultaneously.

Template Processing and Staging

The script iterates over two template directories:

  1. Built-in templates at default/themed/*.tpl
  2. User-supplied templates at ~/.config/omarchy/themed/*.tpl

For each .tpl file found, the renderer applies the sed substitution script and writes the result to ~/.local/state/omarchy/current/next-theme/. Importantly, if a target file already exists in the staging directory, the script skips it, allowing hand-written configuration files to override generated ones. After processing all templates, the temporary sed script is removed.

Theme Activation Flow

The second stage is orchestrated by bin/omarchy-theme-set, which coordinates the atomic swap from the current theme to the new selection.

Theme Validation and Locking

When a user invokes omarchy theme set <name>, the script first normalizes the theme name and validates its existence in either the system path $OMARCHY_PATH/themes or the user path ~/.config/omarchy/themes. To prevent race conditions during concurrent theme changes, the script acquires a file lock at $XDG_RUNTIME_DIR/omarchy-theme-set.lock.

Staging and Template Generation

The activation process follows a strict staging sequence:

  1. Copies the selected theme into a clean staging directory at ~/.local/state/omarchy/current/next-theme, overlaying any user customizations
  2. Generates colors.toml from an existing alacritty.toml if needed via the omarchy-theme-colors-from-alacritty helper
  3. Invokes omarchy-theme-set-templates to render all dynamic configuration files

Atomic Swap and IPC Notification

After rendering templates, the system prepares for a smooth transition:

  • Takes a snapshot of the current background to prevent flickering
  • Atomically swaps the staging directory into the active location at ~/.local/state/omarchy/current/theme
  • Updates the active theme name stored in ~/.local/state/omarchy/current/theme.name
  • Adjusts the background symlink for wallpaper rendering

Finally, the script sends the new palette (colors.toml) and shell description (shell.toml) to the running Quickshell process via the IPC command omarchy-shell shell applyTheme. It then launches post-theme commands in parallel to retint running applications including terminals, Hyprland, btop, and VS Code.

Key Files and Scripts

Understanding the Omarchy theming system requires familiarity with these specific source files:

  • bin/omarchy-theme-set – The main orchestration script that handles theme validation, locking, staging, and IPC notification
  • bin/omarchy-theme-set-templates – The template renderer that processes placeholders, mix functions, and gradients
  • default/themed/*.tpl – Built-in templates defining how palette keys translate to concrete config files (e.g., alacritty.toml.tpl, hyprland.lua.tpl)
  • bin/omarchy-theme-color – Helper utility that parses colors.toml and outputs key/value pairs for the renderer
  • bin/omarchy-hook – Executes the theme-set hook after application, allowing user-defined scripts to run

Summary

  • The Omarchy theming system uses a two-stage pipeline: template rendering via bin/omarchy-theme-set-templates and theme activation via bin/omarchy-theme-set.
  • Template placeholders support raw values, stripped hex, RGB tuples, and dynamic color mixing through special helper syntax.
  • Themes are staged in ~/.local/state/omarchy/current/next-theme/ before an atomic swap into the active theme directory.
  • Concurrent theme changes are serialized using a file lock at $XDG_RUNTIME_DIR/omarchy-theme-set.lock.
  • The Quickshell receives theme updates via IPC using omarchy-shell shell applyTheme to ensure the UI reflects the new palette immediately.

Frequently Asked Questions

What file format does Omarchy use to define color palettes?

Omarchy uses TOML files named colors.toml to define color palettes. Each key in the file (such as accent or background) maps to a hexadecimal color value that the template renderer converts into multiple token formats (raw, stripped, and RGB) for use in different configuration files.

How do I create custom templates for the Omarchy theming system?

Create files ending in .tpl inside the directory ~/.config/omarchy/themed/. These templates use the same placeholder syntax ({{ accent }}, {{ mix background foreground 20% }}) as the built-in templates at default/themed/*.tpl. When omarchy-theme-set-templates runs, it processes user templates alongside system templates, with user versions taking precedence if they already exist in the staging directory.

What is the purpose of the next-theme staging directory?

The ~/.local/state/omarchy/current/next-theme/ directory serves as an atomic staging area where the Omarchy theming system assembles the new theme configuration before activation. This approach ensures that all templates are fully rendered and all files are in place before the system swaps the directory into the active location, preventing partial or broken theme states.

How does Omarchy handle concurrent theme changes?

Omarchy prevents race conditions by using a file-based lock at $XDG_RUNTIME_DIR/omarchy-theme-set.lock. When bin/omarchy-theme-set executes, it acquires this lock before copying theme files or rendering templates, ensuring that only one theme change operation can run at a time even if multiple omarchy theme set commands are triggered simultaneously.

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 →