Component lifecycle
Statuses, how a component becomes shared, the checklist a reviewer walks, and which components the apps use.
Statuses
| Status | Means | To get here | Today |
|---|---|---|---|
| Experimental | In the package with a handbook page, but no app uses it from the package yet. Its API may still change. |
| 37 |
| Beta | Used from the package on at least one real screen. Safe to adopt; changes are announced in the changelog. |
| 0 |
| Stable | Shared across Bridge. Its API only grows: nothing is renamed or removed without going through Deprecated first. |
| 0 |
| Deprecated | Being replaced. Don't use it in new work. |
| 0 |
The build enforces part of this: a component marked Beta or Stable with an unwritten guidance section fails the build.
From idea to Stable
Six steps. Most components stay at Beta for a while, and that's fine.
- Check first. Search the handbook. If a component already does the job, use it, or add an option to it.
- Propose. Name the job, why nothing existing does it, and the two places (or the second app) that need it.
- Build in the package. Start from shadcn’s Base UI version (
npm run ui-add), move it onto Bridge tokens, and match Bridge OS’s API if one exists. - Document. Add it to
registry/pages.tsas Experimental and runnpm run design:sync. Then write its guidance, live examples, numbered anatomy drawing and states grid. - Adopt. Use it from the package on a real screen, merged to the app’s main branch. Refresh the adoption snapshot (below). One screen makes it ready for Beta.
- Review. Walk the checklist, test it with a keyboard and a screen reader, and list anything still off under known gaps. Change its status in the registry. It moves to Stable once it’s used in two places or by a second app.
Versions
Each app chooses which version of @brdgapp/ui it uses, so every release says what it changes.
| Change | Version | Example |
|---|---|---|
| A fix that changes nothing an app relies on | Last number | 1.0.0 → 1.0.1 |
| A new component, or a new option on one | Middle number | 1.0.1 → 1.1.0 |
| Anything that could break an app: a rename, a removal, a changed default | First number | 1.1.0 → 2.0.0 |
This holds for every status, Experimental included: a change that could break an app always gets a new first number.
Before something is renamed or removed, it's marked Deprecated for at least one release. Its page names the replacement and the version it goes away in.
Every release gets a line in packages/ui/CHANGELOG.md. To release, bump the version in packages/ui/package.json, add the changelog entry, merge, then push a tag with the same number (v1.1.0). GitLab runs every check and publishes to npm.
Today: 1.0.0 is ready but not published yet. npm needs its Trusted Publisher set up for this GitLab project first (a one-time step by one of the package's npm owners); then the v1.0.0 tag publishes it. Until then, changes go into the 1.0.0 notes.
Reviewer's checklist
What a component needs before it's added, and what a reviewer walks before changing its status.
- Read DESIGN.md and the named rules the component touches.
- Colors, radius and spacing come from tokens and the scales; no hex, no palette classes.
- Every rendered part has a
data-slot; variants are acvarecipe;classNameis merged last; named exports only. - Interactive parts are built on Base UI; links pass through
renderand stay links. Extra attributes (id,aria-*,data-*) reach the main element. - Every state is drawn and works: hover, focus, pressed, selected, disabled, loading; and loading, empty and error (DataState) if it shows data, with a skeleton the same size as the loaded content.
- Keyboard works everywhere a pointer does, focus shows, every control is named, contrast is met in both themes, motion respects reduced motion.
- Reads correctly in light and dark, at 390px and 1440px.
- A registry entry with status, level, category and import path;
npm run design:syncrun. - Its page has every guidance section, an API entry for every export, honest known gaps and sources, a numbered anatomy drawing, a states grid (if it has states) and three to seven live examples using the sample network's people.
npm run buildpasses: the registry check, the token tests, types and lint.
Adoption
Which components each Bridge app uses from the package, read from the app's main branch. Only merged code counts. A flag means a component's status and its use disagree: a prompt to review, not a verdict.
- Bridge OS:
origin/mainat5d9b382, taken 2026-11-02.
0 of 37 components are used on an app's main branch. Every status matches its use.
No app imports the package on its main branch yet. Bridge OS's move onto the package is in an open merge request; when it merges, refresh the snapshot and review the flags.
| Component | Status | Level | Files | Review |
|---|---|---|---|---|
| ActionMenu | Experimental | molecule | 0 | |
| Avatar | Experimental | atom | 0 | |
| Badge | Experimental | atom | 0 | |
| Bottom sheet | Experimental | molecule | 0 | |
| BrandMark | Experimental | atom | 0 | |
| Button | Experimental | atom | 0 | |
| ButtonGroup | Experimental | molecule | 0 | |
| Card | Experimental | molecule | 0 | |
| Checkbox | Experimental | atom | 0 | |
| Collapsible | Experimental | molecule | 0 | |
| ColumnFilterMenu | Experimental | molecule | 0 | |
| ColumnSortButton | Experimental | atom | 0 | |
| ConfirmDialog | Experimental | organism | 0 | |
| CopyField | Experimental | atom | 0 | |
| DataState | Experimental | utility | 0 | |
| DataTable | Experimental | organism | 0 | |
| Dialog | Experimental | organism | 0 | |
| Drawer | Experimental | organism | 0 | |
| ExpandableBio | Experimental | atom | 0 | |
| Field | Experimental | molecule | 0 | |
| FilterChip | Experimental | atom | 0 | |
| FilterPill | Experimental | molecule | 0 | |
| Hover card | Experimental | molecule | 0 | |
| IconButton | Experimental | atom | 0 | |
| InfoHint, HoverTip and Tip | Experimental | atom | 0 | |
| Input | Experimental | atom | 0 | |
| PageBanner | Experimental | molecule | 0 | |
| SearchInput | Experimental | atom | 0 | |
| SegmentedControl | Experimental | molecule | 0 | |
| Skeleton | Experimental | atom | 0 | |
| StatBox | Experimental | molecule | 0 | |
| Switch | Experimental | atom | 0 | |
| Tabs | Experimental | molecule | 0 | |
| Tag | Experimental | atom | 0 | |
| TagInput | Experimental | molecule | 0 | |
| Textarea | Experimental | atom | 0 | |
| Toast | Experimental | atom | 0 |
To refresh, fetch the app's main branch, then run npm run design:adoption -- --app "Bridge OS" --repo <path to the app> and commit registry/adoption.ts. It only reads the app's code.
Rules
Sources
- Status criteria approved by Aman 2026-11-02 (
registry/statuses.ts). - Sharing rule: decision 2026-11-02 (#11).
- Versions: decision 2026-11-02 (#17). Publishing: GitLab publishes on a version tag (decision 2026-11-02).
- Adding a component: plan
03-architecture.md→ Component base. - Bridge OS
components.md→ How to use this file (update the docs in the same change). - Adoption:
registry/adoption.ts, a snapshot of each app's main branch taken byscripts/adoption.ts. Decision 2026-11-02: only code merged to main counts. - Oration Canon → Component lifecycle (the review step, the checklist, adoption read from code).