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
serviceHostcomponent for background processes. - Panel, Overlay, or Menu – Creates a
Loaderon demand; UI remains alive ifkeepLoaded:true. - Bar-widget – Registers with the
BarWidgetRegistryand integrates intoplugins/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 atbar/Bar.qmlwithkind: bar. - Omarchy Menu (
omarchy.menu) – Provides both a full menu (menu/Menu.qml) and a compact bar widget (menu/BarWidget.qml) with kindsmenuandbar-widget.
Background Services
Service plugins run hidden without persistent UI, handling system functions:
- Battery (
omarchy.battery) – Monitors power status atservices/battery/Service.qml. - Idle (
omarchy.idle) – Detects user inactivity viaservices/idle/Service.qml. - Night Light (
omarchy.nightlight) – Controls display temperature atservices/nightlight/Service.qml. - Lock Screen (
omarchy.lock) – Manages screen locking atlock/Service.qml. - Polkit Agent (
omarchy.polkit) – Handles authentication dialogs atpolkit/PolkitAgent.qml. - Notifications (
omarchy.notifications) – Manages notification dispatch atnotifications/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 atpanels/audio/Panel.qml. - Network (
omarchy.network) – Network status and connections atpanels/network/Panel.qml. - Bluetooth (
omarchy.bluetooth) – Device management atpanels/bluetooth/Panel.qml. - Clock (
omarchy.clock) – Time and calendar display atpanels/clock/BarWidget.qml. - Power (
omarchy.power) – Shutdown and reboot controls atpanels/power/Panel.qml. - Monitor (
omarchy.monitor) – Display settings atpanels/monitor/Panel.qml. - Tailscale (
omarchy.tailscale) – VPN status atpanels/tailscale/Panel.qml. - Weather (
omarchy.weather) – Weather information atpanels/weather/BarWidget.qml. - Agents (
omarchy.agents) – AI agent status atagents/Panel.qml.
Overlays and Utility Panels
These plugins provide on-demand floating interfaces:
- Image Picker (
omarchy.image-picker) – Wallpaper and image selection overlay atimage-picker/ImagePicker.qml. - Emojis (
omarchy.emojis) – Emoji picker atemojis/Emojis.qml. - Clipboard Manager (
omarchy.clipboard) – Clipboard history atclipboard/Clipboard.qml. - Reminders (
omarchy.reminders) – Quick note-taking atreminders/ReminderFlow.qml. - OSD (
omarchy.osd) – On-screen display notifications atosd/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 viaLoaderandserviceHostcomponents.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 bothshellPath + "/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 includingBarWidget.qmlandPanel.qmlreused across plugins.
Summary
- The Quickshell desktop shell is a QML runtime defined in
shell/shell.qmlthat serves as the foundation for the Omarchy desktop environment. - Three core registries (
PluginRegistry,BarWidgetRegistry, andAppLibrary) 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
Loaderelements. - First-party plugins reside in
shell/plugins/while user extensions go in~/.config/omarchy/plugins/, both following themanifest.jsoncontract. - IPC handlers allow external tools to summon interfaces, toggle widgets, and enable plugins dynamically using the
omarchy-shellCLI.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →