Overview
Dux Shell
Overview
Dux Shell's plugin system allows extending the desktop with custom widgets, dash tabs and cards, launchers, automation, and integrations through QML components.
Plugin Location
Plugins are installed to ~/.config/dms/plugins/. Each plugin is a directory containing a plugin.json manifest and QML components.
Official plugins: github.com/duxlabs-dev/dux-plugins Plugin registry: plugins.duxlabs.dev Registry source: github.com/duxlabs-dev/dux-plugin-registry Example plugins: github.com/duxlabs-dev/dux-shell/tree/master/quickshell/PLUGINS
The plugin directory ranks plugins by community 👍 upvotes. Each plugin has a tracking issue in the registry you can upvote and discuss — see Contributing to the Registry.
Plugin Types
Dux Shell supports the following plugin types, defined in plugin.json:
1. Bar Widget (type: "widget")
Widgets that appear in DankBar and in docks. Define horizontalBarPill and verticalBarPill components for different bar orientations. In a dock, a widget can also open an attached panel inside the dock instead of a popout.
Capabilities:
dankbar-widget- Appears in DankBar and docks
Example use cases: System monitors, media controls, weather widgets, clock displays
2. Control Center Widget (type: "widget")
Widgets that appear in the Control Center quick settings panel. Define ccWidget* properties for toggle buttons and detail panels.
Capabilities:
control-center- Appears in Control Center
Example use cases: VPN toggles, custom shortcuts, service controls
3. Launcher Plugin (type: "launcher")
Extends the application launcher with custom searchable items. Define getItems() and executeItem() functions.
Capabilities:
launcher- Adds items to Spotlight search
Required fields:
trigger- Trigger string for filtering (e.g.,"#","!",""for always-visible)
Example use cases: Emoji picker, calculator, web search, custom actions
4. Daemon (type: "daemon")
Background services with no UI. Run automation, monitoring, or provide services to other plugins.
Capabilities:
daemon- Background servicewatch-events- React to system events
Example use cases: Battery alerts, wallpaper automation, notification handlers
5. Desktop Widget (type: "desktop")
Widgets that render directly on the desktop background layer using Wayland's wlr-layer-shell protocol. Users can drag them anywhere and resize via corner handles.
Capabilities:
desktop-widget- Appears on the desktop layer and can be added to the lock screen
Features:
- Free positioning anywhere on desktop
- Resizing with minimum size constraints
- Multi-monitor support with independent positions per screen
- Position/size persistence across sessions
- Reusable on the lock screen with separate instances and geometry (see Lock Screen)
Example use cases: Desktop clock, system monitor, weather widget, sticky notes
6. Dash Tab (type: "dash")
A full tab in the dash popout, next to Overview, Media, Wallpapers and Weather. It shows up in the tab bar as soon as the plugin is enabled, and you can hide or reorder it under Settings → Dashboard.
Capabilities:
dash-tab- Adds a dash tab
Example use cases: Timers, dashboards for a service, notes, anything that needs more room than a popout
7. Dash Card (type: "dashCard")
A card in the dash Overview grid. Add it from the dash (three-dot menu → Edit → Add widget), then drag and resize it like the built-in cards.
Capabilities:
dash-card- Adds an overview card
Example use cases: At-a-glance stats, progress, counters, quick actions
Dash tabs and cards require DMS ≥ 2.0.0. A plugin can ship both; clicking the card then opens the tab.
8. Composite Plugin (type: "composite")
A single plugin that provides several of the above surfaces at once — for example a daemon plus a bar widget plus a desktop widget. Instead of one component, it declares a components map pointing each surface at its own QML file.
Features:
- Any combination of
widget,desktop,daemon,launcher,dash, anddashCardsurfaces - One settings UI and one settings namespace shared across all surfaces
- Shared runtime state via plugin global variables or the daemon instance
Example use cases: A monitor daemon that also shows a bar pill and a desktop tile; an integration that exposes both a launcher and a background watcher; a timer with a bar pill, a dash tab and an overview card
Composite plugins require DMS ≥ 1.5.0. See the development guide for details.
Installation
From GitHub
mkdir -p ~/.config/dms/plugins
cd ~/.config/dms/plugins
git clone https://github.com/author/plugin-name
dms restart
From Plugin Registry
Browse plugins.duxlabs.dev for installation links and documentation.
From the Plugin Browser
Open Settings → Plugins and click Browse. The browser lists every plugin of the configured registries and installs one with a click.
Finding a plugin
- Pick of the week and Pick of the day highlight one plugin each. They are chosen from the registry list on your machine and change by themselves.
- Three shelves sit above the full list: For you (plugins close to the ones you already installed: same categories, same authors), Trending (recent upvotes and updates) and New (latest arrivals).
- Quick filters narrow the list: Hide installed, Installed first, Works here (plugins that support your compositor), New & updated and Official only.
- Search forgives typos, so
walpaperstill finds wallpaper plugins. When nothing matches, Did you mean offers the closest plugins. - Cards carry
newandupdatedmarks, and tell you when a plugin targets another compositor.
Everything above is computed locally from the registry list. Nothing about your installed plugins is sent anywhere.
The detail page
Click a card to open its detail page:
- This plugin can lists the permissions the plugin declares, in plain words.
- Needs lists the commands the plugin requires and marks the ones that are not found on your machine.
- The links open the source, the discussion, a pre-filled problem report, or copy a link to the plugin.
- Click the author to list all of their plugins.
Upvoting
The 👍 count on a card and on the detail page is a button. With the GitHub CLI installed and logged in (gh auth login), a click adds your upvote to the plugin's tracking issue and a second click takes it back. Without it, DMS opens the tracking issue in your web browser instead.
Undoing an uninstall
After you uninstall a registry plugin, the Plugins page shows <name> uninstalled, Undo for a few seconds. Undo installs the plugin again from the registry and turns it back on if it was enabled.
Reproduce Managed Plugins
DMS keeps ~/.config/dms/plugins.lock.json synchronized when registry plugins are installed, updated, or removed. The lockfile records each Git repository, optional monorepo path, and exact commit.
# Refresh the lockfile and optionally export a copy
dms plugins lock
dms plugins lock --output ~/plugins.lock.json
# Install or reset plugins to the exact locked commits
dms plugins restore ~/plugins.lock.json
# Also remove managed plugins that are absent from the lockfile
dms plugins restore ~/plugins.lock.json --prune
The lockfile covers DMS-managed Git plugins. It does not include system plugins, plugin settings, enablement state, or local plugin directories without Git provenance.
Enable Plugin
- Open Settings → Plugins
- Click Scan for Plugins
- Toggle the plugin on
- Add to DankBar layout if applicable
- Restart shell:
dms restart
Custom Registries
DMS fetches installable plugins and themes from registries — Git repositories containing plugins/ and/or themes/ directories in the registry format. The official registry is always active and additional registries can be added alongside it, unless an administrator disables registries.
Requires DMS ≥ 1.6.0.
Managing Registries
GUI: Settings → Plugins → Registries — add a registry by name and Git URL, or remove one. The official registry cannot be removed.
CLI:
# Show configured registries
dms registry list
# Add a registry by name and Git URL
dms registry add myregistry https://github.com/user/my-registry.git
# Remove a registry
dms registry remove myregistry
Additional registries are stored in ~/.config/dms/registries.json. Names are short lowercase identifiers (letters, digits, hyphens) and become the local cache directory for that registry.
Resolution Order
Registries are consulted in declaration order, official first. When two registries provide the same plugin or theme ID, the first occurrence wins — a custom registry cannot override an official entry. An unreachable registry is skipped so the remaining registries keep working.
Registry Format
A registry is a Git repository with either or both of:
plugins/*.json— one plugin manifest per filethemes/<theme-id>/theme.json— one directory per theme
A registry can provide only plugins, only themes, or both. See dms-plugin-registry for the manifest schema.
Plugins run with full desktop session permissions. Only add registries you trust.
Disabling Registries
An administrator can turn off every registry, the official one included, with the disable_registries key in /etc/dms/cli-policy.json:
{
"policy_version": 1,
"disable_registries": true
}
Distributions can ship the same key in /usr/share/dms/cli-policy.json; when both files set it, /etc/dms/cli-policy.json wins.
With the key set, DMS never clones or pulls a registry. Installed plugins and themes keep working, and dms plugins update still updates plugins that have their own Git checkout or a lockfile entry. Browsing, installing from a registry and registry-based update checks, including the update buttons in Settings, stop working. Registries added with dms registry or in Settings stay in registries.json but have no effect.
Requires DMS ≥ 2.0.0.
Official Plugins
Maintained by the Dux Shell team at dms-plugins:
- Dank Actions - Scriptable bar buttons and control center tiles
- Dank Hooks - Event-based automation triggers
- Dank Pomodoro Timer - Focus timer with notifications
- Dank Battery Alerts - Battery threshold warnings
Community Plugins
Third-party plugins submitted to the registry at plugins.duxlabs.dev:
- WallpaperShuffler - Automatic wallpaper rotation
- WorldClock - Multi-timezone clock widget
- PowerUsage - Real-time power consumption monitor
- Calculator - Launcher-based calculator
Always review plugin source code before installation. Plugins run with full desktop session permissions.
Development
See Plugin Development for the complete development guide including:
- Plugin manifest structure (
plugin.json) - Component architecture
- PluginService API
- Settings components
- Bar, dock and Control Center integration
- Dash tabs and overview cards
- Launcher plugin development
- Global variables and state management
- Plugin translations (
translations/+I18n.trFor)
Translations
Plugins carry their own translations — a translations/ directory in the plugin repo with one JSON file per locale. DMS picks the file matching your locale automatically and updates live when you switch languages in Settings → Locale. Nothing to configure as a user; if the plugin ships your language, you get it.
For plugin authors: see Translations in the development guide for the file format and the I18n.trFor API. Registry plugins can also apply for central translation through the same POEditor project that translates DMS itself.
Example Plugins
Reference implementations in the main repository:
- ExampleEmojiPlugin - Launcher plugin with emoji picker
- LauncherExample - Basic launcher plugin structure
- DashTabExample - Standalone dash tab
- DashCardExample - Standalone dash card
- DashCounterExample - Dash tab, dash card and bar or dock widget in one plugin
- AttachedPanelExample - Widget with an attached dock panel
Plugin Registry Submission
To add your plugin to the registry:
- Create a public GitHub repository
- Include
plugin.json, README, and screenshots - Validate manifest against
plugin-schema.json - Submit PR to dms-plugin-registry
- Site rebuilds automatically on merge
Troubleshooting
Plugin not detected:
- Verify
plugin.jsonsyntax withjq . - Check directory is in
~/.config/dms/plugins/ - Click "Scan for Plugins" in Settings
Plugin won't load:
- Check logs:
dms kill && dms runfrom terminal - Verify component paths in
plugin.json - Ensure dependencies are installed
Settings not working:
- Add
"permissions": ["settings_write"]to manifest - Use
PluginSettingswrapper component - Check PluginService is injected properly
Next Steps
- Browse available plugins at plugins.duxlabs.dev
- Learn plugin development in Plugin Development
- Review example code in the PLUGINS directory