Agents
Components, tokens, props, keyboard behavior, and install paths are available as text or JSON.
Surfaces
| Where | What |
|---|---|
https://vlak.dev/llms.txt | The index: what Vlak is, the install paths, one line per component |
https://vlak.dev/llms-full.txt | Everything in one file: every component's docs, props, keyboard, markup |
https://vlak.dev/docs/<name>.md | One component as markdown |
https://vlak.dev/r/<name>.json | The shadcn registry item: files, dependencies, classes |
https://vlak.dev/r/index.json | Every registry item |
npx @noorddev/vlak-cli list --json | The catalogue as JSON, offline |
npx @noorddev/vlak-cli docs <name> | One component's docs in the terminal |
npx @noorddev/vlak-cli tokens | The design tokens as JSON |
@noorddev/vlak/props | Every export's props as JSON, importable |
These surfaces are generated from one registry, so the markdown, JSON, and web documentation share one source. Start with llms.txt; it is the short index and links to the detailed records.
MCP server
{
"mcpServers": {
"vlak": {
"command": "npx",
"args": ["-y", "@noorddev/vlak-mcp"]
}
}
}@noorddev/vlak-mcp serves the same registry over the Model Context Protocol: list components, read one component's docs and props, fetch the tokens, and get the install command for a given path. Works offline; the snapshot ships in the package. Add the block above to your client's MCP configuration.
Conventions an agent can rely on
// State: value / defaultValue / onValueChange, everywhere a value lives
<Select options={cities} value={city} onValueChange={setCity} />
<Tabs defaultValue="overview" onValueChange={track} />
<Calendar value={date} onValueChange={setDate} />
// Booleans follow the same shape
<Switch checked={on} onCheckedChange={setOn} />
<Toggle pressed={bold} onPressedChange={setBold} />
// Overlays: open + onClose, parent state is the source of truth
<Dialog open={open} onClose={() => setOpen(false)} />
// className and style merge onto the root; refs are forwarded
<Button ref={ref} className="mine" style={{ marginTop: 8 }} />
// Every component has a name or takes one
<Slider aria-label="Volume" />- Value state is
value,defaultValue,onValueChange. Booleans usecheckedorpressedwith the matchingonCheckedChangeoronPressedChange. - Overlays take
openandonClose. The parent owns the state; Escape and backdrop clicks callonCloserather than closing on their own. classNameandstylemerge onto the root element. Native attributes pass through.- Refs are forwarded to the element that carries the role.
- Every component is named or takes
aria-label. Dialog parts name their dialog; Field parts describe their control. - Every component applies stable
rs-*classes. They are listed in the registry and on each page; compiled class hashes are not part of the contract. - Compound components are exported flat from the package root:
Dialog,DialogTitle,DialogBody,DialogActions. - Only three install paths exist: the package, the CLI, and shadcn. No CDN, no runtime fetch, no Tailwind, no Radix.