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 namedmix_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:
- Built-in templates at
default/themed/*.tpl - 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:
- Copies the selected theme into a clean staging directory at
~/.local/state/omarchy/current/next-theme, overlaying any user customizations - Generates
colors.tomlfrom an existingalacritty.tomlif needed via theomarchy-theme-colors-from-alacrittyhelper - Invokes
omarchy-theme-set-templatesto 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 notificationbin/omarchy-theme-set-templates– The template renderer that processes placeholders, mix functions, and gradientsdefault/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 parsescolors.tomland outputs key/value pairs for the rendererbin/omarchy-hook– Executes thetheme-sethook 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-templatesand theme activation viabin/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 applyThemeto 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →