# Quickshell Desktop Shell in Omarchy: Architecture and Plugin Ecosystem

> Discover the Quickshell desktop shell in Omarchy. Learn about its registry-based architecture supporting widgets, overlays, services, and menus, and explore its plugin ecosystem.

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

---

**The Quickshell desktop shell is a long-running QML process in Omarchy that dynamically discovers, loads, and manages first-party and user-installed plugins via a registry-based architecture supporting bar widgets, overlays, background services, and menus.**

The Quickshell desktop shell serves as the core UI backbone for Omarchy, the opinionated desktop environment developed by Basecamp. Implemented in the `basecamp/omarchy` repository as a declarative QML runtime, this shell provides the foundation for the status bar, system menus, and background services through a flexible plugin system that loads configuration from `~/.config/omarchy/shell.json`.

## Core Architecture of the Quickshell Desktop Shell

The shell is defined in `shell/shell.qml` and instantiates a `ShellRoot` object that orchestrates the entire desktop environment. It creates three singleton-like registry objects injected into every plugin to manage discovery, UI placement, and application metadata.

### Shell Root and Singleton Registries

When the Quickshell desktop shell initializes, it constructs three critical shared objects available to all plugins:

- **PluginRegistry** – Scans the `plugins/` directory, tracks installed plugins, and resolves enablement states.
- **BarWidgetRegistry** – Registers components that appear in the status bar and handles layout positioning.
- **AppLibrary** – Provides a searchable list of installed applications for menu plugins.

```qml
property PluginRegistry pluginRegistry: PluginRegistry { }
property BarWidgetRegistry barWidgetRegistry: BarWidgetRegistry { }
property AppLibrary appLibrary: AppLibrary { }

```

