# How the Omarchy Desktop Environment Is Structured: A Deep Dive into the Quickshell Architecture

> Explore the Omarchy desktop environment's Quickshell architecture. Learn how modular plugins and RPC calls structure this single long-running process for seamless operation.

- Repository: [37signals/omarchy](https://github.com/basecamp/omarchy)
- Tags: deep-dive
- Published: 2026-08-21

---

**The Omarchy desktop environment runs as a single long-running Quickshell process that loads modular plugins—including the status bar, lock screen, menu, and system services—from the `shell/plugins/` directory, while thin CLI wrappers in `bin/` provide external control via RPC calls.**

The **Omarchy desktop environment structure** follows a plugin-centric design implemented in the `basecamp/omarchy` repository. Unlike traditional desktop environments that spawn separate processes for panels and menus, Omarchy embeds all visual elements into one Quickshell runtime. This architecture separates concerns into command-line utilities, shell plugins, configuration templates, and migration scripts.

## Repository Layout

The `basecamp/omarchy` codebase organizes functionality into distinct directories that reflect the runtime architecture:

- **`bin/`** – Command-line utilities (e.g., `omarchy-toggle`, `omarchy-theme-set`) that communicate with the shell or execute system tasks
- **`shell/`** – Core Quickshell runtime containing the entry point (`shell.qml`), the `PluginRegistry`, and shared libraries in `Ui/` and `Commons/`
- **`shell/plugins/`** – Modular features including the bar, lock screen, menu, and background services, each with a [`manifest.json`](https://github.com/basecamp/omarchy/blob/main/manifest.json) and QML/JS implementation
- **`config/`** and **`default/`** – Templates copied to `~/.config/omarchy/` on first run (e.g., `default/omarchy/omarchy-menu.jsonc`)
- **`migrations/`** – Timestamped scripts that evolve on-disk configuration across releases
- **`manual/`** and **`docs/`** – End-user and developer documentation (e.g., [`docs/omarchy-shell.md`](https://github.com/basecamp/omarchy/blob/main/docs/omarchy-shell.md))
- **`default/fonts/`** and **`default/themed/`** – Static assets including icons and typefaces

## Core Components

### Shell Entry Point

In `shell/shell.qml`, the Quickshell instance boots and initializes the **PluginRegistry**. This file creates the root UI canvas and imports shared helpers from `shell/Commons/` such as `Util.qml`, `Style.qml`, and `Color.qml`.

```qml
import QtQuick 2.15
import Quickshell 1.0

Item {
    Component.onCompleted: {
        PluginRegistry.loadPlugin("bar")
    }
}

```

### Plugin Registry

The `shell/services/PluginRegistry.qml` file maintains a map of all available plugins, loads them on demand, and exposes them to the rest of the desktop. Each plugin declares its capabilities in a nearby [`manifest.json`](https://github.com/basecamp/omarchy/blob/main/manifest.json) file, allowing the registry to instantiate UI elements and background services dynamically.

### The Bar Plugin

Located in `shell/plugins/bar/`, the bar plugin implements the top-most status bar. `BarWidget.qml` hosts a series of widget plugins (workspaces, system tray, battery indicators) found in `shell/plugins/bar/widgets/`. Each widget is a self-contained QML component registered through the plugin system.

### Menu and Lock Screen Plugins

The menu plugin at `shell/plugins/menu/` provides the searchable command interface (`omarchy.menu`). `Menu.qml` renders the UI while [`MenuModel.js`](https://github.com/basecamp/omarchy/blob/main/MenuModel.js) aggregates command metadata drawn from `bin/` helpers. Similarly, the lock screen plugin in `shell/plugins/lock/` handles session security via Quickshell's native `WlSessionLock`, with `LockView.qml` managing the visual interface and `Service.qml` handling the lock state.

### Service Plugins

Background functionality—battery monitoring, media control, idle management, night-light, and clipboard—lives under `shell/plugins/services/<name>/`. Each service follows a consistent pattern: a [`manifest.json`](https://github.com/basecamp/omarchy/blob/main/manifest.json), a `Service.qml` file, and supporting JavaScript models such as [`BatteryModel.js`](https://github.com/basecamp/omarchy/blob/main/BatteryModel.js). For example, `shell/plugins/services/battery/Service.qml` emits signals that update the bar's battery widget in real time.

### UI Library

The `shell/Ui/` directory contains reusable QML components like `Panel.qml`, buttons, dropdowns, and text fields. Plugins import these to maintain visual consistency across the desktop environment.

## Configuration and Data Flow

When the shell starts, `shell.qml` reads user configuration from `~/.config/omarchy/` (populated initially from `default/` templates). The **PluginRegistry** instantiates only the enabled plugins, which then register their UI elements with host components like the bar. Background services start automatically and emit signals to update the interface.

The menu plugin aggregates command metadata using the `GROUP_DESCRIPTIONS` table defined in `bin/` utilities, presenting a searchable list without spawning external processes until a selection is made.

## CLI Integration

Scripts in `bin/` such as `omarchy-toggle` and `omarchy-theme-set` act as thin wrappers. They invoke Quickshell RPC calls through the `omarchy-shell` socket to trigger actions—toggling settings, refreshing themes, or launching applications—without directly manipulating configuration files.

```qml
import Quickshell 1.0

BarIconButton {
    icon: "mdi:refresh"
    onClicked: Quickshell.execDetached("omarchy-theme-refresh")
}

```

## Extending the Desktop

To add a custom widget to the status bar, create a manifest file in [`shell/plugins/bar/widgets/MyWidget.manifest.json`](https://github.com/basecamp/omarchy/blob/main/shell/plugins/bar/widgets/MyWidget.manifest.json):

```json
{
  "name": "MyWidget",
  "description": "Demo widget showing the current date",
  "qml": "MyWidget.qml"
}

```

Implement `MyWidget.qml` in the same directory, then reference it in `BarWidget.qml`. The plugin system handles loading and lifecycle management automatically.

## Summary

- **Single-process architecture**: All UI elements run inside one Quickshell instance (`omarchy-shell`) rather than separate processes
- **Plugin-driven design**: Features are modular packages in `shell/plugins/` with [`manifest.json`](https://github.com/basecamp/omarchy/blob/main/manifest.json) declarations
- **Clear separation**: CLI tools live in `bin/`, configuration templates in `default/`, and runtime logic in `shell/`
- **Live configuration**: The desktop reads from `~/.config/omarchy/` and supports automatic migrations via timestamped scripts in `migrations/`
- **Consistent UI**: The `shell/Ui/` library provides standardized components for all plugins

## Frequently Asked Questions

### What is Quickshell and how does Omarchy use it?

Quickshell is a QtQuick-based shell runtime for Wayland. Omarchy uses it as the foundation for its desktop environment, running a single persistent process (`omarchy-shell`) that hosts all UI components—from the status bar to the lock screen—as dynamically loaded plugins.

### How do I add a custom widget to the Omarchy status bar?

Create a new folder in `shell/plugins/bar/widgets/` containing a [`manifest.json`](https://github.com/basecamp/omarchy/blob/main/manifest.json) file and a QML implementation. The manifest declares the widget name and entry point, while `BarWidget.qml` will instantiate it automatically when the bar plugin loads.

### Where are Omarchy's configuration files stored?

User-specific configuration resides in `~/.config/omarchy/`, populated initially from templates in the repository's `default/` directory. System-wide defaults and fallback assets are located in `default/` and `config/` within the installation prefix.

### How does Omarchy handle configuration updates between versions?

The `migrations/` directory contains timestamped shell scripts that run automatically when the desktop starts after an upgrade. These scripts transform existing configuration files to match new schema requirements without manual intervention.