# How the Omarchy Desktop Is Configured Using shell.json: A Complete Guide

> Learn how to configure the Omarchy desktop using shell.json. This guide covers UI configuration, user overrides, hot-reloading, and inline plugin settings.

- Repository: [37signals/omarchy](https://github.com/basecamp/omarchy)
- Tags: how-to-guide
- Published: 2026-08-28

---

**Omarchy’s Quickshell-based desktop loads its entire UI configuration from a versioned JSON file called [`shell.json`](https://github.com/basecamp/omarchy/blob/main/shell.json), which supports user overrides, hot-reloading, and inline plugin settings.**

The `basecamp/omarchy` repository implements a modular desktop environment where [`shell.json`](https://github.com/basecamp/omarchy/blob/main/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`](https://github.com/basecamp/omarchy/blob/main/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`](https://github.com/basecamp/omarchy/blob/quattro/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`](https://github.com/basecamp/omarchy/blob/main/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/main/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`](https://github.com/basecamp/omarchy/blob/quattro/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`](https://github.com/basecamp/omarchy/blob/main/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`](https://github.com/basecamp/omarchy/blob/main/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`](https://github.com/basecamp/omarchy/blob/main/shell.json) safely. These operations target `~/.config/omarchy/shell.json`, which overrides the defaults located at [`config/omarchy/shell.json`](https://github.com/basecamp/omarchy/blob/main/config/omarchy/shell.json).

Display the current bar layout:

```bash
jq '.bar.layout' ~/.config/omarchy/shell.json

```

Enable the weather plugin by adding its ID to the plugins array:

```bash
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:

```bash
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:

```bash
omarchy reload-config

```

## Summary

- [`shell.json`](https://github.com/basecamp/omarchy/blob/main/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`](https://github.com/basecamp/omarchy/blob/main/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`](https://github.com/basecamp/omarchy/blob/quattro/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`](https://github.com/basecamp/omarchy/blob/main/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`](https://github.com/basecamp/omarchy/blob/main/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`](https://github.com/basecamp/omarchy/blob/main/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`](https://github.com/basecamp/omarchy/blob/main/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`](https://github.com/basecamp/omarchy/blob/main/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`.