# Quickshell Plugin Kinds Explained: The Complete Architecture Guide for Omarchy

> Explore the fourteen Quickshell plugin kinds like service panel bar and more. Understand how each kind integrates into the Omarchy shell architecture for custom user interfaces.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: architecture
- Published: 2026-09-08

---

**Quickshell recognizes fourteen distinct plugin kinds—including `service`, `panel`, `bar`, `bar-widget`, `indicator`, `menu`, `app`, `action`, `dmenu`, `reminder`, `polkit`, `lock`, `background`, and `agents`—that determine how components are loaded, rendered, and integrated into the Omarchy shell.**

Quickshell, the core shell framework in the Omarchy project, treats every extendable component as a **plugin** that declares its functionality through a `kinds` array in its [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) file. These **Quickshell plugin kinds** act as type identifiers that tell the shell whether a component should run as a background daemon, render as a floating window, or embed as a widget in the system bar. The registry logic in `shell/services/PluginRegistry.qml` validates these declarations and routes each plugin to its appropriate loader based on its declared kind.

## Core Quickshell Plugin Kinds

The shell distinguishes between UI components, background services, and specialized agents. Each kind follows specific conventions for file placement and entry-point naming.

### Service Plugins

The **`service`** kind represents long-running background processes that operate without direct user interfaces. These daemons typically handle system monitoring, media control, or hardware management.

According to the Omarchy source code, service implementations reside in `shell/plugins/services/*/Service.qml`. The shell creates dedicated loaders for these plugins that remain active during the entire session.

```qml
// shell.qml – generic loader for service-kind plugins
Loader {
    id: pluginServiceLoader
    active: !shell.pluginReloading && !!registry.entryPointUrl(manifest, "service")
    source: registry.entryPointUrl(manifest, "service")
}

```

### Panel Plugins

**`panel`** plugins render as top-level UI windows that appear as separate floating interfaces, such as weather displays or VPN status panels. These components typically implement `shell/plugins/panels/*/Panel.qml` as their entry point.

To declare a panel plugin, the manifest must specify `"kinds": ["panel"]` and provide a corresponding entry point:

```json
{
  "id": "example.weather",
  "name": "Weather Panel",
  "version": "1.0",
  "kinds": ["panel"],
  "entryPoints": {
    "panel": "Panel.qml"
  }
}

```

### Bar and Bar-Widget Plugins

The **`bar`** kind defines the central system bar that hosts widgets and indicators, implemented in `shell/plugins/bar/Bar.qml`. Within this container, **`bar-widget`** plugins provide individual functional blocks such as workspace switchers or system trays.

Bar widgets declare their kind and preferred position using readonly properties:

```qml
// Workspaces.qml
readonly property string kind: "bar-widget"
readonly property string defaultSection: "left"

```

Widget implementations are located in `shell/plugins/bar/widgets/*/*.qml`.

### Indicator Plugins

**`indicator`** plugins are compact status icons that live inside the bar, distinct from full widgets. These typically display binary states such as screen-recording activity or night-light status. The source tree places these in `shell/plugins/bar/indicators/*/*.qml`, such as `shell/plugins/bar/indicators/ScreenRecording.qml`.

### Menu System Plugins

The menu architecture uses multiple sub-kinds defined within `shell/plugins/menu/Menu.qml`:

- **`menu`**: The container kind that defines the application launcher structure
- **`app`**: Simple launchers that execute applications
- **`action`**: Commands that invoke specific shell functions
- **`dmenu`**: Dynamic menu entries that generate content at runtime (e.g., "Run command…")

Each entry specifies its kind explicitly:

```qml
// Menu.qml – a simple app launcher entry
{
    kind: "app",
    label: "Terminal",
    command: "omarchy launch terminal"
}

```

### Reminder Plugins

The **`reminder`** kind creates time-based overlays that prompt the user, such as break reminders or notification flows. The implementation in `shell/plugins/reminders/ReminderFlow.qml` demonstrates how these transient UI components integrate with the shell's timing systems.

