Skip to main content
Version: 1.6

Contributing to the Registry

██████╗ ███████╗ ██████╗ ██╗███████╗████████╗██████╗ ██╗   ██╗
██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔══██╗╚██╗ ██╔╝
██████╔╝█████╗  ██║  ███╗██║███████╗   ██║   ██████╔╝ ╚████╔╝
██╔══██╗██╔══╝  ██║   ██║██║╚════██║   ██║   ██╔══██╗  ╚██╔╝
██║  ██║███████╗╚██████╔╝██║███████║   ██║   ██║  ██║   ██║
╚═╝  ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝

Thank you for contributing to the DankMaterialShell registry! This guide covers how to submit plugins and themes to the dms-plugin-registry repository.

Contributing a Plugin

How to Add Your Plugin

  1. Fork the repository

  2. Create a new JSON file in the plugins/ directory:

    plugins/{github-username}-{plugin-name}.json
    • Use lowercase letters
    • Separate words with hyphens
    • Examples: daniel-42-z-powerusage.json, rochacbruno-worldclock.json
  3. Fill in your plugin information using this schema:

{
"id": "pluginId",
"name": "PluginName",
"capabilities": ["dankbar-widget"],
"category": "monitoring",
"repo": "https://github.com/yourusername/your-plugin-repo",
"path": "optional/path/in/monorepo",
"author": "Your Name",
"description": "Brief description of what your plugin does",
"dependencies": ["dependency1", "dependency2"],
"compositors": ["niri", "hyprland"],
"distro": ["any"],
"screenshot": "https://url/to/screenshot.png"
}

Plugin Field Descriptions

FieldRequiredDescription
idYesUnique identifier in camelCase (e.g., worldClock). Must match your plugin.json
nameYesDisplay name. Must match your plugin.json
capabilitiesYesArray like ["dankbar-widget"]
categoryYesOne of: monitoring, utilities, appearance, system, etc.
repoYesFull GitHub URL to your plugin repository
pathNoSubdirectory path if plugin is in a monorepo
authorYesYour name or GitHub username
descriptionYesClear, concise description of the plugin's purpose
dependenciesYesArray of dependencies, use [] if none
compositorsYesSupported compositors: ["niri", "hyprland"], ["any"]
distroYesSupported distributions: ["any"], ["fedora"], ["arch"], etc.
screenshotNoDirect URL to a screenshot image
i18nNotrue once approved for central translation — see Plugin Translations. Not for initial submissions
Important

The id and name fields must exactly match the corresponding fields in your plugin repository's plugin.json file.

  1. Validate your plugin locally:
python3 .github/generate.py --validate
python3 .github/validate_links.py
  1. Submit a Pull Request

Plugin Feedback & Ranking

