How to Add a Custom Bar Widget to the Omarchy Bar Layout: A Complete Guide

You add a custom bar widget to Omarchy by creating a plugin package containing a manifest.json that declares "kinds": ["bar-widget"], implementing a QML component that extends the BarWidget base class, and registering it via the omarchy putBarWidget CLI command or manual configuration in shell.json.

Omarchy is an open-source Qt/QML shell environment that supports extensible top-bar widgets through a modular plugin system. Understanding how to add a custom bar widget requires familiarity with the omacom/omarchy repository architecture, specifically how PluginRegistry detects bar-widget plugins and how BarWidgetRegistry manages their lifecycle.

Understanding the Bar Widget Architecture

The Omarchy top bar is composed of bar-widget plugins managed by three core components from the source code:

  • PluginRegistry (shell/services/PluginRegistry.qml): Scans plugin directories and identifies packages with "kinds": ["bar-widget"]. It determines default placement using the defaultBarWidgetSection(manifest) logic.
  • BarWidgetRegistry (shell/plugins/bar/BarWidgetRegistry.qml): Instantiates live widget instances and tracks their state within the bar layout.
  • BarWidget Base Class (shell/Ui/BarWidget.qml): Provides the required interface that all widgets must extend, including standard properties like id, icon, and tooltip.

When a widget is enabled, the registry loads the QML file specified in the manifest's "barWidget" field and inserts it into the requested section (left, center, or right) of the bar layout.

Step 1: Create the Plugin Package

All custom widgets reside in the user plugins directory at ~/.config/omarchy/plugins/.

Directory Structure

Each widget requires a dedicated folder named after its unique plugin ID:

mkdir -p ~/.config/omarchy/plugins/com.example.mywidget

Configure the Manifest

Create a manifest.json file that declares the widget type and entry point:

{
  "id": "com.example.mywidget",
  "kinds": ["bar-widget"],
  "barWidget": "BarWidget.qml",
  "defaultSection": "right"
}

The "defaultSection" field specifies initial placement (left, center, or right) when the widget is first enabled.

Step 2: Implement the Widget Component

Your widget must extend the BarWidget base class defined in shell/Ui/BarWidget.qml. This ensures compatibility with the bar's rendering and IPC systems.

Create BarWidget.qml in your plugin directory:

import QtQuick 2.15
import QtQuick.Layouts 1.15
import "qrc:/shell/Ui" as Ui

Ui.BarWidget {
    id: root
    
    // Override base class properties
    icon: "qrc:/icons/custom.svg"
    tooltip: "My Custom Tool"
    
    // Custom UI implementation
    MouseArea {
        anchors.fill: parent
        onClicked: {
            console.log("Widget activated");
            // Add custom click handling logic here
        }
    }
}

The base class handles integration with the bar's click handling and pop-out panels, allowing you to focus on the UI content.

Step 3: Enable and Position the Widget

Once the plugin files are in place, you must register the widget with the bar layout using one of two methods.

Using the CLI Command

The shell/shell.qml file implements the putBarWidget function, which exposes a CLI interface:

omarchy putBarWidget com.example.mywidget '{"section":"right"}'

This command inserts the widget into the specified section of ~/.config/omarchy/shell.json and triggers the BarWidgetRegistry to load the component immediately.

Manual Configuration

Alternatively, edit ~/.config/omarchy/shell.json directly. Add your widget to the desired layout section:

{
  "bar": {
    "layout": {
      "left": [...],
      "center": [...],
      "right": [
        { "id": "com.example.mywidget" }
      ]
    }
  }
}

The PluginRegistry detects the change and instantiates the widget on the next bar refresh.

Complete Working Example

Here is a full setup script that creates a functional custom widget:


# Create plugin structure

PLUGIN_DIR="$HOME/.config/omarchy/plugins/com.example.sysmonitor"
mkdir -p "$PLUGIN_DIR"

# Write manifest

cat > "$PLUGIN_DIR/manifest.json" << 'EOF'
{
  "id": "com.example.sysmonitor",
  "kinds": ["bar-widget"],
  "barWidget": "BarWidget.qml",
  "defaultSection": "right"
}
EOF

# Write widget implementation

cat > "$PLUGIN_DIR/BarWidget.qml" << 'EOF'
import QtQuick 2.15
import QtQuick.Layouts 1.15
import "qrc:/shell/Ui" as Ui

Ui.BarWidget {
    id: root
    icon: "qrc:/icons/cpu.svg"
    tooltip: "System Monitor"
    
    Text {
        anchors.centerIn: parent
        text: "CPU"
        color: "white"
        font.pointSize: 8
    }
    
    MouseArea {
        anchors.fill: parent
        onClicked: console.log("Opening system monitor...")
    }
}
EOF

# Enable via CLI

omarchy putBarWidget com.example.sysmonitor '{"section":"right"}'

Summary

  • Plugin Structure: Place manifests and QML files in ~/.config/omarchy/plugins/<id>/.
  • Manifest Requirements: Declare "kinds": ["bar-widget"] and specify "barWidget": "YourFile.qml".
  • Base Class: Extend BarWidget from shell/Ui/BarWidget.qml to ensure proper integration.
  • Registration: Use omarchy putBarWidget <id> '{"section":"position"}' or edit shell.json to add the widget to bar.layout.left, center, or right.
  • Registry Flow: PluginRegistry detects the plugin, BarWidgetRegistry instantiates it, and shell.qml manages placement via putBarWidget.

Frequently Asked Questions

What is the base class for omarchy bar widgets?

All bar widgets must extend BarWidget, defined in shell/Ui/BarWidget.qml. This base class provides essential properties like id, icon, and tooltip, and handles integration with the bar's IPC and rendering systems.

How do I specify the default section for my widget?

Include a "defaultSection" field in your manifest.json with a value of "left", "center", or "right". When the PluginRegistry in shell/services/PluginRegistry.qml processes your plugin, it uses this value to determine initial placement via the defaultBarWidgetSection logic.

Can I move a widget after adding it?

Yes. Use the moveBarWidget function available in shell/shell.qml via the CLI, or manually edit the bar.layout sections in ~/.config/omarchy/shell.json. Moving a widget updates its position in the layout array without requiring a plugin reload.

Where is the bar layout configuration stored?

The active bar layout is stored in ~/.config/omarchy/shell.json under the bar.layout object. This JSON file contains three arrays (left, center, right) listing the widget IDs currently displayed in each section.

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 →