How to Configure the Omarchy Bar Using shell.json

The Omarchy bar is configured entirely through the shell.json file located at ~/.config/omarchy/shell.json, which defines the bar's position, transparency, widget layout, and plugin ID without requiring deep-merging with default settings.

The Omarchy desktop environment stores its bar configuration in a declarative JSON file that controls widget placement, visual styling, and plugin selection. This guide explains how shell.json structures the bar layout, how the Omarchy shell loads these settings from shell/shell.qml, and how to customize your desktop panel according to the basecamp/omarchy source code.

Understanding the shell.json Structure

Core Bar Configuration Fields

The bar object in shell.json contains six primary fields that determine how the Omarchy bar renders:

  • id: Specifies the plugin ID for the bar implementation. If set to omarchy.bar or omitted, the built-in bar loads; any other ID referencing a plugin with "kind": "bar" replaces it entirely as determined by selectedBarId → activeBarId logic in shell/shell.qml (lines 66-74).
  • position: Accepts "top" or "bottom" to anchor the bar to the screen edge.
  • transparent: Boolean flag controlling background transparency, toggleable via toggleBarTransparency() in the shell IPC.
  • centerAnchor: Widget ID (e.g., omarchy.clock) that receives focus when the bar centers.
  • layout: Object containing three arrays—left, center, and right—defining widget order and configuration. The shell builds the bar by iterating over shell.barConfig.layout and creating a BarWidget for every entry.

Plugin Definitions

The root plugins array stores non-bar plugins (panels, overlays, services) separately from the bar layout. Each widget entry in the layout arrays requires at least an id field and supports plugin-specific options like format for clock widgets.

Configuration Loading and Override Behavior

When the Omarchy shell initializes, it searches for shell.json in two locations:

  1. Default configuration: config/omarchy/shell.json (bundled with the application)
  2. User override: ~/.config/omarchy/shell.json (canonical source when present)

According to the source code in shell/shell.qml (lines 72-78), the shell performs no deep-merge between these files. If the user-owned file exists and parses correctly, it completely replaces the default configuration. The JSON must contain "version": 1 for validation.

Live Reload and Runtime Persistence

The Omarchy shell watches shell.json for changes using a FileView with watchChanges: true. When modifications occur, the shell triggers applyShellConfig() (defined in shell/shell.qml, lines 30-38), reparses the JSON, and updates the barConfig property to refresh the UI without requiring a restart.

Runtime changes persist back to disk via persistShellConfig() (lines 8-13), which always writes the version: 1 field. When you rearrange widgets using omarchy bar move, the system calls pluginRegistry.moveBarWidget() to manipulate the layout arrays and writes the updated order to ~/.config/omarchy/shell.json.

Practical Configuration Examples

Default Bar Layout

The bundled config/omarchy/shell.json demonstrates standard widget organization:

{
  "version": 1,
  "idle": { "screensaver": 150, "lock": 300 },
  "bar": {
    "id": "omarchy.bar",
    "position": "top",
    "transparent": false,
    "centerAnchor": "omarchy.clock",
    "layout": {
      "left":   [ { "id": "omarchy.menu" }, { "id": "omarchy.workspaces" } ],
      "center": [ { "id": "omarchy.clock", "format": "HH:mm" } ],
      "right":  [ { "id": "omarchy.audio" } ]
    }
  },
  "plugins": []
}

Replacing the Built-in Bar

To use a custom bar implementation, specify a different plugin ID that declares "kinds": ["bar"]:

{
  "version": 1,
  "bar": {
    "id": "my.user.custom-bar",
    "position": "bottom",
    "transparent": true,
    "layout": {
      "left":   [ { "id": "omarchy.menu" } ],
      "center": [ { "id": "my.user.custom-clock", "format": "HH:mm" } ],
      "right":  [ { "id": "omarchy.audio" } ]
    }
  },
  "plugins": []
}

Adding Widgets via CLI

Add new widgets to specific sections using the command line:

omarchy bar add --id omarchy.network --section right

This invokes pluginRegistry.putBarWidget() to insert { "id": "omarchy.network" } into bar.layout.right and triggers persistShellConfig() to save the change.

Summary

  • The Omarchy bar configuration resides in ~/.config/omarchy/shell.json, which completely overrides the default at config/omarchy/shell.json when present.
  • The bar object controls position (top/bottom), transparency, center anchor, and widget layout through left, center, and right arrays.
  • Changes to shell.json apply immediately via file watching and applyShellConfig() without restarting the shell.
  • Runtime modifications persist through persistShellConfig(), ensuring widget reordering and settings updates survive across sessions.
  • Custom bar plugins replace the built-in implementation by setting bar.id to a plugin with "kind": "bar".

Frequently Asked Questions

Where is the shell.json file located?

The canonical location is ~/.config/omarchy/shell.json for user-specific settings, while the default configuration ships at config/omarchy/shell.json within the Omarchy installation directory. The shell only reads the user file if it exists and validates successfully against the version: 1 requirement.

Does Omarchy merge user configuration with default settings?

No. As implemented in shell/shell.qml (lines 72-78), the shell performs no deep-merge. If ~/.config/omarchy/shell.json exists, it completely replaces the default configuration. You must define the entire bar object and any required plugins in your user file.

How do I make the Omarchy bar transparent?

Set "transparent": true in the bar object of shell.json. This boolean controls whether the bar background draws transparently, and can also be toggled at runtime through the toggleBarTransparency() method exposed via the shell IPC.

Can I use a custom bar plugin instead of the built-in one?

Yes. Set bar.id to any plugin ID that declares "kinds": ["bar"] in its manifest. When the shell initializes and reads selectedBarId (lines 66-74 in shell/shell.qml), it loads your custom plugin instead of the default omarchy.bar implementation.

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 →