How Omarchy Migrations Are Stored and Executed: Complete Technical Guide

Omarchy treats configuration changes as versioned migrations, storing each as a timestamped shell script in migrations/ and executing them via the omarchy-migrate command while tracking completion through marker files in the user's state directory.

Omarchy, the opinionated Linux workstation system developed by Basecamp, manages system evolution through a deterministic migration framework. Understanding how Omarchy migrations are stored and executed is essential for contributors and power users who need to track configuration drift or implement custom system modifications. The system employs Unix-epoch timestamp naming and POSIX-compliant shell scripts to ensure idempotent, safely ordered upgrades across all installations.

Migration Storage Architecture

Timestamped Shell Scripts in the Migrations Directory

Every migration in Omarchy lives as a standalone, POSIX-compatible shell script within the repository’s migrations/ directory. Files are named using Unix-epoch timestamps—such as 1787618700.sh and 1787494718.sh—which ensures that lexical filesystem order matches chronological execution order. This design removes the need for complex dependency resolution while guaranteeing that migrations apply in the exact sequence they were introduced to the codebase.

User-State Marker Files

The system tracks which migrations have already run by creating empty marker files in the user’s state directory, specifically $HOME/.local/state/omarchy/migrations/. When bin/omarchy-migrate executes, it compares the filenames in the source migrations/ directory against these markers to determine which scripts are pending. This approach provides true idempotence; once a migration completes successfully, its corresponding marker prevents re-execution during subsequent runs.

The Migration Execution Pipeline

Discovery and Ordering via omarchy-migrate

The public command omarchy-migrate (located at bin/omarchy-migrate) drives the entire migration process. First, it scans $OMARCHY_PATH/migrations/*.sh (defaulting to /usr/share/omarchy/migrations) and sorts the filenames to establish execution order. The tool then checks for corresponding marker files in the user's state directory to filter out completed migrations, as demonstrated in the test suite at test/shell.d/migrate-wrapper-test.sh.

Safe Execution with Bash Strict Mode

Pending migrations execute under bash -euo pipefail, which causes immediate termination if any command exits with a non-zero status, if an undefined variable is referenced, or if a pipeline fails. This strict error handling prevents partial state application—if a migration fails, the runner aborts immediately without creating a marker file, leaving the migration in an unmarked state for retry after the issue is resolved.

Automatic Marker Creation

Upon successful completion (exit 0), the runner automatically creates a marker file in $HOME/.local/state/omarchy/migrations/ matching the script's basename. The migration script itself does not handle this marking; the runner assumes responsibility for state tracking, ensuring consistency across all migration types regardless of their internal implementation.

Desktop Notification Integration

Systemd User Service for Pending Migrations

To ensure users never miss pending configuration updates, Omarchy includes a notification system triggered by the omarchy-migrate-notify.service systemd user unit. Defined in default/systemd/user/omarchy-migrate-notify.service, this service runs on every login and invokes the omarchy-migrate-notify helper binary. This binary internally executes omarchy-migrate --pending to check for work, displaying a desktop toast with the title "Pending Omarchy Migrations" only when unapplied scripts exist, as documented in docs/notifications.md.

Working with Omarchy Migrations

Running and Checking Migration Status

Use the following commands to manage migrations:


# Execute all pending migrations for the current user

omarchy-migrate

# List pending migrations without executing them

omarchy-migrate --pending

Creating Custom Migrations

Developers can add personal migrations by creating timestamped scripts in the appropriate directory:


# Create a new migration with current timestamp

cat >"$HOME/.local/share/omarchy/migrations/$(date +%s).sh" <<'SH'
#!/usr/bin/env bash

# Example migration: enable a new default config

install_default_config "myfeature.conf"
SH
chmod +x "$HOME/.local/share/omarchy/migrations/$(date +%s).sh"

The next invocation of omarchy-migrate will automatically detect and execute this script.

Summary

  • Omarchy migrations are stored as Unix-epoch timestamped shell scripts in the migrations/ directory, ensuring lexical order equals chronological order.
  • The omarchy-migrate command handles discovery, execution with bash -euo pipefail, and automatic marker file creation in $HOME/.local/state/omarchy/migrations/.
  • Idempotence is guaranteed through marker files; successfully completed migrations are never re-run.
  • Safety mechanisms include strict error handling that aborts on first failure, preventing partial system states.
  • User notifications occur via the omarchy-migrate-notify.service systemd unit, which alerts users to pending work at login.

Frequently Asked Questions

Where are Omarchy migration files stored?

Migration source files reside in the repository's migrations/ directory (typically /usr/share/omarchy/migrations/ on installed systems), while completion markers indicating which migrations have run are stored in the user's state directory at $HOME/.local/state/omarchy/migrations/.

How does Omarchy ensure migrations run in the correct order?

Omarchy names migration files using Unix-epoch timestamps (e.g., 1787618700.sh). Since filesystems sort these numerically, lexical order naturally reflects chronological introduction order, eliminating the need for manual sequence numbering or dependency graphs.

What happens if a migration script fails during execution?

The omarchy-migrate runner executes scripts with bash -euo pipefail and aborts immediately upon any non-zero exit code. No marker file is created for failed migrations, ensuring they remain in the pending state and will be retried on the next execution attempt.

Can I check for pending migrations without running them?

Yes. Running omarchy-migrate --pending performs a dry-run check that lists all unapplied migrations by comparing the source directory against marker files, without executing any scripts or modifying system state.

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 →