How it works
DynUI is built on one idea: a model may compose your UI, but it may never free-draw it.
Instead of asking a model to produce markup, you register real components from your design system — each with a behavioral contract — and the model’s only degree of freedom is which registered components to compose, how to arrange them, and which variants to select for this user. A strict validator sits between generation and render; anything off-contract is rejected and a deterministic engine composes the screen instead.
Project boundary
Section titled “Project boundary”DynUI is self-hosted and bring-your-own-provider. It does not include a hosted control plane, managed model, hosted registry console, experiment service, analytics warehouse, or team account system. Your app keeps those systems and connects them through adapters.
Use DynUI when the missing layer is contract-validated structural personalization, not when the team simply needs a flag, CMS entry, or hosted experimentation dashboard.
The six planes
Section titled “The six planes”| # | Plane | What it does | Package |
|---|---|---|---|
| 01 | Contract | Designers annotate components in Figma with a behavioral contract — surfaces, data, audience, accessibility. | @dynui/figma |
| 02 | Manifest | The registered vocabulary: variants, slots, required data, experiment gates. Linted and versioned. | @dynui/contracts |
| 03 | Profile | Behavior resolves to a segment. PII stays on your side of the adapter — the engine sees signals, not people. | @dynui/profile |
| 04 | Compose | A model — backed by a deterministic engine — assembles a UI tree from eligible components only. | @dynui/generate |
| 05 | Validate | The render gate. Off-contract trees never reach a user, from any provider. | @dynui/validate |
| 06 | Render | Your renderer maps the tree to real components — measured per component, canaried per experiment. | @dynui/experiments |
The tree is the contract
Section titled “The tree is the contract”Providers emit a JSON UITree, never markup. The validator enforces the full
contract in context: unknown component types, oversized trees, missing required
data, consent violations, and experiment-gated components without an assignment
are all rejected before render.
The fallback is not the product — but it is the guarantee
Section titled “The fallback is not the product — but it is the guarantee”The recommended way to run DynUI is with a model provider composing screens. The deterministic engine exists so that a timeout, a malformed response, or a failed repair never breaks a user’s screen: generation always resolves to a valid tree or an explicit, typed non-renderable result. It also means CI, local development, and consent-denied sessions work without any API key.
Consent is code
Section titled “Consent is code”Deny-by-default. Without personalization consent the engine composes a neutral screen and the validator rejects anything targeted. Prompts are minimized and redacted; the model never sees user identifiers.