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.json drives the entire Omarchy desktop UI, controlling the bar layout, enabled plugins, and widget-specific settings.
  • The loading hierarchy prioritizes ~/.config/omarchy/shell.json over the bundled config/omarchy/shell.json, with automatic fallback to defaults on errors.
  • The schema requires "version": 1 and supports three primary keys: bar for layout, plugins for module activation, and plugin-specific IDs for inline configuration.
  • shell/shell.qml implements hot-reloading and error handling, allowing live UI updates without session restarts.
  • Use the omarchy bar CLI or jq commands 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:

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 →