Contributing
JDS is small on purpose: every component should earn its place in an agent or voice product.
Setup
git clone https://github.com/JacopoContin/jds
pnpm install
pnpm devAdding a component
Start from the problem
Open an issue describing the agent or voice moment it serves before writing code.
Write the component
In
components/ai,components/voiceorcomponents/ui. Build on Base UI and existing JDS parts. Import icons fromlib/iconsand motion fromlib/motion.Add a demo
examples/<slug>-demo.tsx, with realistic agent-product content.Register it
Add an entry to
lib/docs.ts. Add-ons setparentand become a section of that page. Then runpnpm registry:build; dependencies are read from your imports and the build fails if something is missing.
Quality bar
npx tsc --noEmit # types
pnpm lint # design-system rules: 0 errors, no eslint-disable
pnpm test:visual # every component and recipe, light and dark- Tokens, not values. Colors come from theme tokens. Neutral by default.
- Both themes. Every token set for light is set for dark; the registry build enforces it.
- Motion with meaning. Use the presets and respect reduced motion.
- Accessible. Keyboard reachable, labelled controls, status never shown by color alone.
Visual tests
Every component preview and recipe is screenshotted in light and dark with the clock paused, so timers and animations land in the same state each run. Voice visuals, which are random by design, are masked. Baselines are Linux screenshots made in CI: if a change is meant to look different, run the Visual tests workflow with update to regenerate them.
Releases
Conventional commits, a changelog line for anything user-facing, and new recipes in weekly drops of one or two complete screens.