dsh-genui: interactive UI components inside DeepSeek Harness replies
GenUI for DeepSeek Harness: interactive UI components rendered inline in assistant replies via the dsh-ui fence — layout, charts, plots, forms, quizzes, mermaid, 3D scenes, and an action event loop back to the model. Ships the fence-teaching host plugin, the browser renderer (client half), and the genui skill.
At a glance
- What is it?
- dsh-genui renders declarative dsh-ui fences as charts, plots, forms and 3D scenes inline in a DSH assistant reply, with an action loop back to the model. It installs as a DSH plugin from npm, but the host must activate the browser half before anything appears.
- Who is it for?
- Adopt dsh-genui if you run a DSH build in the supported range and want model answers to carry live panels, plots or forms instead of static text. Skip it if you are on DSH 0.1.1-rc.x or older, or if you cannot run pnpm, since the dsh plugin command depends on it.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 16, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem dsh-genui solves for DSH users
A model reply is text. When the answer is a monthly revenue figure, a parameter sweep, or a quiz, text is a poor container: the reader has to ask a follow-up to see the breakdown, and the model has to re-emit numbers it already produced. dsh-genui exists to close that gap without replacing the prose. The README frames it as turning a model reply into a safe, interactive DSH surface, and the before-and-after table makes the intent concrete: a plain answer says revenue this month is ¥128,430, +12.4% MoM, while the same answer with dsh-genui carries three stat cards, a trend chart and a progress bar next to that sentence.
The audience is narrow and specific. You need to be running DeepSeek Harness, you need the DSH plugin system, and you need a model that has been taught the dsh-ui fence vocabulary. The repository ships the fence-teaching host plugin, the browser renderer (the client half) and a genui skill, so the pieces assume a DSH host rather than a generic chat UI. If you are building a standalone dashboard, this is not the layer you want; it renders inside an assistant reply, not as a page you own.
Dual-channel rendering: registry versus DOM
The mechanism worth understanding before installing is that the plugin ships two rendering channels and picks one automatically after the host activates its browser module. The registry channel applies when the host exposes a fence-registry extension point, in which case fences register through the host's streaming render pipeline. The DOM channel applies when the host lacks that extension point, including supported stock DSH builds; the plugin then observes the session DOM and mounts its own render tree.
The DOM channel is the more interesting engineering, and also the more fragile. Since 0.7.2 it supports streaming rendering, so the first finished component appears as soon as the model writes it rather than waiting for the whole reply. Since 0.8.3 fence discovery is multi-surface: it matches the stock md-code-block surface, the deepsuite-style .code-block and .code-block-small surfaces some host builds render instead, and as a structural backstop any element whose banner labels it dsh-ui and contains a pre body. The README states that if your DSH build renders fences with a different class name they still render, and a one-time console warning tells you the host DOM drifted. That warning is the honest part of the design: the fallback exists precisely because host markup is not a stable contract.
Whichever channel is active, the README says components, interactions, panels and persistence behave identically. That claim is the one to hold the project to, because the two paths reach the same result through very different machinery.
Installing the dsh-genui plugin and rendering a first component
Two prerequisites are stated as required. First, a DSH version in the range ^0.1.2-rc.1 || ^0.1.5-alpha.1 || ^0.1.6-alpha.1; the README notes that dsh-genui 0.11.1-preview.2 is verified on DSH 0.1.6-alpha.1 and the 0.1.2-rc.1 minimum, and that users on DSH <=0.1.1-rc.x should use dsh-genui 0.9.8. Second, pnpm on your PATH, because the dsh plugin command depends on it. If pnpm is missing, the README gives corepack enable or npm i -g pnpm, then asks you to open a new terminal and confirm pnpm -v prints a version.
With those in place, installation into DSH is one command, and the README notes the package is public so no npm account is needed:
# Public npm package (works without an npm account)
dsh plugin --profile web add @changfenhuang/dsh-genuiThere is a second, weaker option. If you only want the package as a Node dependency in an existing project, npm install adds it, but the README is explicit that this does not register the plugin with DSH:
npm install @changfenhuang/dsh-genuiOne warning in the README is worth repeating because it is a common way to break the install: do not use link: on a freshly cloned directory. The README states that link: does not install the plugin's dependencies (mermaid, three, react), so the renderer will break. Reserve link: for local development iteration.
Activation is the part people get wrong. The README says a downloaded client.js or a ModuleLoader cache entry proves only that bytes arrived. Successful activation always prints this line, and if it is absent you should fix package or profile identity or host activation first:
[genui] client active; fence-channel=registry|domDOM attributes such as data-streaming and data-chat-anchor-key are described as optional fallbacks, not installation prerequisites. For a first real use, the README points at demo-prompts.md for the four-step prompt sequence used in the walkthrough, which moves from an answer-embedded panel through forms, plotting, Mermaid and 3D-oriented components.
What the dsh-ui fence can actually render
The component vocabulary is documented in SKILL.md, which the README describes as the supported, guarded dsh-ui component specification. The package description lists the surface area: layout, charts, plots, forms, quizzes, mermaid, 3D scenes, and an action event loop back to the model. The three outputs the README shows are a monitoring panel with refresh and reset controls, time-range selection, statistics, charts and a service table; a function plot whose curves redraw locally as draggable parameter sliders, reset and animation controls change; and layout primitives (typography, grid, card, row and column) composing into a structured surface.
The action event loop is the part that distinguishes this from static chart embedding. The README's before-and-after table describes a panel that already has Refresh and Switch view buttons, where clicking causes the model to update the data. That is a round trip: the UI emits an action, the model responds. It is also the part with the least visible documentation in the README itself, which points to SKILL.md for the specification rather than restating it.
Local interactivity is a deliberate design choice. The plot redraws locally as parameters change, so dragging a slider does not require a model call. Only the actions that need new data go back to the model. That split keeps the interaction responsive and keeps token spend tied to genuine data changes rather than to every drag.
Where dsh-genui breaks or is the wrong choice
The DOM channel is the main failure surface. It works by observing the session DOM and matching known fence class names, which means it is coupled to host markup the project does not control. The README acknowledges this by shipping a structural backstop and a one-time console warning when the host DOM drifts. A warning is not a repair: if a future DSH build changes its fence markup enough that neither the known surfaces nor the dsh-ui banner plus pre body heuristic matches, components stop rendering and the only signal is that warning.
Version coupling is the second constraint. The README names a supported DSH range and a specific fallback (dsh-genui 0.9.8 for DSH <=0.1.1-rc.x). Outside that range you are not in tested territory. The current release line is also a preview: 0.11.1-preview.2, published alongside DSH 0.1.6-alpha.1, follows 0.11.1-preview.1 and 0.11.0 within two days. Frequent preview releases are normal for a project tracking an alpha host, but they also mean the surface you install today is not a settled one.
Finally, consider the fit. dsh-genui renders inside assistant replies. If you need a dashboard that survives independently of a conversation, or a UI your own application controls, this is the wrong tool: the plugin's persistence is described as behaving the same across channels, but the container is still a DSH session. And if you cannot install pnpm on the machine running DSH, the documented install path does not work at all.
How dsh-genui differs from a charting library
The obvious comparison is to a charting library such as ECharts or a plotting stack such as Vega-Lite, and the difference is not the drawing code. dsh-genui's package exports include ./assets/echarts-core and ./assets/echarts, so it is not competing with those renderers at the drawing layer. The difference is who writes the specification and where the result lives.
With a charting library, a developer writes the chart code, owns the data flow, and places the output in an application. With dsh-genui, the model emits a declarative dsh-ui fence inside its reply, and the plugin turns that fence into a live component in place, with an action loop back to the model when the user interacts. The README describes the layout primitives as combining into a hierarchy the model can describe declaratively, which is the whole point: the author of the UI is the model, not you.
That trade has a cost. A developer-authored chart can be tested, typed and versioned; a model-authored fence is only as good as the skill teaching it and the guards in SKILL.md. The README calls the specification guarded, which suggests validation exists, but the README does not enumerate what the guards reject. If you need deterministic, reviewable UI, a conventional charting library with your own components remains the better fit.
Licence and the cost of keeping up with an alpha host
The package is MIT licensed, and package.json sets publishConfig access to public, so the npm package is published publicly and the README's install command works without an npm account. MIT is permissive and imposes no source-disclosure obligation on your own code; that is a statement about the licence text, not legal advice, and if you redistribute the package inside a product you should read the LICENSE file in the repository yourself.
The upgrade cost is the more practical question. The release history shows 0.11.0, 0.11.1-preview.1 and 0.11.1-preview.2 landing on 2026-09-15 and 2026-09-16, each tied to a specific DSH version (0.1.6-alpha.1 for the previews). The last push to the repository was on 2026-09-16. That cadence tells you what maintenance looks like in practice: the project moves with the host, and a DSH upgrade is the event that forces a dsh-genui upgrade. The README already documents one such migration, for the old @omdsh-dev package name, noting that installs from github:omdsh-dev/dsh-genui before v0.9.2 may leave pnpm holding a stale identity. Budget for reading CHANGELOG.md before each DSH bump rather than treating the plugin as install-once.
Editorial conclusion
Adopt dsh-genui if you run a DSH build in the supported range and want model answers to carry live panels, plots or forms instead of static text. Skip it if you are on DSH 0.1.1-rc.x or older, or if you cannot run pnpm, since the dsh plugin command depends on it. Verify three things before trusting it in a workflow: that your DSH version matches the range in the README, that the console prints [genui] client active; fence-channel=registry|dom after activation, and that the fences your build emits are matched by the DOM channel's discovery rules.
Frequently asked questions
How do I install dsh-genui into DSH?
Run dsh plugin --profile web add @changfenhuang/dsh-genui. It requires pnpm on your PATH and a DSH version in the range ^0.1.2-rc.1 || ^0.1.5-alpha.1 || ^0.1.6-alpha.1. A plain npm install only adds the dependency and does not register the plugin with DSH.
Why do no dsh-genui components appear in the reply after installing?
The host owns client activation, and the README states that successful activation always prints [genui] client active; fence-channel=registry|dom. If that line is missing, the browser half never activated, so fix package or profile identity or host activation before checking anything else.
Can I use link: to install dsh-genui from a cloned directory?
The README warns against it for normal installation: link: does not install the plugin's dependencies (mermaid, three, react), so the renderer will break. Use the npm install command instead and reserve link: for local development iteration.
Community notes