Understanding the Different Plugin Kinds in Omarchy: A Complete Guide

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) implements a manifest-driven plugin architecture where every extension lives under shell/plugins/. Each plugin contains a 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 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 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 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 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 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. 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. 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:

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

omarchy-plugin-enable omarchy.weather

Access service data from within a QML widget:

import QtQuick 2.15
import QtQuick.Layouts 1.15
import Omarchy 1.0

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

Open a panel programmatically:

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.
  • 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 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. 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.

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 →