# Understanding the Different Plugin Kinds in Omarchy: A Complete Guide

> Explore the six plugin kinds in Omarchy bar bar-widget service panel background and agents to understand component integration and rendering in the Quickshell desktop environment.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: deep-dive
- Published: 2026-08-30

---

**Omarchy defines six distinct plugin kinds—`bar`, `bar-widget`, `service`, `panel`, `background`, and `agents`—that determine how components are instantiated, rendered, and integrated into the Quickshell-based desktop environment.**

The Omarchy desktop environment ([omacll/omarchy](https://github.com/omacll/omarchy)) implements a **manifest-driven plugin architecture** where every extension lives under `shell/plugins/`. Each plugin contains a [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) that declares its **plugin kinds** in a `kinds` array, instructing the runtime whether to load the component as a UI widget, background service, or standalone panel.

## The Six Plugin Kinds in Omarchy

### bar

The `bar` kind represents the top-level status bar that anchors the desktop. Only one bar plugin can exist at a time. The manifest at [`shell/plugins/bar/manifest.json`](https://github.com/omacom/omarchy/blob/main/shell/plugins/bar/manifest.json) declares `"kinds": ["bar"]` and specifies the entry point as `"bar": "Bar.qml"`. This single instance houses all active `bar-widget` plugins and manages the primary interface layout.

### bar-widget

Plugins with the `bar-widget` kind render interactive elements inside the bar, such as clocks, battery indicators, or workspace switchers. Multiple bar-widgets can coexist within a single bar instance. The Weather widget at [`shell/plugins/panels/weather/manifest.json`](https://github.com/omacom/omarchy/blob/main/shell/plugins/panels/weather/manifest.json) uses `"kinds": ["bar-widget"]` with an entry point of `"barWidget": "BarWidget.qml"`. The bar's QML iterates over enabled widget entry points and places them in configured sections (top, center, bottom).

### service

The `service` kind defines long-running background processes that provide data without rendering UI directly. These supply state to other plugins via the Quickshell IPC system (`shell_ipc`). The Nightlight service at [`shell/plugins/services/nightlight/manifest.json`](https://github.com/omacom/omarchy/blob/main/shell/plugins/services/nightlight/manifest.json) monitors color temperature and exposes properties that widgets consume, starting automatically when the shell initializes.

### panel

`panel` plugins are self-contained popup interfaces triggered on demand, such as Wi-Fi QR codes or Tailscale status displays. These are not embedded in the bar but opened via commands like `omarchy-panel-open omarchy.wifiqr`. The manifest at [`shell/plugins/panels/wifiqr/manifest.json`](https://github.com/omacom/omarchy/blob/main/shell/plugins/panels/wifiqr/manifest.json) declares `"panel": "Panel.qml"`, creating instantiable overlays separate from the main bar workflow.

### background

Reserved for internal use, the `background` kind controls desktop wallpaper layers and full-screen visual effects. It loads as a separate QML layer behind all other UI elements. The reference implementation lives at [`shell/plugins/background/manifest.json`](https://github.com/omacom/omarchy/blob/main/shell/plugins/background/manifest.json) with the entry point `"background": "Background.qml"`, managing the desktop canvas independently of interactive components.

### agents

The `agents` kind covers lightweight helper plugins that expose thin QML APIs for data publishing. Though often declaring `bar-widget` in their manifests, these internal components follow the architectural pattern defined in [`shell/plugins/agents/manifest.json`](https://github.com/omacom/omarchy/blob/main/shell/plugins/agents/manifest.json). They function as supporting infrastructure that other plugins query for specialized functionality.

## How Plugin Kinds Interact

The bar loads all enabled `bar-widget` plugins by scanning the `kinds` array in each manifest, dynamically instantiating widgets in their configured positions. Services start automatically with the shell lifecycle, exposing properties through the `OmarchyService` namespace that widgets reference via property bindings. Panels remain dormant until explicitly invoked through CLI commands or button triggers defined within bar-widgets. Background and agent plugins operate as supporting infrastructure, maintaining clean separation between visual and functional concerns.

## Manifest Schema and Validation

Every plugin must conform to the **plugin-registry contract** enforced by [`test/shell.d/plugin-registry-contract-test.sh`](https://github.com/omacom/omarchy/blob/main/test/shell.d/plugin-registry-contract-test.sh). The contract requires that each value in the `kinds` array has a corresponding key in `entryPoints`, and that the referenced QML file exists. A valid manifest declaring a custom bar-widget follows this structure:

```json
{
  "schemaVersion": 1,
  "id": "omarchy.myexample",
  "name": "My Example",
  "version": "0.1.0",
  "author": "Your Name",
  "description": "Demo of a bar-widget",
  "kinds": ["bar-widget"],
  "entryPoints": {
    "barWidget": "MyWidget.qml"
  },
  "barWidget": {
    "displayName": "Example",
    "category": "Demo",
    "allowMultiple": false
  }
}

```

Place the manifest in `shell/plugins/<category>/<name>/manifest.json`, add the referenced QML file, then activate the plugin.

## Working with Plugin Kinds

Enable a bar-widget using the CLI:

```bash
omarchy-plugin-enable omarchy.weather

```

Access service data from within a QML widget:

```qml
import QtQuick 2.15
import QtQuick.Layouts 1.15
import Omarchy 1.0

Item {
    property int nightTemp: OmarchyService.nightlight.temperature
}

```

Open a panel programmatically:

```bash
omarchy-panel-open omarchy.wifiqr

```

## Summary

- Omarchy uses six plugin kinds: `bar`, `bar-widget`, `service`, `panel`, `background`, and `agents`.
- The `bar` kind manages the top-level status bar, while `bar-widget` populates it with interactive elements.
- `service` plugins provide background data without UI, accessible via `shell_ipc` and `OmarchyService`.
- `panel` plugins create standalone popup interfaces triggered by commands like `omarchy-panel-open`.
- All manifests must validate against the plugin-registry contract in [`test/shell.d/plugin-registry-contract-test.sh`](https://github.com/omacom/omarchy/blob/main/test/shell.d/plugin-registry-contract-test.sh).
- Each kind requires a corresponding entry point in the `entryPoints` object that points to an existing QML file.

## Frequently Asked Questions

### Can a single plugin declare multiple kinds?

Yes. A plugin can include multiple values in its `kinds` array, provided it defines the corresponding entry points for each. For example, a plugin might declare both `service` and `bar-widget` to provide background data while displaying a control widget, though each kind requires its own key in `entryPoints` (e.g., `"service"` and `"barWidget"`).

### How do I create a custom bar widget for Omarchy?

Create a directory under `shell/plugins/<category>/<name>/`, add a [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) declaring `bar-widget` in the `kinds` array, and specify the QML file in `entryPoints.barWidget`. Run `omarchy-plugin-enable <id>` to activate it. The bar will automatically detect and load the widget on the next shell restart.

### What's the difference between a service and a bar-widget?

A `service` runs continuously in the background without rendering UI, exposing data via properties accessible through `OmarchyService`. A `bar-widget` renders visual components inside the top bar and can read values from services but cannot function as a background data source itself. Services provide data; bar-widgets display it.

### Where are plugin manifests validated?

The shell validates manifests against the plugin-registry contract defined in [`test/shell.d/plugin-registry-contract-test.sh`](https://github.com/omacom/omarchy/blob/main/test/shell.d/plugin-registry-contract-test.sh). This ensures every declared kind has a matching entry point and that all referenced files exist before loading, preventing runtime errors from missing QML components.