Skip to content

Component lifecycle

How a component moves from experimental to stable to deprecated, with live adoption across the suite.

The four statuses#

Status tells you how much to trust a component. Every component page shows it beside the title, and the catalog filters by it.

Experimental

27 components

The component exists in packages/canon, but no surface has adopted it or its API is still settling.

Enters when
The file lands in packages/canon with a registry entry and a page, however short.
Leaves when
Moves to Beta once a surface uses it and its page is written. Removed if nothing adopts it.
What you can rely on
Nothing yet. Expect renames and changed props.

Beta

67 components

Used on at least one surface and documented. The API may still change.

Enters when
A screen in the suite imports it, and its page covers usage, examples and API.
Leaves when
Moves to Stable once it is used across surfaces, documented in every section, accessible and its API is settled.
What you can rely on
The job it does. If a prop changes, the change updates every call site.

Stable

71 components

Used across surfaces, documented in every section, accessible, and its API is frozen except for additions.

Enters when
A review confirms adoption in more than one app, a complete page, and keyboard, screen-reader and reduced-motion support.
Leaves when
Only by deprecation.
What you can rely on
Props, slots and behavior. Changes are additive.

Deprecated

0 components

On its way out. The page names the replacement and a removal date.

Enters when
A replacement exists and is at least Beta, and the page says what to use instead and when the old one goes.
Leaves when
Deleted on the removal date, once no file imports it.
What you can rely on
It keeps working until the removal date. Move to the replacement.

How a component moves#

Five steps from an idea to a Stable component. Most components stop at Beta for a while, and that's fine.

  1. 1Propose

    Name the job, why no existing component does it, and the two places it will be used. Check the catalog first; most jobs are taken.

  2. 2Build in packages/canon

    Follow the file anatomy: a Base UI primitive where one exists, cva variants, data-slot on every part, tokens only.

  3. 3Document in Canon

    Add the registry entry as Experimental, run bun run design:sync, and write guidance.ts, demos.tsx and doc.tsx.

  4. 4Adopt

    Use it on a real surface in place of whatever was there. One surface makes it Beta.

  5. 5Review

    Check it against DESIGN.md and the named rules, test keyboard and screen reader, and record drift under known gaps. Promote to Stable when it is used across surfaces.

Contribution checklist#

What a component needs before it enters Canon. A reviewer walks the same list.

  • Read DESIGN.md and the named rules the component touches.
  • Built on a Base UI primitive where one exists, with data-slot on every part, className merged last and named exports.
  • Tokens only: no raw colors, radii of 6, 8, 10 or 12px, and no filled indigo beyond the one primary action.
  • Every state drawn: hover, focus, pressed, selected, disabled, invalid and loading, plus loading, empty and error if it shows data.
  • Accessible names, roles and visible focus. Keyboard works everywhere a pointer does, and motion respects reduced motion.
  • Reads correctly in light and dark, at 390 and 1440px wide.
  • A registry entry with status, level, category, import path and exports, then bun run design:sync.
  • A guidance.ts with when to use and not, rules, accessibility, an API entry for every export, and honest known gaps.
  • Three to seven demos in Cedarline copy, each doing something visible.
  • bunx biome check --write and bun run check-types pass.

Versioning#

Canon lives in a prototype monorepo and is not published. Status is the contract, not a version number.

Versioning facts, read from package.json
FactToday
Package version0.0.0, never bumped
PublishedNo. The package is private and apps depend on it as workspace:*.
ChangelogNone. Git history and each page's known gaps record change.

Because every consumer lives in this repo, a change to a component updates its call sites in the same change. Nothing pins an old version. Stable components only gain props; renaming or removing one means deprecating it with a named replacement first.

Adoption#

Read from the code on every build: for each component, the files in apps/web that import it, grouped by app.

  • Experimental27
  • Beta67
  • Stable71
  • Deprecated0

0 of 165 components are imported somewhere in the suite. 138 have a status that disagrees with their adoption.

Where status and adoption disagree#

Each flag compares the status criteria above with the measured usage. A flag is a prompt for review, not a verdict.

