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

> Learn to add a custom bar widget to Omarchy easily. Follow this guide to create a plugin, implement a QML component, and register your new widget for enhanced functionality.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: how-to-guide
- Published: 2026-09-11

---

**You add a custom bar widget to Omarchy by creating a plugin package containing a [`manifest.json`](https://github.com/omacom/omarchy/blob/main/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`](https://github.com/omacom/omarchy/blob/main/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:

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

```

### Configure the Manifest

Create a [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) file that declares the widget type and entry point:

```json
{
  "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:

```qml
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:

```bash
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:

```json
{
  "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:

```bash

# 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`](https://github.com/omacom/omarchy/blob/main/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`](https://github.com/omacom/omarchy/blob/main/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.