How the Hooks System in config/omarchy/hooks/ Triggers Lifecycle Events in Omarchy

The hooks system in config/omarchy/hooks/ triggers lifecycle events by executing flat hook files and scripts in *.d directories when specific Omarchy commands like omarchy theme set or omarchy update dispatch events via the omarchy hook run dispatcher.

Omarchy is an opinionated desktop environment that uses a lightweight, filesystem-based mechanism to let users extend system behavior without modifying core code. The hooks system in config/omarchy/hooks/ provides a simple "drop-a-script" approach that automatically executes user scripts at well-defined lifecycle moments. This article explains exactly how the core bin/omarchy command dispatches these events and how the directory structure controls execution order.

How the Hooks Directory is Structured

All hooks live under the user's config directory at ~/.config/omarchy/hooks/. The system recognizes specific lifecycle events through a combination of flat files and numbered directories:

  • battery-low.d/ — Triggered when battery drops below threshold (receives percentage as $1)
  • font-set.d/ — Runs after font changes (receives font name as $1)
  • post-boot.d/ — Executed once the desktop environment starts
  • post-update.d/ — Fired after omarchy update completes migrations
  • pre-refresh-pacman.d/ — Invoked before omarchy refresh pacman syncs the database
  • theme-set.d/ — Called after theme switches (receives theme slug as $1)

Execution Flow and Event Dispatching

When an Omarchy lifecycle event fires, the system follows a strict two-phase execution pattern defined in the omarchy hook run implementation within bin/omarchy.

First, if a flat file exists at ~/.config/omarchy/hooks/<event> (without the .d suffix), that script executes immediately. Second, the dispatcher iterates over every executable file inside the corresponding <event>.d/ directory, invoking scripts in lexical (alphabetical) order. Each script receives exactly one positional argument containing the event payload, such as the theme name or battery percentage.

This design allows users to define both one-off actions (flat files) and modular, ordered scripts (.d directories) for the same event.

Lifecycle Events and Trigger Points

The Omarchy core commands invoke hooks at specific moments using the internal dispatcher. Here are the key trigger points implemented in the source code.

Theme Changes

After omarchy theme set <slug> completes the visual transition, the command executes omarchy hook run theme-set "$THEME_SLUG", passing the newly activated theme identifier to all registered hooks.

System Updates

The omarchy update command runs its full migration pipeline, then explicitly triggers omarchy hook run post-update to allow cleanup or notification scripts.

Package Management

Before executing pacman -Sy during omarchy refresh pacman, the system invokes omarchy hook run pre-refresh-pacman, giving users a chance to pause or prepare the environment before database synchronization.

Boot Sequence

The Quickshell session startup script sources omarchy hook run post-boot immediately after the desktop environment initializes, ensuring startup applications or configurations load after the shell is ready.

Battery Monitoring

The background battery-monitor daemon checks charge levels periodically. When the percentage drops below the configured threshold, it dispatches omarchy hook run battery-low "$PERCENT" to trigger power-saving scripts.

Installing and Testing Hooks

Users install hooks using the convenience command omarchy hook install <event> <script>. This copies the supplied script into the appropriate <event>.d/ directory, marks it executable with chmod +x, and optionally creates a flat <event> file if one does not exist.

To test a hook manually without waiting for the lifecycle event, use the manual execution syntax:

omarchy hook run theme-set solarized-dark

For example, to install a notification hook that triggers after theme changes:

omarchy hook install theme-set <<'EOF'
#!/usr/bin/env bash
THEME=$1
notify-send "Theme changed" "Now using: $THEME"
EOF

Sample cleanup script for post-update (saved to ~/.config/omarchy/hooks/post-update.d/clean-temp.hook):

#!/usr/bin/env bash

# Remove stale temporary files after an update

find "$HOME/.cache" -type f -mtime +30 -delete

Summary

  • The hooks system in config/omarchy/hooks/ uses a filesystem-based approach where scripts live in ~/.config/omarchy/hooks/<event>.d/ directories or as flat <event> files.
  • The bin/omarchy dispatcher executes flat files first, then iterates through *.d directories in lexical order, passing event-specific payloads as $1.
  • Core lifecycle commands like omarchy update, omarchy theme set, and omarchy refresh pacman trigger events via omarchy hook run <event>.
  • Users install hooks with omarchy hook install and test them manually with omarchy hook run <event>.

Frequently Asked Questions

What is the execution order for multiple hooks in the same event?

Omarchy executes hooks in lexical (alphabetical) order based on filenames within the *.d directory. To control priority, prefix scripts with numbers, such as 10-notify.sh and 20-cleanup.sh, ensuring deterministic execution sequences.

How do I pass custom arguments to hook scripts?

The system passes exactly one argument to each hook containing the event payload (e.g., theme name, battery percentage). While you cannot pass additional custom arguments during the dispatch call, scripts can read environment variables or configuration files to access extra context.

Can I disable a hook temporarily without deleting it?

Yes. Make the file non-executable using chmod -x ~/.config/omarchy/hooks/<event>.d/<script>. The omarchy hook run dispatcher only executes files with executable permissions, effectively skipping disabled scripts while preserving them for future use.

Where is the omarchy hook run command implemented?

The dispatch logic resides in bin/omarchy, which serves as the main entry point for all Omarchy CLI operations. This wrapper handles the discovery of flat hook files and iteration over *.d directories, as documented in default/agents/skills/omarchy/hooks.md.

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 →