# How to Configure the Bar Layout in Omarchy Quickshell: A Complete Guide

> Learn to configure the bar layout in Omarchy Quickshell. Master widget positioning using shell.json for a personalized terminal experience. Full guide and CLI tips included.

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

---

**Omarchy's bar layout is controlled entirely by the `bar` subtree in `~/.config/omarchy/shell.json`, which defines widget positions in left, center, and right sections, with live reload support and CLI helpers for runtime adjustments.**

The Omarchy desktop environment uses Quickshell to render its modular status bar, driving the UI through a declarative JSON configuration. Unlike traditional panel systems that require graphical editors or theme hacks, Omarchy exposes all bar positioning, transparency, and widget arrangement through a single configuration object that reloads instantly on change.

## Understanding the Bar Configuration Schema

The configuration lives in the `bar` object within `$HOME/.config/omarchy/shell.json`. The `Bar.qml` component (located at `shell/plugins/bar/Bar.qml`) injects this configuration as the `barConfig` property and builds three distinct sections—**left**, **center**, and **right**—from ordered arrays of widget IDs.

Key configuration fields include:

- **`position`** – Anchors the bar to `"top"`, `"bottom"`, `"left"`, or `"right"` of the screen.
- **`transparent`** – Boolean flag enabling transparent background mode with dynamic foreground color calculation.
- **`centerAnchor`** – Widget ID (e.g., `"omarchy.clock"`) that splits the center section into three logical parts.
- **`layout`** – Object containing `left`, `center`, and `right` arrays defining widget order.

