Quickshell Plugin manifest.json Structure in Omarchy: Complete Schema Guide

A Quickshell plugin manifest.json requires schemaVersion 1, a unique id, kinds array, and entryPoints mapping to declare which QML files implement bar, panel, service, or OSD functionality.

In the basecamp/omarchy repository, every Quickshell plugin includes a lightweight JSON manifest that sits alongside its QML source files. Understanding the exact Quickshell plugin manifest.json structure ensures the Omarchy shell can correctly discover, categorize, and load your extensions at runtime.

Core manifest.json Schema Fields

The manifest uses a fixed schema where schemaVersion is always set to 1. This version signals to the loader how to parse the remaining metadata.

Required Metadata Identifiers

Every manifest must declare these top-level fields:

  • id – A unique string identifier, conventionally prefixed with omarchy. (e.g., omarchy.bar or omarchy.wifiqr).
  • name – The human-readable title displayed in plugin menus and UI pickers.
  • version – Semantic version of the plugin itself (e.g., "1.0.0").
  • author – The individual or organization responsible for maintaining the plugin.
  • description – A brief summary shown when users browse available plugins.

Declaring Plugin Kinds and Entry Points

The kinds field is an array of strings that categorizes what the plugin provides. Valid values include bar, panel, service, osd, and notification.

The entryPoints object maps each kind to its corresponding QML implementation file. The keys must match entries in the kinds array exactly.

{
  "schemaVersion": 1,
  "id": "omarchy.example",
  "name": "Example Plugin",
  "kinds": ["panel", "service"],
  "entryPoints": {
    "panel": "Panel.qml",
    "service": "Service.qml"
  }
}

As implemented in basecamp/omarchy, the heavy lifting—logic, DBus calls, and UI rendering—lives in these QML files referenced by entryPoints, while the manifest merely declares the interface.

Optional manifest.json Configuration

Beyond the core schema, manifests support extended fields for complex plugins.

Dependencies and Assets

Use the dependencies array to list plugin IDs that must load before yours. The assets object exposes non-QML resources like icons or images.

{
  "dependencies": ["omarchy.network"],
  "assets": {
    "icon": "icons/plugin.svg"
  }
}

Hooks and Default Settings

The hooks object defines lifecycle functions the shell can invoke, such as onLoad or onUnload. The settings object provides default configuration values that the shell exposes to users.

{
  "hooks": {
    "onLoad": "initFunction"
  },
  "settings": {
    "refreshInterval": 5,
    "theme": "dark"
  }
}

Real-World Examples from basecamp/omarchy

Examining the source repository reveals how these fields combine in production plugins.

Bar Plugin Manifest

In shell/plugins/bar/manifest.json, the built-in bar plugin declares itself as a single-kind component:

{
  "schemaVersion": 1,
  "id": "omarchy.bar",
  "name": "Omarchy Bar",
  "version": "1.0.0",
  "author": "Basecamp",
  "description": "Main status bar",
  "kinds": ["bar"],
  "entryPoints": {
    "bar": "Bar.qml"
  }
}

Wi-Fi QR Panel Manifest

The Wi-Fi QR panel in shell/plugins/panels/wifiqr/manifest.json demonstrates a focused panel implementation:

{
  "schemaVersion": 1,
  "id": "omarchy.wifiqr",
  "name": "Wi-Fi QR Code",
  "version": "1.0.0",
  "author": "Basecamp",
  "description": "Display Wi-Fi credentials as QR code",
  "kinds": ["panel"],
  "entryPoints": {
    "panel": "WifiQr.qml"
  }
}

Minimal Plugin Manifest Template

To create a new panel plugin from scratch, place the following in shell/plugins/panels/mywidget/manifest.json:

{
  "schemaVersion": 1,
  "id": "omarchy.mywidget",
  "name": "My Widget",
  "version": "1.0.0",
  "author": "Your Name",
  "description": "A simple example panel",
  "kinds": ["panel"],
  "entryPoints": {
    "panel": "MyWidget.qml"
  }
}

Ensure MyWidget.qml resides in the same directory; the Omarchy loader resolves paths relative to the manifest location.

Advanced Multi-Kind Configuration

Plugins providing both background services and visual components declare multiple kinds with separate QML entry points:

{
  "schemaVersion": 1,
  "id": "omarchy.myservice",
  "name": "My Service",
  "version": "1.0.0",
  "author": "Your Name",
  "description": "Provides a background service and an on-screen display",
  "kinds": ["service", "osd"],
  "entryPoints": {
    "service": "MyService.qml",
    "osd": "MyOsd.qml"
  },
  "dependencies": ["omarchy.network"]
}

The dependencies array guarantees that omarchy.network initializes before this plugin attempts to use network-related functionality.

Summary

  • The Quickshell plugin manifest.json structure requires schemaVersion set to 1 and uses a fixed schema understood by the Omarchy runtime.
  • Required fields include id (prefixed with omarchy.), name, version, kinds (array), and entryPoints (object mapping kinds to QML files).
  • Valid kinds are bar, panel, service, osd, and notification.
  • Optional fields like dependencies, assets, hooks, and settings enable complex plugin hierarchies and resource management.
  • Manifests live adjacent to their QML files, as seen in shell/plugins/bar/manifest.json and shell/plugins/panels/wifiqr/manifest.json.

Frequently Asked Questions

What schema version does Omarchy use for Quickshell manifests?

The basecamp/omarchy repository currently uses schema version 1 for all plugin manifests. This version number must appear exactly as "schemaVersion": 1 at the root of every manifest.json file.

Can a single Quickshell plugin implement multiple UI components?

Yes. Define multiple entries in the kinds array—such as ["service", "osd"]—and map each to its respective QML file in the entryPoints object. The shell instantiates each component according to its kind and lifecycle requirements.

Where should the manifest.json file be located?

Place manifest.json in the plugin's root directory alongside its QML implementation files. For example, shell/plugins/panels/mywidget/manifest.json should sit next to MyWidget.qml so relative paths in entryPoints resolve correctly.

How does Omarchy handle plugin loading order?

Declare dependencies using the dependencies array, listing plugin IDs as strings. The Omarchy loader guarantees that every plugin listed in dependencies initializes before the dependent plugin begins loading, preventing undefined reference errors at runtime.

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 →