Quickshell Desktop Shell in Omarchy: Architecture and Plugin Ecosystem

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.
property PluginRegistry pluginRegistry: PluginRegistry { }
property BarWidgetRegistry barWidgetRegistry: BarWidgetRegistry { }
property AppLibrary appLibrary: AppLibrary { }

(see lines 11‑19 of shell/shell.qml)

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:

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)

The shell parses 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:

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

(see lines 34‑53 of shell/shell.qml)

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)

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 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/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:

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)

Managing Bar Widgets

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

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)

Querying and Enabling Plugins Dynamically

List all installed plugins with their metadata:

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:

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)

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 – 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 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 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.

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 →