How the Omarchy Desktop Environment Is Structured: A Deep Dive into the Quickshell Architecture
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 tasksshell/– Core Quickshell runtime containing the entry point (shell.qml), thePluginRegistry, and shared libraries inUi/andCommons/shell/plugins/– Modular features including the bar, lock screen, menu, and background services, each with amanifest.jsonand QML/JS implementationconfig/anddefault/– Templates copied to~/.config/omarchy/on first run (e.g.,default/omarchy/omarchy-menu.jsonc)migrations/– Timestamped scripts that evolve on-disk configuration across releasesmanual/anddocs/– End-user and developer documentation (e.g.,docs/omarchy-shell.md)default/fonts/anddefault/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.
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 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 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, a Service.qml file, and supporting JavaScript models such as 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.
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:
{
"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/withmanifest.jsondeclarations - Clear separation: CLI tools live in
bin/, configuration templates indefault/, and runtime logic inshell/ - Live configuration: The desktop reads from
~/.config/omarchy/and supports automatic migrations via timestamped scripts inmigrations/ - 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 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.
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 →