How Omarchy Handles Database Migrations: A Complete Guide to Script-Driven System Evolution
Omarchy handles database migrations through a lightweight, shell-based system that uses the omarchy-migrate command to discover and execute timestamped scripts in the migrations/ directory, tracking state in $XDG_DATA_HOME/omarchy/migrations and aborting on any error to ensure atomic updates.
Omarchy, a declarative system configuration framework, manages configuration state changes across releases using a deterministic migration system. Unlike traditional database migration tools that rely on SQL, Omarchy employs idempotent Bash scripts executed in strict chronological order to modify system files and configuration. This approach ensures that upgrades are reproducible, testable, and safe, with the omarchy-migrate command serving as the central orchestrator for all system state transitions.
The Migration Architecture and File Structure
Omarchy stores migration logic as executable shell scripts within the migrations/ directory of the repository. Each script follows a timestamped naming convention (for example, 1788595060.sh or 1788124236.sh) that encodes execution order chronologically. The bin/omarchy-migrate file implements the core discovery engine, scanning this directory and sorting scripts by filename to determine sequence.
This architecture treats system configuration as code, allowing migrations to move files, update drop-in configuration snippets, or modify service definitions. Because the system targets operating system state rather than relational data, migrations use standard Unix utilities and Bash logic instead of SQL statements.
How the omarchy-migrate Command Discovers and Executes Scripts
When invoked, omarchy-migrate performs a deterministic discovery process:
- Scanning: It identifies all files in the
migrations/directory matching the*.shpattern. - Ordering: It sorts discovered scripts lexicographically by filename, ensuring that timestamp prefixes dictate execution sequence.
- Execution: It runs each script in a clean environment with
bash -euo pipefail, causing immediate termination if any command fails or references an undefined variable.
According to the implementation in bin/omarchy-migrate, the system enforces strict error handling. If any migration script exits with a non-zero status, the entire migration run aborts immediately, preventing partial system modifications that could leave the configuration in an inconsistent state.
# Run all pending migrations (normally invoked automatically after upgrades)
omarchy-migrate
# Execute with verbose output for debugging
bash -x /usr/local/bin/omarchy-migrate
Tracking Pending and Completed Migrations
Omarchy maintains migration state within the user's data directory to prevent re-execution of successful scripts. After a migration completes with exit code 0, the system records its completion in $XDG_DATA_HOME/omarchy/migrations. This state tracking allows the --pending flag to identify migrations that have not yet successfully run.
# List all migrations waiting to be applied
omarchy-migrate --pending
The state file mechanism ensures idempotency across multiple upgrade attempts; rerunning omarchy-migrate only executes scripts that failed or were introduced since the last successful run.
Integration with System Upgrades
The migration system integrates directly into Omarchy's upgrade pipeline through bin/omarchy-upgrade-to-quattro. This script calls omarchy-migrate immediately after completing package upgrades, ensuring that configuration adjustments apply before the user session resumes. This sequencing guarantees that binary updates and configuration migrations occur atomically, preventing version mismatches between installed software and system configuration.
The upgrade script's implementation demonstrates that migrations are not manually triggered by users during normal operation, but rather orchestrated automatically as part of the system's self-healing update mechanism.
User Notification for Pending Migrations
When automatic migration execution fails or requires user intervention, the omarchy-migrate-notify command provides feedback. Defined in bin/omarchy-migrate-notify, this helper checks for pending migrations using the --pending flag and surfaces desktop notifications to alert users that manual action is required.
The repository includes a systemd user service at default/systemd/user/omarchy-migrate-notify.service that triggers this notification check after the graphical session starts. This ensures that users are promptly informed of any configuration drift that needs resolution without polling the system manually.
Testing Migration Safety and Idempotency
The test suite validates migration behavior through test/shell.d/upgrade-to-quattro-test.sh. This test verifies that:
- Migrations execute in the correct chronological order derived from filenames.
- The system correctly handles success, failure, and pending states.
- Scripts are idempotent, meaning they can run multiple times without causing errors or unintended side effects.
These automated checks enforce that all contributions to the migrations/ directory meet safety standards before release, ensuring that community-contributed configuration changes do not destabilize existing installations.
Writing Custom Migration Scripts
Migration scripts must conform to strict execution standards to maintain system integrity. A valid migration requires the shebang #!/usr/bin/env bash and must enable set -euo pipefail at the outset. The script should verify preconditions, perform atomic file operations, and exit with status 0 on success.
#!/usr/bin/env bash
set -euo pipefail
# Example: Migrate legacy configuration to new structure
old_conf="${HOME}/.config/omarchy/old.conf"
new_conf="${HOME}/.config/omarchy/settings.conf"
if [[ -f "$old_conf" ]]; then
mv "$old_conf" "$new_conf"
fi
# Explicitly exit 0 to mark success
exit 0
Scripts should avoid dependencies on external services and must handle cases where previous partial runs may have completed some but not all steps.
Summary
- Discovery mechanism: The
bin/omarchy-migratecommand scans themigrations/directory and sorts scripts by timestamped filenames to determine execution order. - Strict execution: Every migration runs under
bash -euo pipefail, with any non-zero exit code aborting the entire migration process to prevent partial updates. - State tracking: Completed migrations are recorded in
$XDG_DATA_HOME/omarchy/migrations, enabling the--pendingflag to identify outstanding work. - Upgrade integration: The
bin/omarchy-upgrade-to-quattroscript automatically invokes migrations after package updates, ensuring configuration and binaries remain synchronized. - User notifications: The
bin/omarchy-migrate-notifyhelper and corresponding systemd service alert users when manual migration intervention is required. - Validation: The
test/shell.d/upgrade-to-quattro-test.shtest suite enforces idempotency and correct ordering for all migration scripts.
Frequently Asked Questions
What is the difference between Omarchy migrations and traditional SQL database migrations?
Traditional SQL migrations modify relational database schemas using statements like CREATE TABLE or ALTER COLUMN, whereas Omarchy migrations are Bash scripts that modify system configuration files, move data directories, or update service definitions. Omarchy's approach treats the entire operating system configuration as a versioned state, using shell commands rather than SQL to achieve idempotent system evolution.
How does Omarchy ensure that migrations run in the correct order?
The system relies on lexicographic sorting of filenames within the migrations/ directory. Developers prefix migration scripts with Unix timestamps (for example, 1788595060.sh), ensuring that alphabetical order corresponds to chronological execution sequence. The bin/omarchy-migrate command implements this sorting logic during the discovery phase, guaranteeing deterministic run order across all installations.
What happens if a migration script fails during execution?
If any migration returns a non-zero exit code, the omarchy-migrate command immediately aborts the entire run without attempting subsequent scripts. This fail-fast behavior, enforced by set -euo pipefail within the execution environment, prevents partial configuration changes that could corrupt system state. Users must fix the underlying issue and rerun omarchy-migrate to complete the pending migrations.
How can I check which migrations are pending without running them?
Use the --pending flag to display a list of migrations that have not yet been recorded as successful in the state file. This command queries $XDG_DATA_HOME/omarchy/migrations against the available scripts in the migrations/ directory, providing a safe way to audit upcoming configuration changes before applying them.
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 →