When your plugin is merged, a tracking issue is automatically opened for it in the registry. This issue is the plugin's home for feedback:

  • Upvoting — anyone can give the issue a 👍 reaction. The plugin directory ranks plugins by upvotes, so reactions directly affect visibility.

  • Status — maintainers flag plugins by commenting commands on the issue, shown as badges in the directory:

    CommandBadge
    /broken / /workingMarks (or clears) Broken
    /unmaintainedMarks Unmaintained
    /deprecatedMarks Deprecated
    /review / /unreviewMarks (or clears) Reviewed
    /similar #<issue> [#<issue> ...] / /unsimilar #<issue>Links (or unlinks) related plugins

    Moderators can't /review or /unreview a plugin they authored — only Owners can.

    Plugin authors can run /unmaintained and /deprecated on their own plugin without being a moderator. Use /unmaintained when you're looking for a new maintainer, and /deprecated when the plugin is superseded by another plugin or a built-in DMS feature. Other commands remain moderator-only.

    /similar references one or more plugin tracking issues by number (e.g. /similar #530 or /similar #403 #411) and links them to this plugin both ways — each issue lists the others under Related plugins, and the directory and DMS surface the relationship. Use /unsimilar #<issue> to remove a link.

The directory links to each plugin's issue from its Discuss button.

Plugin Translations

Any plugin can ship its own translations — a translations/ directory with one JSON file per locale, loaded by DMS automatically. No approval needed, no registry involvement. See Translations in the development guide for the file format and the I18n.trFor API.

On top of that, registry plugins can apply to join the central DMS POEditor project — the same one community translators use for DMS itself, currently covering 21 languages. Approved plugins get their strings translated alongside the shell, and finished translations come back to the plugin repo as PRs.

Before applying:

  • Your plugin is listed in this registry and actively maintained
  • Every user-facing string goes through I18n.trFor("<your plugin id>", ...), with the id as a literal string exactly matching the id in your plugin.json — the extraction tooling reads call sites, so a variable there means your strings never get picked up

Applying:

  1. Open a PR setting "i18n": true in your plugin's registry JSON. Include a short note: what the plugin does, roughly how many strings
  2. On approval, a maintainer adds your repo to the translation sync. Your English strings get uploaded to POEditor, tagged with your plugin id
  3. As translators finish languages, you get PRs adding translations/<locale>.json files to your repo — merge them and the translations ship with your next plugin update
warning

Once your strings are in POEditor, renaming a term is a delete-plus-add — the old term's translations across every language are discarded. Keep English strings stable.


Contributing a Theme

How to Add Your Theme

  1. Fork the repository

  2. Create a new folder in the themes/ directory:

    themes/{theme-id}/theme.json
    • Use lowercase letters and hyphens for the folder name
    • Examples: tokyonight/, gruvbox-dark/, catppuccin-mocha/
  3. Create your theme.json with this schema:

{
"id": "themeId",
"name": "Theme Name",
"version": "1.0.0",
"author": "Your Name",
"description": "Brief description of your theme",
"dark": {
"primary": "#7aa2f7",
"primaryText": "#16161e",
"primaryContainer": "#7dcfff",
"secondary": "#bb9af7",
"surface": "#1a1b26",
"surfaceText": "#73daca",
"surfaceVariant": "#2f3549",
"surfaceVariantText": "#cbccd1",
"surfaceTint": "#7aa2f7",
"background": "#16161e",
"backgroundText": "#d5d6db",
"outline": "#787c99",
"surfaceContainerLowest": "#121319",
"surfaceContainerLow": "#262c3c",
"surfaceContainer": "#2f3549",
"surfaceContainerHigh": "#444b6a",
"error": "#f7768e",
"warning": "#ff9e64",
"info": "#7dcfff"
},
"light": {
"primary": "#2e7de9",
"primaryText": "#d0d5e3",
"primaryContainer": "#007197",
"secondary": "#9854f1",
"surface": "#e1e2e7",
"surfaceText": "#387068",
"surfaceVariant": "#c4c8da",
"surfaceVariantText": "#1a1b26",
"surfaceTint": "#2e7de9",
"background": "#cbccd1",
"backgroundText": "#1a1b26",
"outline": "#4c505e",
"surfaceContainerLowest": "#fefeff",
"surfaceContainerLow": "#fcfcff",
"surfaceContainer": "#dfe0e5",
"surfaceContainerHigh": "#9699a3",
"error": "#f52a65",
"warning": "#b15c00",
"info": "#007197"
}
}

Theme Metadata Fields

FieldRequiredDescription
idYesUnique identifier in camelCase (e.g., tokyoNight, gruvboxDark)
nameYesDisplay name of your theme
versionYesSemver version (e.g., 1.0.0)
authorYesYour name or username
descriptionYesBrief description of the theme

Theme Color Fields

Both dark and light objects require these color properties:

FieldDescription
primaryPrimary accent color
primaryTextText color on primary backgrounds
primaryContainerContainer using primary color
secondarySecondary accent color
surfaceMain surface/card background
surfaceTextText on surfaces
surfaceVariantAlternative surface color
surfaceVariantTextText on variant surfaces
surfaceTintTint overlay color
backgroundApp background color
backgroundTextText on background (matugen-only — see note)
outlineBorder/divider color
surfaceContainerLowestLowest elevation container (darkest in dark mode, lightest in light mode) (matugen-only — see note)
surfaceContainerLowLow elevation container, between surface and surfaceContainer (matugen-only — see note)
surfaceContainerContainer background
surfaceContainerHighElevated container background
errorError state color
warningWarning state color
infoInfo state color

:::note Not all colors are used by DMS itself surfaceContainerLowest, surfaceContainerLow, and backgroundText are not rendered by DankMaterialShell's own UI. They complete the Material palette and are exported to matugen templates (VS Code, KDE, Firefox, Zed, etc.), so external apps themed via DMS use them. They are still required for a valid theme — pick sensible values that fit your palette. :::

For more details on how these colors are used, see Custom Themes.

  1. Validate your theme locally:
python3 .github/validate_themes.py
python3 .github/generate.py --validate
  1. Submit a Pull Request
    • Commit only your theme.json file (previews are auto-generated)
    • A preview will be generated and posted as a comment on your PR
    • After merge, the preview SVG will be committed automatically

Guidelines

For Plugins

  • Keep descriptions concise and informative
  • Ensure your repository has proper documentation
  • Test that your plugin works with the specified compositors and distros
  • Include a screenshot when possible

For Themes

  • All color values must be 6-digit hex codes (e.g., #7aa2f7)
  • Both dark and light variants are required
  • The id must be camelCase (starts lowercase, alphanumeric only)
  • Version must follow semver format (X.Y.Z)
  • Test your colors for readability and contrast

Questions?

If you have questions about the contribution process, please open an issue in the registry repository.