Pass the data.
The component does the rest.
A list is an items array. A tree is a nested shape. A form is its schema. Rokkit components read their own data — selection, validation, theming, keyboard, a11y — so your code stays about what the user sees, not how to wire it.
$ bun add @rokkit/ui Data is the API
A List takes items. A Tree takes a nested shape. A Form reads its schema. No snippet trees, no recursive composition — pass the data, get a working control.
One config drives every look
Pick a style (zen-sumi, rokkit, minimal, material), a skin (paper / ink / accent palette), a typography pair, a density. Set it once on the body — every component picks it up.
Density is a data attribute
Compact for a power-user table. Cozy for a settings page. Comfortable for an onboarding flow. Type stays put — only the rhythm changes.
Embeddable in any AI surface
Every component is a typed artifact — items in, value out, no global state. Drop one into Claude, into your own chat, into Rokkit's playground. Same code, themed to its host.
The same <Tabs/>, rendered four ways — by changing one
attribute on the parent.
No variant prop. No conditional CSS in the component. The style — zen-sumi
underline, rokkit block, minimal hairline, material pill — comes from data-style on the body. Components don't know which one is on;
they just render.
data-style="zen-sumi" ink fill · saffron branddata-style="rokkit" gradient · ocean branddata-style="minimal" underline · violet branddata-style="material" pill · rose brandPull in only what you need.
The library is the chat is the docs.
Open the playground, ask for any component or how-to, get a real working artifact back. Browse the same components from the sidebar. Read the same docs they were mounted from.