Introduction

The DSH Web interface defaults to only three appearance options: Follow System, Light, and Dark. If you want to change the color scheme, there is no ready-made entry. @kongxiangyiren/dhs-theme-plugin fills this gap: it adds a “Themes” category under “Settings,” includes built-in Forest Green and Ocean Blue themes, and allows the upload of custom JS themes. Click to switch, data is saved to the disk, so it won’t be lost when switching browsers. Below is an introduction to its features, installation, and usage.

What is this

This is a DSH theme management plugin by the author kongxiangyiren, version 0.0.3, MIT license. DSH’s philosophy is “everything is a plugin,” and this plugin extends it at the interface layer: it does two things: first, it provides built-in themes, and second, it leaves a pathway for those who want to do it themselves to upload custom themes.

Core Features

  • “Settings → Themes” Category: A new theme category at the same level as “General” in Settings.
  • Built-in Themes: Forest Green and Ocean Blue, covering 13 alias tokens, accompanied by texture effect CSS (glow, grid/ripple, vignette, neon bands).
  • Upload Custom JS Themes: Single files in __ModuleLoader__.load format, supporting overrideTokens for color changes, CSS injection, and slots for registering UI components, with require("react") available inside the factory, no file size limit.
  • Click to Switch: Uploaded themes appear directly in the main list; one click applies them. Switching to a built-in theme automatically disables the uploaded theme, ensuring only one is active at a time.
  • Disk Persistence: The Host side registers a webServer route GET/POST /api/theme-plugin, data is stored under the DSH home directory, independent of the browser.

Installation and Usage

First, install the plugin:

dsh plugin --profile web add @kongxiangyiren/dhs-theme-plugin

This command adds the package to the dsh.profile.bundles list in the profile. If you don’t want to use npm, you can also install directly from Git—the package is pure JS, has no prepare script, and does not require allowBuilds authorization:

dsh plugin --profile web add git+https://github.com/kongxiangyiren/dhs-theme-plugin

After installation, start normally:

npx @deepseek-ai/dsh web

To uninstall when no longer needed:

dsh plugin --profile web remove @kongxiangyiren/dhs-theme-plugin

Daily Usage

  1. Open “Settings → Themes”.
  2. Click list items to switch: Follow System / Light / Dark / Forest Green / Ocean Blue / Uploaded Themes.
  3. To use your own theme, click “Select JS File” and choose a theme script.
  4. The “Uploaded Themes” area allows you to check the status of each theme (Applied / Not Applied) and delete them.

The repository’s examples/ directory includes two example themes that can be uploaded directly: cyberpunk-theme.js is a terminal style with a black background and fluorescent green, featuring grid, scanlines, neon bands, and glitch effects; nekogirl-theme.js is a pink cat-girl style, demonstrating the usage of require("react") combined with slots to register UI components. Note that these examples are not published with the npm package; you need to get them from the GitHub repository.

Writing Your Own Theme

Uploaded files must be in the browser bundle format (same as the dsh.client package), with the entry point attached to window.__ModuleLoader__.load. Below is a minimal color-changing theme:

window.__ModuleLoader__.load({
  id: 'my-theme',
  factory: require => {
    var module = { exports: {} };
    var exports = module.exports;
    function apply(ctx) {
      ctx.effect(
        () =>
          ctx.theme.overrideTokens('my-theme', {
            '--dsw-alias-bg-base': { light: '#ffffff', dark: '#0f1115' },
            '--dsw-alias-brand-primary': { light: '#7c3aed', dark: '#a78bfa' }
          }),
        'my-theme tokens'
      );
    }
    exports.apply = apply;
    return module.exports;
  }
});

The mini ctx received by apply provides theme / slots / effect / on / once / timeout / interval / get / console, and require("react") is supported inside the factory. The code above only implements overrideTokens for color changes. By combining this with CSS injection or registering components via slots, you can create themes with a heavier style. Once written, go back to “Settings → Themes” to upload; the theme will appear in the main list.

Where is the Data Stored

Each uploaded theme is stored as an individual .js file, and the index is stored separately:

  • Theme files: ~/.dsh/dhs-theme-plugin-themes/<id>-<hash>.js
  • Index (metadata + selected state): ~/.dsh/dhs-theme-plugin.json

The index content looks roughly like this:

{
  "themes": [{ "id": "my-theme", "name": "my-theme", "file": "my-theme-a1b2c3.js", "active": true }],
  "selected": "ocean"
}

active records the enabled status, and selected remembers the selected item for themes like Forest Green and Ocean Blue. In older versions, data embedded in the index source code was automatically split into separate files upon the first read. Since the data is all under the DSH home directory on the disk, your theme settings remain even when opening with a different browser.

Usage Notes

  1. Uploaded JS will execute directly in the page; only use trusted files. The plugin runs with the permissions of the current DSH process. It is recommended to review the source code and license before installing.
  2. Changes to the Host side require restarting the application to take effect.
  3. Example themes are not published with the package and need to be obtained from the examples/ directory of the GitHub repository.

Summary

What this plugin does is not complicated: it adds a theme category, includes two built-in color schemes, leaves a pathway for uploading custom themes, and saves data to disk. It is suitable for those who want to personalize the DSH Web interface or want to try writing their own themes. Source code and examples are on GitHub: https://github.com/kongxiangyiren/dhs-theme-plugin; Community plugin directory page: https://www.skillhub.cn/plugins/kongxiangyiren/dhs-theme-plugin (independently maintained by the community, with no official affiliation to DeepSeek or Hanhuan).