*(see lines 11‑19 of [`shell/shell.qml`](https://github.com/basecamp/omarchy/blob/quattro/shell/shell.qml#L11-L19))*

### Configuration Resolution and Plugin Paths

The shell derives critical paths from the `OMARCHY_PATH` environment variable and the user's home directory. It distinguishes between **first-party plugins** shipped with Omarchy and **user-installed plugins** stored in the configuration directory:

```qml
readonly property string firstPartyPluginsDir: shellPath + "/plugins"
readonly property string defaultsPath: omarchyPath + "/config/omarchy/shell.json"
readonly property string userConfigPath: home + "/.config/omarchy/shell.json"

```

*(see lines 24‑31 of [`shell/shell.qml`](https://github.com/basecamp/omarchy/blob/quattro/shell/shell.qml#L24-L31))*

The shell parses [`shell.json`](https://github.com/basecamp/omarchy/blob/main/shell.json) to configure the status bar (`barConfig`) and determine which plugins are enabled. If the user configuration is missing, it falls back to a built-in default:

```qml
readonly property var builtinShellConfig: ({
    version: 1,
    bar: { position: "top", layout: { left: [{id:"omarchy.menu"}], ... } },
    plugins: []
})

```

*(see lines 34‑53 of [`shell/shell.qml`](https://github.com/basecamp/omarchy/blob/quattro/shell/shell.qml#L34-L53))*

### Plugin Loading Lifecycle and UI Instantiation

Plugins are loaded dynamically via QML `Loader` elements. The shell distinguishes between several **plugin kinds** that determine how they are instantiated:

- **Service** – Creates a hidden `serviceHost` component for background processes.
- **Panel**, **Overlay**, or **Menu** – Creates a `Loader` on demand; UI remains alive if `keepLoaded:true`.
- **Bar-widget** – Registers with the `BarWidgetRegistry` and integrates into `plugins/bar/Bar.qml`.

The `syncPluginWidgets` function (starting at line 66) iterates through enabled plugins and populates the bar with widget components. For service plugins, the shell injects shared references including `omarchyPath`, `shell`, and `manifest` into the service host.

*(see sections “services” and “on‑demand panels” in [`shell/shell.qml`](https://github.com/basecamp/omarchy/blob/quattro/shell/shell.qml#L63-L98))*

## First-Party Plugins and Supported Types

Omarchy ships with a comprehensive set of first-party plugins located in `shell/plugins/`. Each plugin declares its capabilities via a [`manifest.json`](https://github.com/basecamp/omarchy/blob/main/manifest.json) file specifying its `id`, `kinds`, and entry points.

### Core Interface Plugins

These plugins provide the primary user interface shell components:

- **Bar** (`omarchy.bar`) – The main status bar implementation rendering at `bar/Bar.qml` with `kind: bar`.
- **Omarchy Menu** (`omarchy.menu`) – Provides both a full menu (`menu/Menu.qml`) and a compact bar widget (`menu/BarWidget.qml`) with kinds `menu` and `bar-widget`.

### Background Services

Service plugins run hidden without persistent UI, handling system functions:

- **Battery** (`omarchy.battery`) – Monitors power status at `services/battery/Service.qml`.
- **Idle** (`omarchy.idle`) – Detects user inactivity via `services/idle/Service.qml`.
- **Night Light** (`omarchy.nightlight`) – Controls display temperature at `services/nightlight/Service.qml`.
- **Lock Screen** (`omarchy.lock`) – Manages screen locking at `lock/Service.qml`.
- **Polkit Agent** (`omarchy.polkit`) – Handles authentication dialogs at `polkit/PolkitAgent.qml`.
- **Notifications** (`omarchy.notifications`) – Manages notification dispatch at `notifications/Service.qml`.
- **Media** (`omarchy.media`) – Controls media playback as both a service (`services/media/Service.qml`) and bar widget (`services/media/BarWidget.qml`).

### Status Bar Widgets

These plugins render interactive panels in the status bar when clicked:

- **Audio** (`omarchy.audio`) – Volume control panel at `panels/audio/Panel.qml`.
- **Network** (`omarchy.network`) – Network status and connections at `panels/network/Panel.qml`.
- **Bluetooth** (`omarchy.bluetooth`) – Device management at `panels/bluetooth/Panel.qml`.
- **Clock** (`omarchy.clock`) – Time and calendar display at `panels/clock/BarWidget.qml`.
- **Power** (`omarchy.power`) – Shutdown and reboot controls at `panels/power/Panel.qml`.
- **Monitor** (`omarchy.monitor`) – Display settings at `panels/monitor/Panel.qml`.
- **Tailscale** (`omarchy.tailscale`) – VPN status at `panels/tailscale/Panel.qml`.
- **Weather** (`omarchy.weather`) – Weather information at `panels/weather/BarWidget.qml`.
- **Agents** (`omarchy.agents`) – AI agent status at `agents/Panel.qml`.

### Overlays and Utility Panels

These plugins provide on-demand floating interfaces:

- **Image Picker** (`omarchy.image-picker`) – Wallpaper and image selection overlay at `image-picker/ImagePicker.qml`.
- **Emojis** (`omarchy.emojis`) – Emoji picker at `emojis/Emojis.qml`.
- **Clipboard Manager** (`omarchy.clipboard`) – Clipboard history at `clipboard/Clipboard.qml`.
- **Reminders** (`omarchy.reminders`) – Quick note-taking at `reminders/ReminderFlow.qml`.
- **OSD** (`omarchy.osd`) – On-screen display notifications at `osd/Osd.qml`.

*(see lines 14‑36 of [[`shell/plugins/README.md`](https://github.com/basecamp/omarchy/blob/main/shell/plugins/README.md)](https://github.com/basecamp/omarchy/blob/quattro/shell/plugins/README.md#L14-L36))*

## IPC Commands for Shell Interaction

The Quickshell desktop shell exposes an `IpcHandler` with target `"shell"` that allows external scripts and CLI tools to control the desktop environment programmatically.

### Summoning Plugins via CLI

To activate an overlay plugin like the image picker, send an IPC request with configuration payload:

```bash
omarchy-shell shell summon omarchy.image-picker '{"imageDirs":["/usr/share/wallpapers"],"imageRows":"..."}'

```

The `summon` implementation (lines 40‑78) routes the request to load the plugin if necessary and delivers the payload to the component.

*(see `summon` implementation at lines 40‑78 of [`shell/shell.qml`](https://github.com/basecamp/omarchy/blob/quattro/shell/shell.qml#L40-L78))*

### Managing Bar Widgets

For bar-widget plugins, the shell routes commands directly to the live bar instance rather than creating new loaders:

```bash
omarchy-shell shell toggle omarchy.network '{}'

```

This invokes `bar.summonBarWidget` for immediate display in the status bar.

*(see bar‑widget handling in `summon` at lines 55‑61 of [`shell/shell.qml`](https://github.com/basecamp/omarchy/blob/quattro/shell/shell.qml#L55-L61))*

### Querying and Enabling Plugins Dynamically

List all installed plugins with their metadata:

```bash
omarchy-shell shell listPlugins

# → JSON array with id, kinds, enabled status, etc.

```

The `listPlugins` method iterates over `pluginRegistry.installedPlugins` (lines 52‑89).

Enable a plugin and optionally add it to the bar layout:

```bash
omarchy-shell shell enablePlugin omarchy.weather '{"kinds":["bar-widget"],"position":"right"}'

```

This parses placement JSON and updates the `PluginRegistry` configuration.

*(see `enablePlugin` in [`shell/shell.qml`](https://github.com/basecamp/omarchy/blob/quattro/shell/shell.qml))*

## Key Implementation Files

Understanding the Quickshell desktop shell requires familiarity with these specific source files:

- **`shell/shell.qml`** – The core host process that wires registries, loads JSON configuration, and manages plugin lifecycles via `Loader` and `serviceHost` components.
- **[`shell/plugins/README.md`](https://github.com/basecamp/omarchy/blob/main/shell/plugins/README.md)** – Catalog documenting all first-party plugin IDs, supported kinds, and QML entry points.
- **`shell/plugins/*/manifest.json`** – Individual plugin manifests defining the contract between the shell and plugin code.
- **`shell/services/PluginRegistry.qml`** – Implementation of the discovery mechanism scanning both `shellPath + "/plugins"` and `~/.config/omarchy/plugins/`.
- **`shell/services/BarWidgetRegistry.qml`** – Manages registration and layout of status bar components.
- **`shell/plugins/bar/Bar.qml`** – Default status bar UI container that hosts widgets from the registry.
- **`shell/Ui/`** – Shared QML components including `BarWidget.qml` and `Panel.qml` reused across plugins.

## Summary

- The **Quickshell desktop shell** is a QML runtime defined in `shell/shell.qml` that serves as the foundation for the Omarchy desktop environment.
- **Three core registries** (`PluginRegistry`, `BarWidgetRegistry`, and `AppLibrary`) manage plugin discovery, bar placement, and application metadata.
- **Plugin kinds** determine lifecycle behavior: services run hidden, bar-widgets render in the status bar, and overlays appear on demand via `Loader` elements.
- **First-party plugins** reside in `shell/plugins/` while user extensions go in `~/.config/omarchy/plugins/`, both following the [`manifest.json`](https://github.com/basecamp/omarchy/blob/main/manifest.json) contract.
- **IPC handlers** allow external tools to summon interfaces, toggle widgets, and enable plugins dynamically using the `omarchy-shell` CLI.

## Frequently Asked Questions

### What programming language powers the Quickshell desktop shell?

The Quickshell desktop shell is implemented in **QML** (Qt Meta Language) with JavaScript integration. It runs as a long-lived `ShellRoot` process that leverages Qt's declarative UI framework to render the Omarchy desktop environment.

### Where does Omarchy store its shell configuration and user plugins?

The shell loads its primary configuration from `~/.config/omarchy/shell.json`. If this file is absent, it falls back to a built-in default defined in `shell/shell.qml`. User-installed plugins belong in `~/.config/omarchy/plugins/<plugin-id>/`, while first-party plugins reside in the Omarchy installation directory under `shell/plugins/`.

### How do bar widgets differ from service plugins in the Quickshell architecture?

**Bar widgets** render interactive UI elements in the status bar via the `BarWidgetRegistry` and respond to `toggle` commands, while **service plugins** execute as hidden background processes using the `serviceHost` component. Services handle system functions like battery monitoring (`omarchy.battery`), idle detection (`omarchy.idle`), and notifications without displaying persistent interface elements.

### Can third-party developers create plugins for the Quickshell desktop shell?

Yes. Developers can create custom plugins by placing them in `~/.config/omarchy/plugins/<plugin-id>/` with a valid [`manifest.json`](https://github.com/basecamp/omarchy/blob/main/manifest.json) defining the plugin's `kinds` and entry points. The `PluginRegistry` automatically discovers these at startup, enabling extensions that integrate as bar widgets, overlays, or background services using the same APIs as first-party components.