How Omarchy Installs and Manages Third-Party Plugins: The Complete Guide
Omarchy treats every third-party plugin as a Git repository containing a manifest.json file, installing them into ~/.config/omarchy/plugins/ and managing their lifecycle through CLI commands that update the shell.json configuration.
Omarchy is a Qt-based desktop shell that supports deep customization through third-party plugins distributed as Git repositories. Understanding how the shell discovers, validates, and isolates these extensions is essential for both users installing community enhancements and developers building new UI components.
The Git-Based Plugin Architecture
Omarchy's plugin system is built entirely on Git. Each third-party plugin is a standalone repository that the shell clones directly into the user's configuration directory. According to the Omarchy source code, the shell maintains plugins at ~/.config/omarchy/plugins/<id>/, where <id> corresponds to the plugin's unique identifier defined in its manifest.
The core discovery mechanism lives in shell/services/PluginRegistry.qml. At startup and whenever rescanPlugins is invoked, this registry walks the plugins directory, loads each manifest.json, and builds capability-scoped facades that restrict what third-party code can access. This architecture prevents untrusted plugins from reaching privileged services while still allowing full UI integration for legitimate components.
Installing Third-Party Plugins
The Installation Process
When you run omarchy plugin add <git-url>, the system executes bin/omarchy-plugin-add, which performs three critical operations:
- Clones the remote repository into
~/.config/omarchy/plugins/<id>/ - Validates the
manifest.jsonstructure against the schema defined inshell/services/PluginRegistry.qml - Disables the plugin by default so you can inspect the code before activation
# Install a third-party weather widget
omarchy plugin add https://github.com/acme/omarchy-weather.git
# The plugin remains disabled until you explicitly enable it
omarchy plugin enable community.weather-extra
Manual Installation Method
You can also install plugins manually without using the CLI:
# Create the plugin directory
mkdir -p ~/.config/omarchy/plugins/acme.clock
# Copy your plugin files
cp -r /path/to/local/clock/* ~/.config/omarchy/plugins/acme.clock/
# Rescan and enable
omarchy-shell shell rescanPlugins
omarchy plugin enable acme.clock
The Plugin Manifest Format
Every third-party plugin must contain a manifest.json at its root. The shell/services/PluginRegistry.qml validates this schema strictly. Here is the required structure:
{
"schemaVersion": 1,
"id": "my.org.cool-clock",
"name": "Cool clock",
"version": "1.0.0",
"author": "You",
"kinds": ["bar-widget"],
"entryPoints": { "barWidget": "Widget.qml" }
}
Key fields:
kinds: Declares which UI surfaces the plugin targets (e.g.,bar,panel,bar-widget)entryPoints: Maps each kind to a specific QML file that the shell instantiatesid: The unique reverse-domain identifier used for the directory name andshell.jsonentries
Enabling and Disabling Plugins
Security-conscious by design, Omarchy keeps newly installed plugins disabled by default. The bin/omarchy-plugin-enable command activates a plugin by appending its ID to the plugins[] array in shell.json:
{
"plugins": [
{ "id": "community.weather-extra" },
{ "id": "acme.system-monitor" }
]
}
To disable a plugin without removing it, use bin/omarchy-plugin-disable, which removes the entry from shell.json while optionally keeping service instances alive:
# Disable but keep running (for smooth transitions)
omarchy plugin disable community.weather-extra
Managing Plugin Lifecycle
Updating Plugins
The bin/omarchy-plugin-update command pulls fast-forward changes from the remote repository, runs validation against shell/services/PluginRegistry.qml, and triggers a rescan. The system shows a diff before applying changes and re-validates the manifest.json schema:
# Update a specific plugin
omarchy plugin update community.weather-extra
# Update all installed third-party plugins
omarchy plugin update
Removing Plugins
To completely remove a third-party plugin, bin/omarchy-plugin-remove deletes the plugin directory at ~/.config/omarchy/plugins/<id>/ and purges its entry from shell.json:
# Remove the weather widget completely
omarchy plugin remove community.weather-extra
Cloning Built-in Plugins
For customization, bin/omarchy-plugin-clone creates a local copy of built-in plugins so you can modify them:
# Clone the default bar for editing
omarchy plugin clone default-bar
Security and Isolation via PluginRegistry
The shell/services/PluginRegistry.qml implements a sophisticated security model. When it scans ~/.config/omarchy/plugins/*, it constructs different facades based on the kinds declared in the manifest:
- A
bar-widgetreceives a lightweight UI facade with limited API surface - A full
barplugin receives a comprehensive service facade - Privileged system services remain inaccessible to all third-party code
Additionally, the shell supports hot-reloading: whenever any file under the plugin's directory changes, the shell reloads the QML code instantly without requiring a desktop restart, enabling rapid development cycles while maintaining security boundaries.
Summary
- Git-based distribution: Third-party plugins install as Git repos into
~/.config/omarchy/plugins/<id>/viaomarchy plugin add <git-url> - Manifest-driven: Every plugin requires a root
manifest.jsondeclaringid,kinds, andentryPointsvalidated byshell/services/PluginRegistry.qml - Secure by default: New plugins install disabled; activation requires
omarchy plugin enable <id>which updatesshell.json - Capability isolation: The PluginRegistry builds scoped facades preventing third-party code from accessing privileged services
- Full lifecycle support: Update with
omarchy plugin update, remove withomarchy plugin remove, and clone built-ins withomarchy plugin clone
Frequently Asked Questions
What is the required format for the plugin manifest.json?
The manifest must include schemaVersion, id, name, version, author, kinds, and entryPoints. The kinds field declares which UI components the plugin implements (such as bar-widget or panel), while entryPoints maps each kind to a specific QML file path. The shell/services/PluginRegistry.qml validates this schema strictly when scanning ~/.config/omarchy/plugins/.
How does Omarchy prevent third-party plugins from accessing system functions?
Omarchy's PluginRegistry creates capability-scoped facades that expose only the APIs appropriate for the declared kinds. For example, a plugin declaring bar-widget receives a restricted UI facade, while the shell prevents direct access to privileged services regardless of the plugin's declared capabilities.
Can I install plugins without using the omarchy plugin add command?
Yes. You can manually copy plugin files to ~/.config/omarchy/plugins/<id>/ and then run omarchy-shell shell rescanPlugins followed by omarchy plugin enable <id>. This method bypasses the automatic Git cloning but still requires a valid manifest.json for the PluginRegistry to recognize the plugin.
Does Omarchy support hot-reloading for plugin development?
Yes. The shell monitors file changes within each plugin's directory under ~/.config/omarchy/plugins/ and hot-reloads the QML code instantly without requiring a desktop restart. This feature allows developers to see changes immediately while working on entryPoints files like Widget.qml.
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 →