How the Omarchy Desktop Is Configured Using shell.json: A Complete Guide
Omarchy’s Quickshell-based desktop loads its entire UI configuration from a versioned JSON file called shell.json, which supports user overrides, hot-reloading, and inline plugin settings.
The basecamp/omarchy repository implements a modular desktop environment where shell.json serves as the single source of truth for the omnipresent bar layout, enabled plugins, and per-widget settings. Understanding how this file is parsed and prioritized allows you to customize your Omarchy desktop without touching source code.
Understanding the shell.json Loading Hierarchy
Omarchy employs a cascading configuration system that prioritizes user preferences while maintaining safe fallbacks.
Default Bundled Configuration
On startup, the shell first locates the default configuration bundled with the repository at config/omarchy/shell.json. This file contains the baseline schema specifying the default bar layout and core plugins. The host QML file shell/shell.qml defines this path via the defaultsPath property around line 73, ensuring the desktop can always boot into a working state.
User Override Behavior
If a user-specific file exists at ~/.config/omarchy/shell.json, the shell parses this first and overlays its values onto the defaults. A valid user configuration completely overrides the bundled defaults for any keys specified. If the user file is missing or contains malformed JSON, the shell silently falls back to the bundled defaults and emits console warnings (see the error-handling logic in shell.qml lines 82–102).
Schema Structure and Key Configuration Sections
The shell.json schema requires "version": 1 at the root. The configuration is organized into three primary domains that control every aspect of the desktop UI.
The Bar Layout Configuration
The bar key defines the omnipresent bar’s structure through left, center, and right arrays containing widget IDs. The [shell/plugins/bar/README.md](https://github.com/basecamp/omarchy/blob/quattro/shell/plugins/bar/README.md) documents this shape in detail, including optional appearance settings like margins and spacing. Each entry in the layout arrays corresponds to a registered plugin module.
Enabling Plugins
The plugins array contains string IDs of modules that shell/services/PluginRegistry.qml validates and loads at runtime. Only plugins listed in this array are instantiated; omitting an ID disables the plugin entirely. For example, adding "omarchy.weather" to this array activates the weather panel.
Inline Module Settings
Individual widgets or plugins can store per-instance configuration under their own ID keys at the root level. This allows granular customization without separate files. For instance, the clock widget reads its format from an omarchy.clock object, while the weather panel reads from omarchy.weather. The source files shell/plugins/panels/clock/Panel.qml and shell/plugins/panels/weather/Panel.qml implement this pattern.
Hot-Reloading and Error Handling
Omarchy monitors the user’s shell.json for changes using the host QML engine. When the file is modified, the shell re-parses the JSON and updates the UI without requiring a restart. This hot-reload mechanism depends on the file maintaining valid JSON syntax and the required version field. If parsing fails, the shell immediately reverts to the bundled defaults and prints diagnostic warnings to the console, ensuring the desktop remains usable even after a bad edit.
Programmatic Configuration via CLI
While manual editing is supported, the canonical way to modify shell.json is through the omarchy bar CLI command group. This utility writes directly to ~/.config/omarchy/shell.json, preserving JSON integrity and schema compliance. After making changes—whether manually or via CLI—you can apply them immediately using the omarchy reload-config helper.
Practical Configuration Examples
Use jq to query and modify your shell.json safely. These operations target ~/.config/omarchy/shell.json, which overrides the defaults located at config/omarchy/shell.json.
Display the current bar layout:
jq '.bar.layout' ~/.config/omarchy/shell.json
Enable the weather plugin by adding its ID to the plugins array:
jq '.plugins += ["omarchy.weather"] | unique' \
~/.config/omarchy/shell.json > /tmp/tmp.json && mv /tmp/tmp.json ~/.config/omarchy/shell.json
Configure the clock widget to use 24-hour format via inline settings:
jq '.["omarchy.clock"].format = "HH:mm"' \
~/.config/omarchy/shell.json > /tmp/tmp.json && mv /tmp/tmp.json ~/.config/omarchy/shell.json
Apply changes without restarting:
omarchy reload-config
Summary
shell.jsondrives the entire Omarchy desktop UI, controlling the bar layout, enabled plugins, and widget-specific settings.- The loading hierarchy prioritizes
~/.config/omarchy/shell.jsonover the bundledconfig/omarchy/shell.json, with automatic fallback to defaults on errors. - The schema requires
"version": 1and supports three primary keys:barfor layout,pluginsfor module activation, and plugin-specific IDs for inline configuration. shell/shell.qmlimplements hot-reloading and error handling, allowing live UI updates without session restarts.- Use the
omarchy barCLI orjqcommands to modify configuration values programmatically while maintaining JSON validity.
Frequently Asked Questions
Where is the shell.json file located?
Omarchy uses two locations: the default configuration ships with the repository at config/omarchy/shell.json, while your personal overrides belong at ~/.config/omarchy/shell.json in your home directory. The shell always attempts to load the user copy first; if it is absent or corrupted, the system falls back to the bundled defaults.
What happens if shell.json contains invalid JSON?
If the user’s shell.json contains syntax errors or missing required fields like "version": 1, the shell rejects the file and loads the bundled defaults from config/omarchy/shell.json instead. Console warnings are emitted to alert you of the specific parsing failure, and the desktop continues running without the broken configuration.
How do I enable or disable plugins in Omarchy?
Add or remove the plugin’s ID string from the plugins array in your shell.json. For example, to enable the weather panel, ensure "omarchy.weather" appears in the array managed by PluginRegistry.qml. Removing the ID disables the plugin on the next reload. You can verify the change instantly using omarchy reload-config.
Can I configure individual widget settings in shell.json?
Yes. Each widget or plugin can read its own configuration object stored under its ID key at the root of shell.json. For example, the clock widget looks for settings under "omarchy.clock", allowing you to specify formats, timezones, or styling without modifying the plugin’s source code in shell/plugins/panels/clock/Panel.qml.
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 →