How Omarchy Shell Plugins Function: Quickshell Plugin System Explained

Omarchy shell plugins are self-contained UI extensions that run inside a single long-running Quickshell process, discovered via manifest.json files, loaded dynamically at runtime, and controlled through IPC commands.

The Omarchy desktop environment manages all visual elements—status bars, widgets, panels, overlays, and background services—through a unified plugin architecture. According to the basecamp/omarchy source code, this system enables seamless customization without requiring shell restarts or complex compilation steps.

Plugin Discovery and Validation

The foundation of Omarchy shell plugins lies in shell/services/PluginRegistry.qml, which orchestrates the entire plugin lifecycle.

Scanning Locations

At initialization, the PluginRegistry invokes a Bash script via its rescan() function to scan two distinct directories:

  • First-party plugins: shell/plugins — bundled components shipped with Omarchy
  • Third-party plugins: ~/.config/omarchy/plugins — user-installed extensions

For each manifest.json (or *.manifest.json) discovered, the registry performs four validation steps:

  1. Parses the JSON structure
  2. Validates against schema version 1 with required fields and safe entry-point paths
  3. Stamps metadata with __sourceDir and __isFirstParty flags
  4. Merges manifests into installedPlugins, reserving omarchy.* namespace for first-party plugins

Manifest Schema and Structure

Every Omarchy shell plugin requires a manifest.json at its root directory. The schema defines capabilities and entry points for the Quickshell runtime.

Field Purpose
id Unique identifier; omarchy. prefix reserved for built-ins
name Human-readable display title
version Semantic version string
kinds Plugin types: bar-widget, bar, panel, overlay, menu, service
entryPoints Maps each kind to a relative QML file
keepLoaded Optional; retains plugin in memory after dismissal
barWidget Optional placement metadata and multiplicity rules

Entry-point paths must be relative and cannot contain .. or traverse outside the plugin directory—enforced by path validation in PluginRegistry.qml.

Enabling and Disabling Omarchy Shell Plugins

Plugin activation is controlled through ~/.config/omarchy/shell.json, interpreted by PluginRegistry.setEnabled(id, true|false, placement?).

Configuration Patterns

  • Bar widgets: Enabled by inclusion in bar.layout.<section> arrays
  • Bar replacements: Selected via bar.id field
  • General plugins: Listed in top-level plugins[] array

First-party non-bar plugins are implicitly enabled unless explicitly listed in disabledPlugins[]. The registry handles special logic for widget placement, ensuring cloned plugins correctly supersede their sources.

Runtime IPC Communication

External tools interact with running Omarchy shell plugins through an IPC layer that wraps PluginRegistry methods for atomic configuration changes.

Core IPC Methods

Command Function
listPlugins Returns JSON array of all discovered plugins
enablePlugin <id> <placement> Activates plugin with optional bar placement
putBarWidget <id> <placement> Adds widget if absent
moveBarWidget <id> <placement> Relocates existing widget
call <id> <method> <arg> Invokes method on loaded plugin

These commands enable scripting, automation, and integration with external tools without shell restarts.

Hot-Reload and Plugin Cloning

Omarchy shell plugins support development workflows through automatic reloading and safe customization via cloning.

File System Monitoring

The localPluginWatcher in PluginRegistry.qml uses inotifywait to detect source modifications. Changes emit localPluginChanged(pluginId), triggering hot-reload while preserving state for keepLoaded plugins.

Cloning Mechanism

Cloning creates a personal copy of first-party plugins under ~/.config/omarchy/plugins/<username>.<id>/ with these characteristics:

  • Preserved identity: Clone retains original IPC identity—existing shortcuts remain functional
  • Automatic mutual exclusion: Enabling clone disables source plugin via disabledPlugins[]; conversely, enabling source removes clone from disabled list

This design allows users to modify built-in behavior without losing upstream compatibility.

Entry-Point Loading and Injected Properties

When summoned via omarchy-shell shell summon <id>, the registry resolves the entry-point URL through entryPointUrl(manifest, kind). The resulting file:// path loads as a QML Item with injected context:

  • omarchyPath — Absolute filesystem path to plugin directory
  • shell — Reference to running shell instance
  • manifest — Parsed manifest object
  • pluginRegistry / barWidgetRegistry — Runtime registries for dynamic queries

These properties enable plugins to query system state, emit IPC calls, and self-configure.

Practical Examples

Minimal Bar Widget Manifest

{
  "schemaVersion": 1,
  "id": "myorg.cool-clock",
  "name": "Cool Clock",
  "version": "1.0.0",
  "kinds": ["bar-widget"],
  "entryPoints": { "barWidget": "Widget.qml" },
  "barWidget": {
    "defaultSection": "center",
    "allowMultiple": false
  }
}

See shell/services/PluginRegistry.qml for complete schema validation rules.

CLI Plugin Activation


# Enable plugin with left-side bar placement

omarchy enablePlugin myorg.cool-clock '{"section":"left"}'

This internally invokes PluginRegistry.setEnabled("myorg.cool-clock", true, {"section":"left"}).

Panel Summoning with Payload


# Load weather panel and pass location data

omarchy-shell shell summon community.weather '{"location":"Seattle"}'

The summon method loads the plugin if needed and calls its open(payloadJson) entry point.

Basic QML Widget Implementation

// Widget.qml
Item {
    width: 80; height: 30
    Text {
        anchors.centerIn: parent
        text: "12:34"
        font.pixelSize: Style.font.title
        color: Color.foreground
    }
}

Automatically receives shell, pluginRegistry, and other context properties on load.

Architecture Files

Path Responsibility
shell/services/PluginRegistry.qml Discovery, validation, lifecycle management, hot-reload
docs/omarchy-shell.md Manifest format, IPC reference, configuration schema
shell/shell.qml Shell instantiation, IPC target exposure, config wiring
shell/plugins/*/*/manifest.json Reference first-party plugin implementations
test/shell.d/plugins-test.sh Manifest parsing and safety validation tests

Summary

  • Omarchy shell plugins are Quickshell QML components discovered through manifest.json scanning in shell/plugins and ~/.config/omarchy/plugins
  • shell/services/PluginRegistry.qml validates manifests, manages enabled state, and orchestrates loading
  • IPC commands (enablePlugin, summon, call) control runtime behavior without shell restarts
  • Hot-reload via inotifywait and cloning with preserved identity enable safe customization
  • Injected properties (shell, omarchyPath, pluginRegistry) provide plugin context

Frequently Asked Questions

What file format defines an Omarchy shell plugin?

A manifest.json file at the plugin root declares metadata including id, version, kinds, and entryPoints. The schema requires schemaVersion: 1 and enforces safe relative paths for entry points.

Can I modify built-in Omarchy plugins without losing updates?

Yes. Use the cloning feature: omarchy enablePlugin with a first-party plugin creates a copy under ~/.config/omarchy/plugins/<user>.<id>/. This preserves the original IPC identity while allowing modifications; the clone automatically supersedes the original when enabled.

How do Omarchy shell plugins receive data when summoned?

The summon IPC method passes a JSON payload to the plugin's open() entry point. For bar widgets and persistent services, injected properties like shell and pluginRegistry enable ongoing runtime interaction.

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 →