Skip to main content
Every registry component follows the same shape. This page is what it takes to add one to mzizi-dev/mzizi-registry.
New work goes to Rust. Mzizi’s own components are being rebuilt in Rust as Mzizi Roots, and that is where new component work goes. The .tsx steps below are the React build, which keeps working but is deprioritised. A component with a Rust sibling lives beside its .tsx as a .rs file and has a contract test asserting the two agree. The design for Roots is still being written, so check the registry for its current conventions before starting a Rust component.

1. Create the component file

Components live under components/registry/n<number>-<name>/, filed by the node they sit on. See placing a component if you are unsure which that is.

2. Follow the mandatory patterns

Every component carries:
  • CVA variants — class-variance-authority for every visual variant, never inline conditional classes.
  • cn() composition — all className props go through it.
  • A data-slot attribute on the root element.
  • Named exports — the component and its variants. No default export.
  • Radix UI primitives for focus, keyboard and screen-reader behaviour where the component is interactive.
  • TypeScript types extending the appropriate HTML element props.

3. Add it to registry.json

An item with more than one source file where the schema expects exactly one is a manifest bug rather than a bad request, and the API says so — worth knowing when a component 500s and the source looks fine.

4. Run the generators

pnpm build is the registry’s whole build. There is no app to build: it runs every generator, and CI’s Build job fails if running it changes a committed file.

5. Check it resolves

There is no local server: the registry removed its app, /api/* included, on 2 October 2026. Once the change is on main and the API’s pin has moved to it, curl https://api.mzizi.dev/v1/ui/my-component returns the metadata and the inlined source.

6. Add tests

7. Run everything

pnpm check chains every CI gate locally.

Checklist

  • CVA + Radix + cn() throughout
  • CSS custom properties only — no hardcoded colours
  • data-slot on the root element
  • Named exports, no default export
  • Entry in registry.json with the right type and dependencies
  • pnpm registry:validate and pnpm registry:verify pass
  • pnpm build leaves no diff
  • Tests, lint and types pass
  • APCA 3.0 contrast, 48px minimum touch targets, keyboard navigation