How Omarchy Filters User Theme Overlays: A Technical Deep Dive

Omarchy uses a contextual two-step overlay system that applies full file replacement for manually created themes but enforces a security denylist for Git-cloned themes, blocking executable configuration files like alacritty.toml and kitty.conf.

When activating a theme, Omarchy balances customization flexibility with security by examining how a user theme was installed. The omarchy-theme-set command orchestrates this process, handling everything from staging to final activation in ~/.local/state/omarchy/current/theme.

The Two-Step Overlay Architecture

Omarchy's theme activation follows a predictable pipeline. First, it copies built-in theme files from themes/<name>/. Then it overlays user-provided files from ~/.config/omarchy/themes/<name>/ according to trust boundaries.

This design allows users to override any aspect of a built-in theme while protecting against supply-chain attacks from untrusted Git repositories.

Full Overlay for Manually Created Themes

When a user creates a theme directory by hand—without initializing a Git repository—Omarchy applies the overlay without restriction. Every file placed in ~/.config/omarchy/themes/<name>/ replaces its counterpart in the base theme.

This mode trusts the user as the sole author, giving complete control over terminal emulators, editors, and shell configurations.

Filtered Overlay for Git-Cloned Themes

If the theme directory contains a .git folder, Omarchy treats it as potentially untrusted. The overlay logic switches to filtered mode, selectively copying only safe files and omitting any that could execute arbitrary code.

The INSTALLED_THEME_DENIED Denylist

The security boundary is defined in bin/omarchy-theme-set as a bash array:


# Inspect the denylist in bin/omarchy-theme-set

grep -A5 "INSTALLED_THEME_DENIED=" bin/omarchy-theme-set

As of the current implementation, INSTALLED_THEME_DENIED contains:

When the overlay loop encounters any filename matching this array, it prints a warning to stderr and excludes the file from staging. Only color-related and non-executable resources survive the filter.

Theme Activation Flow

The complete sequence in omarchy-theme-set <name> follows three phases:

  1. Staging – Base theme copies to a temporary directory, then user overlay applies (full or filtered depending on .git presence)
  2. Template Rendering – If colors.toml exists, dynamic templates are processed
  3. Activation – Final theme moves to ~/.local/state/omarchy/current/theme, and the running shell reloads

# Activate a manually created theme - full overlay applies

omarchy-theme-set my-custom-theme

# Install and activate a theme from Git - filtered overlay applies

omarchy theme install https://github.com/example/omarchy-theme.git
omarchy-theme-set example

# stderr warning: "Skipping dangerous file: kitty.conf"

Verifying the Filtering Behavior

The test suite test/shell.d/theme-staging-test.sh validates that cloned themes cannot smuggle executable configurations. It asserts that:

  • Color definitions and static assets pass through unchanged
  • Files matching INSTALLED_THEME_DENIED are absent from the final staged theme
  • Warnings appear for each dropped file

# Run the overlay filtering test

./test/shell.d/theme-staging-test.sh

This test ensures the denylist mechanism remains functional across refactors.

Security Design Rationale

Omarchy's filtering strategy acknowledges two threat models. Trusted authors (manual theme creators) maintain full control over their environment. Untrusted sources (any Git repository) are sandboxed from executing code through terminal or editor configurations.

The denylist approach prioritizes explicit safety over completeness—new dangerous file types can be added to INSTALLED_THEME_DENIED as the ecosystem evolves.

Summary

Frequently Asked Questions

How does Omarchy detect whether to use full or filtered overlay?

Omarchy checks for a .git directory inside ~/.config/omarchy/themes/<name>/. If present, the theme is treated as cloned and the filtered overlay applies. Absence of .git indicates a manually created theme receiving full overlay privileges.

Can I override the denylist for a cloned theme?

No—the denylist is hardcoded in bin/omarchy-theme-set and applies uniformly to all Git-cloned themes. To use denied configurations, manually create the theme directory without Git initialization, or fork the theme and maintain it outside version control.

Where are filtered themes ultimately stored?

After staging and any template rendering, the finalized theme moves to ~/.local/state/omarchy/current/theme. This location is read by the shell environment and application launchers to apply the active theme.

Why are terminal configurations specifically targeted?

Terminal emulators execute shell commands through features like shell, startup_script, or command directives. By denying these files from untrusted sources, Omarchy prevents a malicious theme from triggering arbitrary code execution when the user opens a new terminal window.

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 →