### Polkit Plugins

**`polkit`** plugins implement PolicyKit agents that request elevated privileges when applications need authentication. The reference implementation in `shell/plugins/polkit/PolkitAgent.qml` shows how these plugins handle secure privilege escalation dialogs.

### Lock Plugins

The **`lock`** kind manages screen-lock UI components and related helper services. The core implementation in `shell/plugins/lock/Service.qml` coordinates the lock screen's visual and security aspects.

### Background Plugins

**`background`** plugins provide wallpaper or video backgrounds for the desktop environment. These are implemented in `shell/plugins/background/Background.qml` and are loaded early in the shell initialization sequence.

### Agent Plugins

The **`agents`** kind represents generic plugins that expose custom APIs to other shell components. Located in `shell/plugins/agents/*/*.qml`, these plugins act as bridges between the shell and external services without providing direct UI elements.

## How Quickshell Validates Plugin Kinds

The **PluginRegistry** in `shell/services/PluginRegistry.qml` serves as the authority for plugin kind validation. Every plugin manifest must contain a non-empty `kinds` array, verified by the `validateManifest` function in lines 64-68 of the registry file.

The registry distinguishes special handling for certain kinds when locating configuration entries. Specifically, it treats **"bar"**, **"bar-option"**, and **"plugin"** as reserved identifiers during the resolution process (lines 215-244). This logic ensures that core shell components receive proper configuration context while generic plugins follow standard loading paths.

## Summary

- **Quickshell plugin kinds** are declared in the `kinds` array of each plugin's [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) file.
- The fourteen recognized kinds include: `service`, `panel`, `bar`, `bar-widget`, `indicator`, `menu`, `app`, `action`, `dmenu`, `reminder`, `polkit`, `lock`, `background`, and `agents`.
- **Service** plugins run as background daemons in `shell/plugins/services/*/Service.qml`.
- **Panel** plugins render as independent windows using entry points in `shell/plugins/panels/*/Panel.qml`.
- **Bar-widget** and **indicator** plugins embed in the system bar through `shell/plugins/bar/widgets/` and `shell/plugins/bar/indicators/`.
- **Menu** plugins use sub-kinds (`app`, `action`, `dmenu`) defined in `shell/plugins/menu/Menu.qml`.
- The **PluginRegistry** at `shell/services/PluginRegistry.qml` validates manifests and resolves entry-point URLs using the `validateManifest` function.

## Frequently Asked Questions

### What is the difference between a bar-widget and an indicator in Quickshell?

**Bar-widgets** are functional UI components that provide interactive controls like workspace switching or volume adjustment, while **indicators** are simple status displays that show binary states like recording activity or connectivity status. Bar-widgets typically occupy more space and accept user input, whereas indicators appear as compact icons within the bar's indicator area.

### How do I create a new service plugin in Quickshell?

Create a new directory under `shell/plugins/services/` containing a `Service.qml` file and a [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) that declares `"kinds": ["service"]`. The shell automatically detects enabled service plugins and loads them through the `pluginServiceLoader` in `shell.qml`, which activates when `registry.entryPointUrl(manifest, "service")` returns a valid path.

### Can a single Quickshell plugin declare multiple kinds?

Yes, a plugin can declare multiple kinds in its manifest's `kinds` array. The PluginRegistry handles multi-kind plugins by resolving separate entry points for each declared kind. For example, a plugin might provide both a `service` for background logic and a `panel` for configuration UI, with each component loaded through its respective entry point URL.

### Where does Quickshell validate that a plugin has a valid kind?

Validation occurs in `shell/services/PluginRegistry.qml` within the `validateManifest` function (lines 64-68), which checks that the manifest contains a non-empty `kinds` array. Additionally, the registry's entry-point resolution logic (lines 215-244) handles special cases for core kinds like "bar" and "plugin" when matching plugins to their configuration contexts.