Introduction
The headless core owns the state transitions and the accessibility semantics: what is open, what is selected, what a screen reader should be told about it. Each framework adapter takes that and renders it as its own native component.
Recipes
Start with one complete workflow, including its loading, empty, failure, and recovery states.
Install
The CLI uses package delivery wherever the selected registry layer publishes it. Styled components include bounded CSS and a component leaf import; headless and machine packages expose the lower-level contracts. Add --mode source to copy editable files, or use --eject as the styled-source shortcut. Source-only entries fail with that explicit recovery command rather than silently copying files.
pnpm dlx grassroot add ui/selectEvery component page carries its own command, switchable across pnpm, npm, yarn and bun.
Theming
Set a theme on the document root. Six tokens give a useful minimum; the rest resolve from the base contract.
[data-theme="custom"] {
--surface-canvas: #0b0f14;
--surface-card: #131a22;
--text-heading: #e6edf3;
--text-body: #9fb0c0;
--accent: #4cc38a;
--border-strong: #24313d;
}Parity
Behaviour, DOM output, accessibility, keyboard interaction, SSR, hydration, types, contracts, theme resolution and visual output all get checked in CI before a release goes out. When one adapter drifts from the other four, the build is what tells you, rather than someone using it. See the same Select mounted in five runtimes, or read the browser and accessibility evidence per component.
CLI
The CLI is published on npm as grassroot. init sets up an existing TypeScript app. New configs default styled, headless, and machine to package delivery; legacy configs retain their source-first default until migrated.
npx grassroot init
npx grassroot add ui/dialog
npx grassroot add ui/dialog --layer headless
npx grassroot add ui/dialog --layer machine
npx grassroot add ui/dialog --layer headless --mode source
npx grassroot add ui/dialog --eject--dry-run prints the plan, --diff a unified diff, and existing source files are never overwritten without --overwrite. grassroot doctor reports what is installed and what has drifted. The registry declares package and source availability in immutable JSON addressed by SHA-256; grassroot registry build produces a private copy you can vendor internally.
MCP
The MCP server exposes the same generated contract data as the site: props, events, slots and accessibility requirements.