Components whose status and adoption disagree
ComponentStatusLevelFilesAppsFlag
Action barBetaOrganism0NoneNo surface uses it, which Beta requires.
AI loaderBetaAtom0NoneNo surface uses it, which Beta requires.
AI messageBetaOrganism0NoneNo surface uses it, which Beta requires.
AlertBetaMolecule0NoneNo surface uses it, which Beta requires.
Approval cardBetaOrganism0NoneNo surface uses it, which Beta requires.
BadgeBetaAtom0NoneNo surface uses it, which Beta requires.
BreadcrumbBetaMolecule0NoneNo surface uses it, which Beta requires.
Button groupBetaMolecule0NoneNo surface uses it, which Beta requires.
CardBetaMolecule0NoneNo surface uses it, which Beta requires.
Card stackBetaOrganism0NoneNo surface uses it, which Beta requires.
Card tableBetaOrganism0NoneNo surface uses it, which Beta requires.
Choice cardBetaMolecule0NoneNo surface uses it, which Beta requires.
ComboboxBetaMolecule0NoneNo surface uses it, which Beta requires.
Demo controlsBetaUtility0NoneNo surface uses it, which Beta requires.
DiffBetaMolecule0NoneNo surface uses it, which Beta requires.
Filter chipBetaMolecule0NoneNo surface uses it, which Beta requires.
Form dialogBetaOrganism0NoneNo surface uses it, which Beta requires.
Icon actionBetaMolecule0NoneNo surface uses it, which Beta requires.
Icon morphBetaAtom0NoneNo surface uses it, which Beta requires.
IllustrationBetaAtom0NoneNo surface uses it, which Beta requires.
Inline stat stripBetaMolecule0NoneNo surface uses it, which Beta requires.
Insight cardBetaOrganism0NoneNo surface uses it, which Beta requires.
JSON schema builderBetaOrganism0NoneNo surface uses it, which Beta requires.
JSON viewerBetaMolecule0NoneNo surface uses it, which Beta requires.
KanbanBetaOrganism0NoneNo surface uses it, which Beta requires.
Latency timelineBetaOrganism0NoneNo surface uses it, which Beta requires.
Live transcriptBetaOrganism0NoneNo surface uses it, which Beta requires.
LogoBetaAtom0NoneNo surface uses it, which Beta requires.
Meta lineBetaMolecule0NoneNo surface uses it, which Beta requires.
Mobile breakpointBetaUtility0NoneNo surface uses it, which Beta requires.
Monogram tileBetaAtom0NoneNo surface uses it, which Beta requires.
One-time codeBetaMolecule0NoneNo surface uses it, which Beta requires.
Overflow fadeBetaUtility0NoneNo surface uses it, which Beta requires.
Page titleBetaOrganism0NoneNo surface uses it, which Beta requires.
Password inputBetaMolecule0NoneNo surface uses it, which Beta requires.
Pending buttonBetaMolecule0NoneNo surface uses it, which Beta requires.
ProgressBetaAtom0NoneNo surface uses it, which Beta requires.
Prompt barBetaOrganism0NoneNo surface uses it, which Beta requires.
Prompt editorBetaOrganism0NoneNo surface uses it, which Beta requires.
Provider model pickerBetaOrganism0NoneNo surface uses it, which Beta requires.
Radial chartBetaMolecule0NoneNo surface uses it, which Beta requires.
Recommendation cardBetaOrganism0NoneNo surface uses it, which Beta requires.
Resizable panelsBetaMolecule0NoneNo surface uses it, which Beta requires.
Section headerBetaMolecule0NoneNo surface uses it, which Beta requires.
Select fieldBetaMolecule0NoneNo surface uses it, which Beta requires.
SeparatorBetaAtom0NoneNo surface uses it, which Beta requires.
Side tabsBetaMolecule0NoneNo surface uses it, which Beta requires.
SidebarBetaOrganism0NoneNo surface uses it, which Beta requires.
Simulated streamBetaUtility0NoneNo surface uses it, which Beta requires.
Slider fieldBetaMolecule0NoneNo surface uses it, which Beta requires.
Source cardsBetaMolecule0NoneNo surface uses it, which Beta requires.
Stacked dialogBetaOrganism0NoneNo surface uses it, which Beta requires.
StepperBetaMolecule0NoneNo surface uses it, which Beta requires.
Task listBetaMolecule0NoneNo surface uses it, which Beta requires.
Text swapBetaAtom0NoneNo surface uses it, which Beta requires.
ThinkingBetaMolecule0NoneNo surface uses it, which Beta requires.
ThreadBetaOrganism0NoneNo surface uses it, which Beta requires.
TimelineBetaMolecule0NoneNo surface uses it, which Beta requires.
Timezone selectBetaMolecule0NoneNo surface uses it, which Beta requires.
Toggle groupBetaMolecule0NoneNo surface uses it, which Beta requires.
Tool chipBetaMolecule0NoneNo surface uses it, which Beta requires.
ToolbarBetaMolecule0NoneNo surface uses it, which Beta requires.
Variable chipBetaAtom0NoneNo surface uses it, which Beta requires.
Video facadeBetaMolecule0NoneNo surface uses it, which Beta requires.
Voice orbBetaAtom0NoneNo surface uses it, which Beta requires.
Voice pickerBetaOrganism0NoneNo surface uses it, which Beta requires.
WellBetaAtom0NoneNo surface uses it, which Beta requires.
Agent avatarStableAtom0NoneStable, but no app imports it.
AI generate buttonStableMolecule0NoneStable, but no app imports it.
Animated numberStableAtom0NoneStable, but no app imports it.
AvatarStableAtom0NoneStable, but no app imports it.
Business hours pickerStableOrganism0NoneStable, but no app imports it.
ButtonStableAtom0NoneStable, but no app imports it.
CalendarStableMolecule0NoneStable, but no app imports it.
ChartStableOrganism0NoneStable, but no app imports it.
CheckboxStableAtom0NoneStable, but no app imports it.
Class namesStableUtility0NoneStable, but no app imports it.
Code blockStableMolecule0NoneStable, but no app imports it.
Code snippet tabsStableMolecule0NoneStable, but no app imports it.
CollapsibleStableMolecule0NoneStable, but no app imports it.
Command menuStableOrganism0NoneStable, but no app imports it.
Confirm dialogStableOrganism0NoneStable, but no app imports it.
Copy buttonStableMolecule0NoneStable, but no app imports it.
Copy rowStableMolecule0NoneStable, but no app imports it.
Data gridStableOrganism0NoneStable, but no app imports it.
Data stateStableOrganism0NoneStable, but no app imports it.
DialogStableOrganism0NoneStable, but no app imports it.
Dirty formStableUtility0NoneStable, but no app imports it.
Dropdown menuStableMolecule0NoneStable, but no app imports it.
DropzoneStableMolecule0NoneStable, but no app imports it.
Duration pickerStableMolecule0NoneStable, but no app imports it.
Editable textStableMolecule0NoneStable, but no app imports it.
EmptyStableMolecule0NoneStable, but no app imports it.
FieldStableMolecule0NoneStable, but no app imports it.
Flow canvasStableOrganism0NoneStable, but no app imports it.
Fluid hoverStableUtility0NoneStable, but no app imports it.
Health barStableMolecule0NoneStable, but no app imports it.
Hold buttonStableMolecule0NoneStable, but no app imports it.
Icon swapStableAtom0NoneStable, but no app imports it.
IdenticonStableAtom0NoneStable, but no app imports it.
Info tipStableMolecule0NoneStable, but no app imports it.
InputStableAtom0NoneStable, but no app imports it.
Input groupStableMolecule0NoneStable, but no app imports it.
KbdStableAtom0NoneStable, but no app imports it.
Key-value editorStableMolecule0NoneStable, but no app imports it.
LabelStableAtom0NoneStable, but no app imports it.
MeterStableAtom0NoneStable, but no app imports it.
Mini chartStableMolecule0NoneStable, but no app imports it.
Mock queryStableUtility0NoneStable, but no app imports it.
Native selectStableMolecule0NoneStable, but no app imports it.
Option selectStableMolecule0NoneStable, but no app imports it.
Page introStableOrganism0NoneStable, but no app imports it.
PopoverStableMolecule0NoneStable, but no app imports it.
QR codeStableMolecule0NoneStable, but no app imports it.
Radio groupStableAtom0NoneStable, but no app imports it.
Save barStableOrganism0NoneStable, but no app imports it.
Search fieldStableMolecule0NoneStable, but no app imports it.
Segmented controlStableMolecule0NoneStable, but no app imports it.
SelectStableMolecule0NoneStable, but no app imports it.
Settings sectionStableOrganism0NoneStable, but no app imports it.
SheetStableOrganism0NoneStable, but no app imports it.
SkeletonStableAtom0NoneStable, but no app imports it.
SliderStableAtom0NoneStable, but no app imports it.
Sortable listStableOrganism0NoneStable, but no app imports it.
SpinnerStableAtom0NoneStable, but no app imports it.
SpringsStableUtility0NoneStable, but no app imports it.
Stat stripStableMolecule0NoneStable, but no app imports it.
Status labelStableAtom0NoneStable, but no app imports it.
Streaming textStableMolecule0NoneStable, but no app imports it.
SwitchStableAtom0NoneStable, but no app imports it.
TableStableOrganism0NoneStable, but no app imports it.
TabsStableMolecule0NoneStable, but no app imports it.
TagStableAtom0NoneStable, but no app imports it.
Tag inputStableMolecule0NoneStable, but no app imports it.
TextareaStableAtom0NoneStable, but no app imports it.
ToastStableMolecule0NoneStable, but no app imports it.
TooltipStableMolecule0NoneStable, but no app imports it.
WaveformStableAtom0NoneStable, but no app imports it.

