Understanding the Different Plugin Kinds in Omarchy
Omarchy defines six distinct plugin kinds—bar-widget, panel, overlay, menu, service, and bar—that determine how components are loaded, displayed, and managed within the long‑living Quickshell process.
The Omarchy desktop environment from basecamp/omarchy is architected around a modular plugin system where every visible component is a plugin. Each plugin declares its capabilities through a manifest.json file, using the kinds field to tell the shell exactly where the component can appear in the UI and how it should be instantiated.
The Six Plugin Kinds Defined
The kinds array in manifest.json supports the following values, as documented in manual/32-shell-plugins.md and enforced by the shell’s validation logic:
bar-widget
A component that the active bar can place into a section, such as a clock, network indicator, or media controller. When declaring this kind, the manifest may include a barWidget block that configures the display name, category, default section, and whether multiple instances are allowed.
panel
A persistent or summoned floating window that overlays the desktop but does not cover the entire screen. Weather widgets, system monitors, or notification centers typically implement this kind.
overlay
A fullscreen surface that covers the whole screen, blocking interaction with underlying windows. Common examples include the emoji picker and clipboard manager.
menu
A summoned menu surface that appears on user interaction. The Omarchy menu itself is implemented as a plugin of this kind.
service
A headless singleton with no UI, typically running background tasks such as battery monitoring, network polling, or media session tracking. Services start automatically when enabled and run continuously until the shell exits.
bar
A full‑bar replacement that swaps out the built‑in bar entirely. Only one bar plugin can be active at a time, as it assumes responsibility for the entire top or bottom screen edge.
How Plugin Kinds Drive System Behavior
The kinds declaration is not merely descriptive; it dictates core shell behavior across discovery, lifecycle management, and extension.
Discovery and Loading
At startup, the omarchy-shell process scans two locations for valid plugins:
$OMARCHY_PATH/shell/plugins/for first‑party plugins bundled with Omarchy~/.config/omarchy/plugins/for third‑party user installations
The shell validates each discovered manifest.json and maps the declared kinds to specific entry points defined in the entryPoints object. For example, a plugin declaring both service and bar-widget must provide corresponding QML files:
{
"schemaVersion": 1,
"id": "acme.media",
"name": "Media Controller",
"kinds": ["service", "bar-widget"],
"entryPoints": {
"service": "Service.qml",
"barWidget": "Widget.qml"
},
"barWidget": {
"displayName": "Media",
"category": "media",
"allowMultiple": false
}
}
Enable and Disable Logic
Enabling a plugin persists its ID to ~/.config/omarchy/shell.json in a location appropriate to its kind:
- Bar widgets are added to the bar layout configuration
- Non‑widget first‑party plugins are tracked in
enabledPlugins[]or removed fromdisabledPlugins[]
Disabling reverses these mutations, ensuring the shell does not load entry points for inactive plugins on the next start.
Cloning and Extending
When cloning a built‑in plugin using omarchy plugin clone, the new copy inherits the original’s kinds array. This allows developers to modify UI components or business logic without breaking the shell’s expectations about where the plugin can appear.
Validating Plugin Kinds
The bin/omarchy-plugin-validate CLI tool ensures that every declared kind has a matching entry point in manifest.json. This validation prevents runtime errors by catching mismatches between the kinds array and the entryPoints object before the shell attempts to load the plugin.
The test suite in test/shell.d/plugins-test.sh further enforces these contracts, confirming that:
- Plugins with
bar-widgetkind correctly exposebarWidgetmetadata - Multi‑kind plugins load all declared entry points
- Invalid kind declarations are rejected during the validation phase
Practical Examples
List discovered plugins with their kinds:
omarchy plugin list --json | jq '.[] | {id, kinds}'
Enable a specific bar‑widget:
omarchy plugin enable myclock.bar-widget
Add a third‑party plugin providing both a panel and a service:
omarchy plugin add https://github.com/acme/omarchy-weather.git --enable
Summary
- Omarchy recognizes six plugin kinds:
bar-widget,panel,overlay,menu,service, andbar. - The
kindsarray inmanifest.jsondetermines which entry points the shell loads and where UI components appear. - Bar widgets support additional configuration via the
barWidgetblock for display metadata and instance limits. - Plugins are discovered in
$OMARCHY_PATH/shell/plugins/and~/.config/omarchy/plugins/, with enablement state stored in~/.config/omarchy/shell.json. - Validation is handled by
bin/omarchy-plugin-validateand verified bytest/shell.d/plugins-test.sh.
Frequently Asked Questions
Can a single plugin declare multiple kinds?
Yes. A plugin can declare multiple kinds simultaneously in its manifest.json. For example, the media plugin is both a service (for background playback monitoring) and a bar-widget (for the control interface). Each kind requires a corresponding entry point in the entryPoints object.
Where are plugin kinds documented for developers?
The canonical reference is shell/plugins/README.md, which lists each supported kind and its required entry points. User‑facing documentation covering kind behavior and configuration options is maintained in manual/32-shell-plugins.md.
How does Omarchy handle conflicts between bar plugins?
Only one plugin of kind bar can be active at a time because it replaces the entire built‑in bar. Attempting to enable a second bar plugin typically disables the first, with the shell logging a warning about the replacement. Bar widgets (bar-widget), however, can coexist in unlimited numbers within the active bar.
What happens if a plugin declares a kind but omits the entry point?
The bin/omarchy-plugin-validate command will reject the manifest with a validation error. The shell requires that every string in the kinds array has a matching key in entryPoints (e.g., service maps to a service key, bar-widget maps to barWidget). This ensures the shell can resolve the QML file path during initialization.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →