Client UI & Slots
Browser-side development: register UI in Slots, use theme tokens, and write interfaces with React.createElement
The Client is a plugin's browser-side half, responsible for themes, layout, current page state, tool cards, and Slot UI. Client code runs in the browser and cannot use Node.js capabilities; for files, commands, or services, delegate to the Host side and call it through private JSON methods.
Write plain JavaScript only
Client code is not transformed by TypeScript, JSX, or a bundler. Therefore:
- No TypeScript types,
as, decorators,import, orrequire. - No JSX; React code must use
React.createElement(...).
// A React element in client code
React.createElement('div', { className: 'card' }, 'content')Register UI in a Slot
Client UI must be registered in a queried Slot; apply() cannot directly return a React element. A Slot is a named, registerable position in the client architecture.
Before registering, query the available Slot tree and confirm the target Slot's registration contract and props, then write code against that contract. This way the registered UI is unwound when the plugin unloads.
Theme tokens
Themes are expressed through tokens. The browser client packages keep the --dsw-* static scale and semantic aliases (--dsw-alias-*) in ui-theme, and ui-layout applies the resolved theme snapshot to the document. Feature packages consume semantic aliases rather than defining another global theme.
When overriding the theme or injecting styles from a plugin, treat them as reversible effects: unwind them on stop, update, or undefine.
Styling rules
Browser client components follow one styling convention:
- Use CSS Modules and
clsx; do not add a component library or Tailwind. - Use
--dsw-alias-*semantic tokens in feature components; do not copy static palette values or write literal colors. - Keep theme selectors out of feature component CSS; light/dark overrides belong to the theme owner.
- Pair font sizes with line heights and reuse the theme typography variables.
- Preserve keyboard focus visibility and reduced-motion behavior when adding transitions or hover-only controls.
Host/Client communication
The Client calls the Host through package-private JSON methods (Client → Host); only lossless JSON crosses that boundary. Do not serialize live data in plugin code — services, events, and sessions are internal live objects; read only the leaf fields the task needs, then build the smallest owned data object.
Next steps
- For the full dynamic plugin lifecycle, see Dynamic Plugins.
- For complete examples, see the Cookbook.