Every component#

Sorted by status, then by the number of files that import it.

Adoption of every component
ComponentStatusLevelFilesApps
AccordionExperimentalMolecule0None
Alert dialogExperimentalOrganism0None
Aspect ratioExperimentalUtility0None
AttachmentExperimentalMolecule0None
BubbleExperimentalMolecule0None
CarouselExperimentalOrganism0None
CascaderExperimentalOrganism0None
Context menuExperimentalMolecule0None
Direction providerExperimentalUtility0None
DrawerExperimentalOrganism0None
FiltersExperimentalOrganism0None
Hairline illustrationExperimentalMolecule0None
Hover cardExperimentalMolecule0None
ItemExperimentalMolecule0None
Latency sparklineExperimentalAtom0None
MarkerExperimentalAtom0None
MenubarExperimentalOrganism0None
MessageExperimentalMolecule0None
Message scrollerExperimentalOrganism0None
Model pickerExperimentalMolecule0None
Navigation menuExperimentalOrganism0None
PaginationExperimentalMolecule0None
QuestionnaireExperimentalOrganism0None
Scroll areaExperimentalUtility0None
Selection actionsExperimentalOrganism0None
Size contextExperimentalUtility0None
ToggleExperimentalAtom0None
Action barBetaOrganism0None
AI loaderBetaAtom0None
AI messageBetaOrganism0None
AlertBetaMolecule0None
Approval cardBetaOrganism0None
BadgeBetaAtom0None
BreadcrumbBetaMolecule0None
Button groupBetaMolecule0None
CardBetaMolecule0None
Card stackBetaOrganism0None
Card tableBetaOrganism0None
Choice cardBetaMolecule0None
ComboboxBetaMolecule0None
Demo controlsBetaUtility0None
DiffBetaMolecule0None
Filter chipBetaMolecule0None
Form dialogBetaOrganism0None
Icon actionBetaMolecule0None
Icon morphBetaAtom0None
IllustrationBetaAtom0None
Inline stat stripBetaMolecule0None
Insight cardBetaOrganism0None
JSON schema builderBetaOrganism0None
JSON viewerBetaMolecule0None
KanbanBetaOrganism0None
Latency timelineBetaOrganism0None
Live transcriptBetaOrganism0None
LogoBetaAtom0None
Meta lineBetaMolecule0None
Mobile breakpointBetaUtility0None
Monogram tileBetaAtom0None
One-time codeBetaMolecule0None
Overflow fadeBetaUtility0None
Page titleBetaOrganism0None
Password inputBetaMolecule0None
Pending buttonBetaMolecule0None
ProgressBetaAtom0None
Prompt barBetaOrganism0None
Prompt editorBetaOrganism0None
Provider model pickerBetaOrganism0None
Radial chartBetaMolecule0None
Recommendation cardBetaOrganism0None
Resizable panelsBetaMolecule0None
Section headerBetaMolecule0None
Select fieldBetaMolecule0None
SeparatorBetaAtom0None
Side tabsBetaMolecule0None
SidebarBetaOrganism0None
Simulated streamBetaUtility0None
Slider fieldBetaMolecule0None
Source cardsBetaMolecule0None
Stacked dialogBetaOrganism0None
StepperBetaMolecule0None
Task listBetaMolecule0None
Text swapBetaAtom0None
ThinkingBetaMolecule0None
ThreadBetaOrganism0None
TimelineBetaMolecule0None
Timezone selectBetaMolecule0None
Toggle groupBetaMolecule0None
Tool chipBetaMolecule0None
ToolbarBetaMolecule0None
Variable chipBetaAtom0None
Video facadeBetaMolecule0None
Voice orbBetaAtom0None
Voice pickerBetaOrganism0None
WellBetaAtom0None
Agent avatarStableAtom0None
AI generate buttonStableMolecule0None
Animated numberStableAtom0None
AvatarStableAtom0None
Business hours pickerStableOrganism0None
ButtonStableAtom0None
CalendarStableMolecule0None
ChartStableOrganism0None
CheckboxStableAtom0None
Class namesStableUtility0None
Code blockStableMolecule0None
Code snippet tabsStableMolecule0None
CollapsibleStableMolecule0None
Command menuStableOrganism0None
Confirm dialogStableOrganism0None
Copy buttonStableMolecule0None
Copy rowStableMolecule0None
Data gridStableOrganism0None
Data stateStableOrganism0None
DialogStableOrganism0None
Dirty formStableUtility0None
Dropdown menuStableMolecule0None
DropzoneStableMolecule0None
Duration pickerStableMolecule0None
Editable textStableMolecule0None
EmptyStableMolecule0None
FieldStableMolecule0None
Flow canvasStableOrganism0None
Fluid hoverStableUtility0None
Health barStableMolecule0None
Hold buttonStableMolecule0None
Icon swapStableAtom0None
IdenticonStableAtom0None
Info tipStableMolecule0None
InputStableAtom0None
Input groupStableMolecule0None
KbdStableAtom0None
Key-value editorStableMolecule0None
LabelStableAtom0None
MeterStableAtom0None
Mini chartStableMolecule0None
Mock queryStableUtility0None
Native selectStableMolecule0None
Option selectStableMolecule0None
Page introStableOrganism0None
PopoverStableMolecule0None
QR codeStableMolecule0None
Radio groupStableAtom0None
Save barStableOrganism0None
Search fieldStableMolecule0None
Segmented controlStableMolecule0None
SelectStableMolecule0None
Settings sectionStableOrganism0None
SheetStableOrganism0None
SkeletonStableAtom0None
SliderStableAtom0None
Sortable listStableOrganism0None
SpinnerStableAtom0None
SpringsStableUtility0None
Stat stripStableMolecule0None
Status labelStableAtom0None
Streaming textStableMolecule0None
SwitchStableAtom0None
TableStableOrganism0None
TabsStableMolecule0None
TagStableAtom0None
Tag inputStableMolecule0None
TextareaStableAtom0None
ToastStableMolecule0None
TooltipStableMolecule0None
WaveformStableAtom0None

What the count misses

Adoption counts files in apps/web only, and excludes the docs. A component used only inside other packages/canon components, such as Kbd inside the save bar, reads lower than it is. Components pages import several at once, so one file can count toward many rows.

Each component page shows the same numbers in its header, with the files that import it. See All components to filter by status.