The special widget ID `"omarchy.tray"` receives automatic handling: `BarModel.normalizeLayout()` (in [`shell/plugins/bar/BarModel.js`](https://github.com/basecamp/omarchy/blob/main/shell/plugins/bar/BarModel.js)) pins the tray widget to the inner edge of its assigned section, ensuring it always sits adjacent to the screen edge.

## Configuring Widget Layout via shell.json

Direct editing provides the most granular control over bar composition. When [`shell.json`](https://github.com/basecamp/omarchy/blob/main/shell.json) changes, the `FileView` watcher at the bottom of `Bar.qml` (lines 73‑78) triggers `applyBarConfig()`, which copies the on-disk configuration into the local `layoutConfig` state.

### Basic Layout Structure

```json
{
  "bar": {
    "position": "top",
    "transparent": true,
    "centerAnchor": "omarchy.clock",
    "layout": {
      "left": ["omarchy.workspaces", "omarchy.tray"],
      "center": [],
      "right": ["omarchy.battery", "omarchy.media"]
    }
  }
}

```

### Adding Custom Widgets

Define custom entries using arbitrary IDs. The `ModuleSlot` component (lines 27‑55 of `Bar.qml`) resolves each entry through the `barWidgetRegistry` or loads custom implementations:

```json
{
  "bar": {
    "layout": {
      "left": ["omarchy.workspaces"],
      "center": ["myweather"],
      "right": ["omarchy.battery"]
    }
  }
}

```

Create the corresponding QML file at `~/.config/omarchy/bar/modules/myweather.qml`. The path resolution is handled by `BarModel.expandPath()` (lines 4‑9 of [`BarModel.js`](https://github.com/basecamp/omarchy/blob/main/BarModel.js)).

## Using CLI Helpers to Modify the Layout

Omarchy provides command-line utilities that invoke `shell.mutateShellConfig` to update the bar without manual JSON editing.

### Moving Widgets Dynamically

The `omarchy-bar-move` command repositions widgets via the `dropBarModule()` → `moveModuleInConfig()` chain (see lines 45‑68 of `Bar.qml`):

```bash
omarchy-bar-move omarchy.battery right omarchy.tray

```

This moves the battery widget to the right section, placing it before the tray widget.

### Toggling Transparency

Activate or deactivate transparent mode using the dedicated toggle command or by double-clicking the bar (handled by `CenterGestureArea` at lines 66‑70):

```bash
omarchy-toggle-bar-transparency

```

This executes `toggleTransparency()` (lines 17‑27), which flips the `config.bar.transparent` boolean and triggers `scheduleTransparentForegroundRefresh()`.

## Custom Widget Implementation Types

The bar supports two custom module types, distinguished by `ModuleSlot` during instantiation:

**QML Custom Modules** – Specify a `source` path or rely on auto-loading from `~/.config/omarchy/bar/modules/<id>.qml`. These must expose `open` and `close` methods if they include panels.

**Command Modules** – Set an `exec` property with a shell command string. [`BarModel.js`](https://github.com/basecamp/omarchy/blob/main/BarModel.js) (lines 21‑22) infers the type as `"command"` and loads the appropriate loader backend.

Example command-based widget:

```json
{
  "id": "custom-script",
  "exec": "~/.config/omarchy/scripts/status.sh"
}

```

## Advanced Layout Features

### Center Anchoring

When `centerAnchor` specifies a widget ID (typically `"omarchy.clock"`), the center section splits into three segments: widgets before the anchor, the anchored widget itself, and widgets after. This prevents center-section widgets from shifting when neighboring sections resize.

### Tray Pinning Behavior

Regardless of its position in the `layout` arrays, `"omarchy.tray"` always pins to the inner edge (left side when in the left section, right side when in the right section). This behavior is enforced by `BarModel.normalizeLayout()` during configuration loading.

## How Live Reload Works

The bar implements sophisticated delta detection to minimize UI disruption. When `applyBarConfig()` detects a configuration change:

1. **Structural changes** trigger a full rebuild of the `ModuleList` loaders for the affected sections.
2. **Inline settings changes** invoke `BarModel.inlineSettingsDelta()` to compute property differences, updating existing widgets without destroying their `PanelWindow` instances.

This architecture ensures that editing [`shell.json`](https://github.com/basecamp/omarchy/blob/main/shell.json) with any text editor reflects immediately, while preserving panel states when possible.

## Summary

- Omarchy bar configuration resides in the `bar` object of `~/.config/omarchy/shell.json`, consumed by `Bar.qml` and processed through [`BarModel.js`](https://github.com/basecamp/omarchy/blob/main/BarModel.js).
- Layouts define three sections (`left`, `center`, `right`) as ordered arrays of widget IDs, with `"omarchy.tray"` automatically pinned to inner edges.
- Custom widgets load from `~/.config/omarchy/bar/modules/<id>.qml` for QML components or via `exec` strings for command-based modules.
- CLI tools like `omarchy-bar-move` and `omarchy-toggle-bar-transparency` wrap the configuration mutation API for runtime adjustments.
- The system uses `inlineSettingsDelta()` to apply changes without full rebuilds when only widget properties change.

## Frequently Asked Questions

### How do I add a new widget to the Omarchy bar?

Add the widget ID to the appropriate `layout` array in `~/.config/omarchy/shell.json`. For built-in widgets, use their registry ID (e.g., `"omarchy.weather"`). For custom widgets, create a QML file at `~/.config/omarchy/bar/modules/<your-id>.qml` and reference `<your-id>` in the JSON array.

### Why does the tray widget move to the edge even when I put it in the middle of the list?

The `BarModel.normalizeLayout()` function in [`shell/plugins/bar/BarModel.js`](https://github.com/basecamp/omarchy/blob/main/shell/plugins/bar/BarModel.js) automatically pins `"omarchy.tray"` to the inner edge of its section (leftmost in the left section, rightmost in the right section) regardless of its array position. This ensures consistent anchoring behavior across different layouts.

### How can I make the bar transparent or change its position?

Set `"transparent": true` in the `bar` configuration object, or run `omarchy-toggle-bar-transparency` from the terminal. Change the `"position"` field to `"top"`, `"bottom"`, `"left"`, or `"right"` to anchor the bar to different screen edges; `Bar.qml` automatically adjusts the `ModuleList` orientation between horizontal and vertical based on this value.

### What happens if I edit [`shell.json`](https://github.com/basecamp/omarchy/blob/main/shell.json) while the shell is running?

The `FileView` watcher in `Bar.qml` detects file changes immediately and calls `applyBarConfig()`. If you modified only widget settings (like colors or labels), `BarModel.inlineSettingsDelta()` applies the changes to existing widgets without rebuilding the bar surface. Structural changes (adding or moving widgets) trigger a section rebuild.