# How to Define a Custom Plugin manifest.json for Omarchy: Complete Developer Guide

> Learn how to define a custom plugin manifest.json for Omarchy. This guide details the metadata and entry-point mappings needed for the Quickshell runtime.

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

---

**Omarchy discovers and loads plugins through a [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) file placed in the plugin's root directory, which supplies metadata and entry-point mappings required by the Quickshell runtime.**

Omarchy is a desktop environment built on the Quickshell runtime that extends functionality through a dynamic plugin system. When the shell starts, it scans specific directories for valid plugin manifests. Understanding how to define a custom plugin manifest.json for Omarchy is essential for extending the desktop with custom bar widgets, panels, or background services.

## How Omarchy Discovers Plugins

The plugin discovery mechanism is implemented in `shell/PluginManager.qml`. When Quickshell initializes, the manager searches the `shell/plugins/` directory for subdirectories containing a [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) file. The `loadPluginManifest` function parses this JSON to register the plugin under its unique identifier and create the appropriate QML components.

Each manifest must reside in the plugin's root directory. For reference, see the Weather panel implementation at [`shell/plugins/panels/weather/manifest.json`](https://github.com/omacom/omarchy/blob/main/shell/plugins/panels/weather/manifest.json). The runtime uses the manifest to determine which **kinds** the plugin implements and which QML files to load for each entry point.

## Required Manifest Schema Fields

A valid [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) must include specific metadata fields that tell Omarchy how to handle the plugin:

- **schemaVersion**: Currently must be set to `1`
- **id**: A unique dotted identifier (e.g., `"omarchy.weather"`) used to reference the plugin globally
- **name**: Human-readable title displayed in the UI
- **kinds**: Array of plugin types implemented (e.g., `["bar-widget"]`, `["panel"]`, or `["service"]`)
- **entryPoints**: Object mapping each kind to its corresponding QML file path relative to the plugin directory

Optional fields include `version`, `author`, and `description`, which appear in the plugin picker interface.

## Configuring Plugin Entry Points and Kinds

The `entryPoints` object defines which QML files the runtime loads for each kind. For example, a bar widget declares `"barWidget": "BarWidget.qml"` to specify that `BarWidget.qml` contains the implementation extending the base component found in `shell/components/BarWidget.qml`.

Kind-specific metadata blocks (e.g., `barWidget`, `panel`) configure UI presentation:

- **displayName**: The title shown in selection menus
- **category**: The grouping for organization (e.g., `"Utility"`, `"System"`)
- **allowMultiple**: Boolean indicating whether users can instantiate multiple copies
- **settingsForm**: String referencing a QML file (relative path) that extends `shell/components/SettingsForm.qml` for configuration UI

## Creating a Custom Plugin Step-by-Step

Follow this workflow to register a new plugin with Omarchy:

1. Create a directory under `shell/plugins/` (e.g., `shell/plugins/panels/my-awesome-panel/`)
2. Add a [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) with required fields and appropriate kinds
3. Create the QML files referenced in `entryPoints` relative to the plugin directory
4. Optionally create a settings form QML and reference it in the kind-specific block
5. Restart Omarchy to trigger plugin scanning

## Minimal Bar-Widget Plugin Example

This complete example demonstrates a functional custom widget.

The [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) file:

```json
{
  "schemaVersion": 1,
  "id": "omarchy.mywidget",
  "name": "My Widget",
  "version": "0.1.0",
  "author": "Your Name",
  "description": "A simple custom bar widget",
  "kinds": ["bar-widget"],
  "entryPoints": {
    "barWidget": "MyBarWidget.qml"
  },
  "barWidget": {
    "displayName": "My Widget",
    "description": "Shows a static label",
    "category": "Utility",
    "allowMultiple": false,
    "settingsForm": "myWidgetSettings"
  }
}

```

The corresponding `MyBarWidget.qml` implementation:

```qml
import QtQuick 2.15
import Omarchy 1.0

BarWidget {
    Text {
        text: "Hello Omarchy"
        color: Theme.foreground
    }
}

```

Optional settings form (`myWidgetSettings.qml`):

```qml
import QtQuick 2.15
import Omarchy 1.0

SettingsForm {
    property string greeting: "Hello Omarchy"
}

```

Place all three files in the same plugin directory. After restarting Omarchy, the new widget appears under **Utility → My Widget** in the bar-widget picker.

## Summary

- Omarchy scans `shell/plugins/` directories for [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) files during startup via `shell/PluginManager.qml`
- The manifest requires `schemaVersion`, `id`, `name`, `kinds`, and `entryPoints` at minimum
- Kind-specific blocks configure UI metadata like `displayName`, `category`, and `allowMultiple`
- Entry points reference QML files that extend base components such as `BarWidget` or `SettingsForm`
- Plugins must be placed in the correct directory structure and require a shell restart to appear in the interface

## Frequently Asked Questions

### What kinds of plugins can I create in Omarchy?

Omarchy supports several plugin kinds including `bar-widget` for the top bar, `panel` for full-screen overlays, and `service` for background processes. Each kind expects specific entry point names in the manifest and extends corresponding base components in `shell/components/`.

### Where does Omarchy scan for plugin manifests?

The runtime scans subdirectories within `shell/plugins/` looking for [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) files. The discovery logic resides in `shell/PluginManager.qml`. You can organize plugins into subdirectories like `shell/plugins/panels/` or `shell/plugins/services/` without affecting detection.

### Can I instantiate multiple copies of the same widget?

Set `allowMultiple: true` in the kind-specific configuration block (e.g., `barWidget.allowMultiple`). When enabled, users can add multiple instances of your plugin to the bar or panel. If set to `false`, the system restricts instantiation to a single copy.

### How do I debug a plugin that isn't loading?

Verify that [`manifest.json`](https://github.com/omacom/omarchy/blob/main/manifest.json) contains valid JSON with all required fields (`schemaVersion`, `id`, `name`, `kinds`, `entryPoints`). Check that QML file paths in `entryPoints` are correct relative to the plugin directory. Omarchy's startup logs often indicate parse errors in `shell/PluginManager.qml` if the manifest fails validation.