# Omarchy Package Management Integration: How It Wraps Pacman for Safe, Testable System Operations

> Discover how Omarchy integrates with package management by wrapping pacman commands. Achieve safe, testable system operations with a unified interface for menus, migrations, and updates.

- Repository: [37signals/omarchy](https://github.com/basecamp/omarchy)
- Tags: how-to-guide
- Published: 2026-08-18

---

**Omarchy integrates with package management through a small set of Bash helper scripts that wrap Arch's native `pacman` and `yay` commands, providing a uniform interface used across menus, migrations, and the update pipeline.**

Omarchy is a desktop environment built on Arch Linux that needs to reason about installed packages throughout its entire stack. Rather than invoking `pacman` directly, the project implements a **thin abstraction layer** of helper scripts. This design enables consistent exit-code contracts, safer system modifications, and testable automation across CLI commands, UI menus, and version migrations.

## Core Helper Scripts: The Pacman Abstraction Layer

At the heart of Omarchy's package management integration are four Bash scripts located in `bin/` that wrap native package operations:

- **`bin/omarchy-pkg-add`** — Installs missing Arch packages, automatically elevating with `sudo` when needed.
- **`bin/omarchy-pkg-drop`** — Removes packages with the same safety semantics.
- **`bin/omarchy-pkg-present`** — Returns success if a package is installed.
- **`bin/omarchy-pkg-missing`** — Returns success if a package is **not** installed.

These helpers are intentionally thin. In `bin/omarchy-pkg-add`, the script handles privilege detection and delegates to `sudo pacman -S --needed`. The `bin/omarchy-pkg-present` helper queries `pacman -Q` and returns standardized exit codes. This lets other Omarchy components treat package operations as **native shell predicates**.

```bash

# Install packages through the Omarchy abstraction

omarchy pkg add jq ripgrep fd

# Query package state for conditional logic

if omarchy-pkg-present firewalld; then
    echo "Firewall installed – applying rules"
    sudo firewall-cmd --add-service=ssh
fi

```

The exit-code contract is consistent across all four helpers: success means the operation succeeded or the condition is true, failure means it did not. This uniformity powers Omarchy's **declarative configuration** patterns.

## Menu Guards: Conditional UI Based on Package State

Omarchy's JSON-C menu system in `default/omarchy/omarchy-menu.jsonc` uses these helpers in `"when"` clauses to **dynamically show or hide items** based on what's installed on the system.

```jsonc
{
  "id": "install.browser.brave",
  "label": "Install Brave Browser",
  "action": "install.browser.brave",
  "disabled": "omarchy-pkg-present brave-bin"
}

```

When the Quickshell menu renders, the shell plugin evaluates these guards. If `brave-bin` is already present, the item appears disabled—preventing redundant installations. This **declarative approach** keeps UI logic out of JavaScript and in version-controlled configuration.

The [`shell/plugins/menu/MenuModel.js`](https://github.com/basecamp/omarchy/blob/main/shell/plugins/menu/MenuModel.js) file exposes JavaScript wrappers that call the Bash helpers:

```javascript
// MenuModel.js exposes these to all Quickshell plugins
omarchyPkgPresent("neovim")   // → calls bin/omarchy-pkg-present
omarchyPkgMissing("code")     // → calls bin/omarchy-pkg-missing

```

This bridging layer lets plugins query package state without re-implementing logic or spawning redundant subprocesses.

## Migration Scripts: Idempotent Package Management

Omarchy's version migrations in `migrations/*.sh` leverage the helpers for **reliable, repeatable system transitions**. When a new Omarchy version changes its default package set, migration scripts use `omarchy-pkg-add` and `omarchy-pkg-drop` to bring systems into compliance.

Example from [`migrations/1784510887.sh`](https://github.com/basecamp/omarchy/blob/main/migrations/1784510887.sh):

```bash
#!/bin/bash

# Migration: Replace legacy tools with modern alternatives

omarchy-pkg-drop vim
omarchy-pkg-add neovim
omarchy-pkg-add fd            # Alternative to find

omarchy-pkg-add ripgrep       # Alternative to grep -r

```

Because the helpers are idempotent—`omarchy-pkg-add` uses `pacman -S --needed` and `omarchy-pkg-drop` handles missing packages gracefully—**migrations can run multiple times safely**. Failures are caught early through explicit exit codes rather than silent `pacman` failures.

## Update Pipeline: Pre- and Post-Transaction Hooks

The `omarchy update` command in `bin/omarchy` owns the complete system update flow. Before any `pacman -Syu` operation, the **pre-refresh hook** validates package database synchronization. After the transaction completes, the pipeline:

1. Runs `omarchy-pkg-present` checks for critical dependencies.
2. Executes pending migrations.
3. Triggers post-update hooks for additional configuration.

The full pipeline behavior is documented in [`docs/update-process.md`](https://github.com/basecamp/omarchy/blob/main/docs/update-process.md). This structured approach ensures that **package state remains consistent** even when Arch's rolling updates introduce breaking changes.

## AUR Support: Yay Integration for Foreign Packages

For packages outside official Arch repositories, Omarchy generates **`bin/omarchy-pkg-aur-add`** at install time. This helper delegates to `yay` for building and installing AUR packages. The separate `bin/omarchy-update-aur-pkgs` script handles foreign package updates, calling the AUR helper only when foreign packages actually exist on the system.

```bash

# Update flow conditionally includes AUR

omarchy-update-aur-pkgs       # Skips entirely if no foreign packages installed

```

This **conditional execution** avoids unnecessary `yay` invocations and keeps update times minimal for systems without AUR dependencies.

## CLI Routing: Unified User Interface

The main `bin/omarchy` router maps user-facing commands to the internal helpers:

| User Command | Maps To |
|-------------|---------|
| `omarchy pkg add <pkg>` | `bin/omarchy-pkg-add` |
| `omarchy pkg drop <pkg>` | `bin/omarchy-pkg-drop` |

This ensures **identical behavior** whether a user installs from the terminal or clicks a menu item. Both paths exercise the same validation, privilege handling, and exit-code reporting.

## Benefits of Omarchy's Package Management Design

The helper-based architecture provides four key advantages over direct `pacman` invocation:

- **Consistency** — Every component uses the same exit-code contract and error handling.
- **Safety** — Helpers perform additional verification (e.g., confirming packages actually installed) beyond raw `pacman` output.
- **Testability** — Unit tests can stub `bin/omarchy-pkg-*` scripts rather than invoke the system package manager.
- **Extensibility** — Menus, migrations, and update logic react to package state without duplicating query logic.

## Summary

- Omarchy's package management integration centers on **four Bash helpers** (`omarchy-pkg-add`, `omarchy-pkg-drop`, `omarchy-pkg-present`, `omarchy-pkg-missing`) that wrap `pacman` and `yay`.
- The **JSON-C menu system** uses these helpers in `"when"` clauses for conditional UI rendering via `default/omarchy/omarchy-menu.jsonc`.
- **Migration scripts** in `migrations/*.sh` rely on the helpers for idempotent, version-to-version package transitions.
- The **`omarchy update` pipeline** orchestrates pre-transaction validation, `pacman -Syu`, migrations, and post-update hooks.
- **AUR support** is handled through generated helpers that delegate to `yay` only when foreign packages exist.
- The design prioritizes **testability and safety** through a consistent abstraction layer rather than direct package manager access.

## Frequently Asked Questions

### Does Omarchy modify pacman configuration directly?

No. Omarchy never writes to [`/etc/pacman.conf`](https://github.com/basecamp/omarchy/blob/main//etc/pacman.conf) or modifies pacman's core configuration. All package operations flow through the helper scripts, which invoke `pacman` and `yay` with explicit flags. System-level pacman settings remain under administrator control.

### Can I use Omarchy's package helpers in my own scripts?

Yes. The helpers in `bin/` are designed for standalone use and follow standard Unix conventions. They accept package names as arguments, handle `sudo` elevation automatically, and return meaningful exit codes. Scripts outside Omarchy can source or call these helpers directly.

### What happens if a migration fails due to a missing package?

Migration scripts exit on first failure due to `set -e` and the helpers' strict error handling. The `omarchy-pkg-*` scripts return non-zero when operations fail, stopping the migration and surfacing the error. Administrators can then resolve the conflict and re-run `omarchy update` to continue.

### How does Omarchy handle partial upgrades or pacman database locks?

The `omarchy update` command includes pre-refresh validation in its pipeline, documented in [`docs/update-process.md`](https://github.com/basecamp/omarchy/blob/main/docs/update-process.md). Before any transaction, it checks for database synchronization and lock conditions. If pacman reports a partial upgrade state or database lock, the update pauses and reports the specific condition rather than proceeding with a potentially broken transaction.