How to Develop Omarchy Plugins: A Complete Guide to Building Desktop Extensions
Developing Omarchy plugins requires creating a directory with a manifest.json file and QML entry points inside ~/.config/omarchy/plugins/, then enabling them via the CLI to leverage automatic hot-reload during development.
Omarchy is a desktop environment built by Basecamp that runs as a single long-lived Quickshell process (omarchy-shell). Every visible element—from the top bar to system dialogs—is implemented as a plugin that the shell loads at startup. Whether you are extending the UI with a custom widget or building a background service, understanding how to develop Omarchy plugins allows you to customize your entire desktop experience using QML and JavaScript.
Understanding Plugin Locations
Omarchy distinguishes between first-party and third-party plugins based solely on disk location. Both are automatically scanned when the shell starts.
First-party plugins bundled with Omarchy reside in the repository under "$OMARCHY_PATH/shell/plugins/". These are maintained by the core team and include essential components like omarchy.clock and omarchy.network.
Third-party plugins that you develop or install from external sources live in your home configuration directory:
~/.config/omarchy/plugins/
When the Quickshell process initializes, it scans both locations to discover available extensions.
Creating the Plugin Manifest
Every Omarchy plugin requires a manifest.json file at its root directory. This manifest declares the plugin's identity, capabilities, and entry points.
Required Manifest Fields
According to the basecamp/omarchy source code documented in manual/32-shell-plugins.md, the manifest must include:
- id: A unique identifier for the plugin. Built-in plugins use the reserved
omarchy.prefix (e.g.,omarchy.battery), which is restricted to the core distribution. Your plugins should use a personal namespace likeusername.pluginname. - name: Human-readable display name.
- version: Semantic version string.
- kinds: Array of plugin types such as
service,bar-widget,panel,osd, orfullscreen. - entryPoints: Map connecting each kind to its QML implementation file.
Example structure for a custom bar widget:
{
"id": "developer.weather",
"name": "Weather Widget",
"version": "1.0.0",
"kinds": ["bar-widget"],
"entryPoints": {
"bar-widget": "WeatherBar.qml"
}
}
Validation Before Installation
Before enabling your plugin, validate the manifest against Omarchy's schema to catch configuration errors:
omarchy plugin validate ./developer.weather
This command checks for duplicate IDs, unsupported kinds, and valid entry point declarations without executing any plugin code.
Implementing Plugin Kinds and UI Components
The kinds array in your manifest determines how Omarchy loads and displays your plugin. The full schema and IPC contract are documented in shell/README.md, while the complete list of first-party plugin implementations is cataloged in shell/plugins/README.md.
Bar Widgets
Bar widgets appear in the top bar and may specify optional placement metadata:
- defaultSection: Determines initial placement (left, center, right).
- allowMultiple: Boolean flag permitting multiple instances on the same bar.
Place your QML files in the plugin directory and reference them in entryPoints. For example, a bar widget implementation lives at ~/.config/omarchy/plugins/developer.weather/WeatherBar.qml.
Services and Panels
Other plugin kinds include:
- service: Headless background processes (e.g., battery monitoring).
- panel: Expandable side panels or overlays.
- osd: On-screen display notifications.
- fullscreen: Lock screens or full-screen overlays.
Each kind maps to a specific QML file via the entryPoints object in manifest.json.
Enabling and Configuring Plugins
Plugin state is managed through ~/.config/omarchy/shell.json, which you modify indirectly via CLI commands rather than editing manually.
Enabling Third-Party Plugins
To activate a plugin and optionally specify its bar section:
# Enable on the left section of the bar
omarchy plugin enable developer.weather --section left
# List all discovered plugins
omarchy plugin list
Third-party plugins are enabled by appearing in the configuration file (as a bar entry, a plugins[] element, or bar.id). First-party plugins are enabled by default and can only be turned off by listing them in a disabledPlugins array.
Full-Bar Plugins
A full-bar plugin replaces the entire top bar and has no "off" state—enabling a different bar automatically replaces the current one.
Installing from Git Repositories
To distribute or install third-party plugins, Omarchy supports a secure Git-based workflow that never executes arbitrary installation hooks:
# Add and immediately enable a plugin from a remote repository
omarchy plugin add https://github.com/acme/omarchy-weather.git --enable
The CLI performs the following operations:
- Clones the repository to a temporary staging area.
- Validates
manifest.jsonagainst the schema (checking for reserved IDs likeomarchy.*and supported kinds). - Moves the verified plugin to
~/.config/omarchy/plugins/<id>/. - Optionally enables the plugin if
--enableis passed.
Updating and Removing Plugins
Maintain your development environment with lifecycle commands:
# Update a specific plugin from its git remote
omarchy plugin update developer.weather
# Update all git-managed plugins (shows diff before applying)
omarchy plugin update
# Remove a plugin (disables first, then deletes or backups)
omarchy plugin remove developer.weather
The update command pulls the latest commit, displays a diff for review, and validates the new version before swapping files. The remove command moves hand-made plugins to a timestamped backup rather than deleting them immediately.
Local Development Workflow
Cloning Built-in Plugins
To modify existing behavior without editing core files, clone a built-in plugin into your user directory:
omarchy plugin clone omarchy.clock
This command:
- Copies the plugin from
"$OMARCHY_PATH/shell/plugins/omarchy.clock"to~/.config/omarchy/plugins/. - Prefixes the ID with your username (e.g.,
dhh.clockfor userdhh). - Preserves your previous bar placement and settings.
- Enables the cloned version immediately.
Hot Reload During Development
Omarchy monitors ~/.config/omarchy/plugins/ for file changes. Save any QML or JavaScript file to trigger automatic hot-reload, allowing you to see UI changes instantly without restarting the shell.
For rapid iteration:
- Create your plugin directory at
~/.config/omarchy/plugins/username.plugin/. - Write
manifest.jsonwith appropriate kinds and entry points. - Implement QML files (e.g.,
Bar.qmlfor bar widgets). - Validate with
omarchy plugin validate ./username.plugin. - Enable with
omarchy plugin enable username.plugin. - Edit files and observe changes immediately via hot-reload.
Summary
- Omarchy plugins reside in
~/.config/omarchy/plugins/for third-party development or"$OMARCHY_PATH/shell/plugins/"for first-party components. - Every plugin requires a
manifest.jsondeclaring a unique ID (avoid the reservedomarchy.prefix), version, kinds, and QML entry points. - The CLI provides safe Git-based installation via
omarchy plugin addwithout executing arbitrary code. - Development is accelerated by hot-reload functionality that monitors file changes in the user plugins directory.
- Built-in plugins can be cloned for local modification using
omarchy plugin clone, which automatically renames them with your username prefix.
Frequently Asked Questions
What programming languages are used to write Omarchy plugins?
Omarchy plugins are written using QML (Qt Meta Language) and JavaScript. The entry points declared in manifest.json are QML files that define the user interface and behavior. System-level logic can be implemented through Qt's JavaScript integration or by interfacing with external processes.
Can I distribute my plugin through the AUR or other package managers?
While the basecamp/omarchy source code supports Git-based installation via omarchy plugin add, you can distribute plugins through any mechanism that places files into ~/.config/omarchy/plugins/. However, the native CLI tools in bin/omarchy-plugin-* expect Git remotes for update management. If installing manually through a package manager, ensure the manifest.json is present at the plugin root and run omarchy plugin validate before enabling.
Why does my plugin ID get rejected during validation?
Omarchy reserves the omarchy. namespace for first-party plugins distributed with the core system. If your manifest ID starts with omarchy., validation will fail. Use a personal prefix like githubusername.pluginname or com.company.pluginname. Additionally, duplicate IDs across all discovered plugins (both first and third party) will cause validation errors.
How do I debug a service plugin that has no visible UI?
Service plugins (declared with the service kind) run headless within the Quickshell process. Debug output appears in the shell's standard error stream. Launch omarchy-shell from a terminal to view console logs, or use QML's console.log() function within your service implementation. Since hot-reload applies to services as well, you can iterate on logic without restarting the desktop session.
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 →