How to Configure the Bar Layout in Omarchy Quickshell: A Complete Guide
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 containingleft,center, andrightarrays defining widget order.
The special widget ID "omarchy.tray" receives automatic handling: BarModel.normalizeLayout() (in 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 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
{
"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:
{
"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).
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):
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):
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 (lines 21‑22) infers the type as "command" and loads the appropriate loader backend.
Example command-based widget:
{
"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:
- Structural changes trigger a full rebuild of the
ModuleListloaders for the affected sections. - Inline settings changes invoke
BarModel.inlineSettingsDelta()to compute property differences, updating existing widgets without destroying theirPanelWindowinstances.
This architecture ensures that editing shell.json with any text editor reflects immediately, while preserving panel states when possible.
Summary
- Omarchy bar configuration resides in the
barobject of~/.config/omarchy/shell.json, consumed byBar.qmland processed throughBarModel.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>.qmlfor QML components or viaexecstrings for command-based modules. - CLI tools like
omarchy-bar-moveandomarchy-toggle-bar-transparencywrap 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 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 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.
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 →