Quickshell Desktop Configuration (shell.json) Structure in Omarchy: Complete Guide
The shell.json file in Omarchy is a versioned JSON configuration that defines the status bar layout, enabled plugins, and global desktop settings for the Quickshell-based environment.
The Omarchy repository uses Quickshell as its lightweight QML-based shell. Understanding the shell.json structure is essential for customizing your desktop or developing new plugins. This guide breaks down every field, loading mechanism, and validation test based on the actual source code implementation.
Location and Loading Priority
The Quickshell host resolves configuration through a two-tier system:
- Default configuration —
config/omarchy/shell.jsonbundled with the repository - User override —
~/.config/omarchy/shell.json(complete replacement, no deep-merge)
In shell/shell.qml at line 73, the runtime implements file watching for hot-reload. When the user edits their config, the shell updates bar layout and enabled plugins without restart.
The test suite at test/shell.d/config-test.sh line 16 verifies this override behavior: if the user file exists and parses as valid JSON, it replaces defaults entirely.
Top-Level Structure Overview
Every shell.json file must contain three core keys:
| Key | Type | Required | Description |
|---|---|---|---|
version |
integer | Yes | Schema version; current default is 1 |
bar |
object | Yes | Status bar configuration with layout arrays |
plugins |
array of strings | Yes | List of plugin IDs to load |
Optional top-level keys include theme (string) and settings (object) for plugin-specific global configuration.
Bar Configuration (bar)
The bar object controls the status bar appearance and widget arrangement.
Core Fields
- id (string, optional): Identifier for the bar instance, used by migration scripts
- transparent (boolean): Controls background transparency; defaults to
falseper runtime-smoke-test.sh line 298 - layout (object): Contains three arrays defining widget placement
Layout Structure
The layout object requires exactly three keys:
{
"bar": {
"id": "main-bar",
"transparent": false,
"layout": {
"left": [],
"center": [],
"right": []
}
}
}
Each array holds widget entries in display order. The config-test.sh suite validates that all three arrays exist and are parseable.
Widget Entry Format
Individual widgets are objects with this structure:
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Widget module name (e.g., omarchy.clock, omarchy.battery) |
settings |
object | No | Inline configuration overriding plugin defaults |
Example entry with settings:
{
"id": "omarchy.battery",
"settings": {
"showPercentage": true
}
}
The runtime-smoke-test.sh line 293 verifies that default widget IDs like omarchy.clock are present in valid configurations.
Plugins Array
The top-level plugins field lists enabled plugin IDs as strings:
"plugins": [
"omarchy.workspaces",
"omarchy.clock",
"omarchy.tray",
"omarchy.battery"
]
Plugin activation follows two paths per PluginRegistry.qml at line 110:
- Explicit: ID appears in the
pluginsarray - Implicit: Widget entry in bar layout references the plugin ID
The registry resolves these IDs to QML module paths and instantiates corresponding plugin components.
Complete Configuration Example
Putting it together, a production-ready shell.json:
{
"version": 1,
"bar": {
"id": "main-bar",
"transparent": false,
"layout": {
"left": [
{ "id": "omarchy.workspaces" }
],
"center": [
{ "id": "omarchy.clock" }
],
"right": [
{ "id": "omarchy.tray" },
{
"id": "omarchy.battery",
"settings": { "showPercentage": true }
}
]
}
},
"plugins": [
"omarchy.workspaces",
"omarchy.clock",
"omarchy.tray",
"omarchy.battery"
],
"theme": "default"
}
Hot-Reload and Runtime Behavior
The Quickshell host monitors configuration files using Qt's file system watcher. When shell.json changes:
- JSON validity is checked
- If valid, the entire configuration replaces the current state
- Bar layout rebuilds with new widget arrangement
- Plugin registry updates enabled set
- Theme re-applies if changed
This implementation in shell/shell.qml enables rapid iteration without session restart.
Key Source Files
| Path | Purpose |
|---|---|
config/omarchy/shell.json |
Default configuration template |
shell/shell.qml |
QML host, config loading and hot-reload |
shell/services/PluginRegistry.qml |
Plugin resolution from JSON IDs |
test/shell.d/config-test.sh |
Schema validation tests |
test/shell.d/runtime-smoke-test.sh |
Runtime behavior verification |
shell/plugins/bar/README.md |
Widget ID documentation |
Summary
shell.jsonis versioned via theversionfield (currently1)bar.layoutuses three arrays (left,center,right) of widget entries- Widget entries require
idand optionally includesettings pluginsarray lists explicitly enabled plugins; implicit activation occurs through widget references- User override at
~/.config/omarchy/shell.jsonreplaces defaults completely - Hot-reload watches file changes and updates runtime without restart
PluginRegistry.qmlresolves IDs to QML modules at line 110
Frequently Asked Questions
What happens if shell.json has invalid JSON syntax?
The shell rejects the configuration and falls back to the default bundled in config/omarchy/shell.json. The runtime logs the parse error but continues operation with known-good defaults.
Can I use multiple bars with different configurations?
The current schema supports a single bar object. Multiple bar instances would require distinct configuration files and separate Quickshell process launches, which Omarchy does not implement by default.
Do I need to list a plugin in both plugins and bar.layout?
No. Per PluginRegistry.qml, plugins activate through either mechanism. However, listing in plugins ensures initialization even if no widget currently uses the plugin, which matters for background services like notifications.
How do I find available widget IDs for my layout?
Consult shell/plugins/bar/README.md in the repository for documented widget identifiers, or examine the plugin directories under shell/plugins/—each valid widget exports its ID through the plugin manifest.
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 →