# Component Lifecycle

How Design System components mature inside the Design System, from Experimental through Beta to Stable.

Design System components move through three states inside the Design System: Experimental, Beta, and Stable. They start as experimental components built in `@aleph-alpha/ui-library/experimental` with lower governance, mature into Beta when they show cross-team value, and become Stable once their design and technical model are proven. This page describes each state, the criteria that move a component between them, and the workflows for contributing and deprecating components.

## Tooling

Component usage across products is tracked by `vue-component-analyzer`. The latest scan output is available at [main-scan](https://animated-funicular-jzw7q73.pages.github.io/pipeline/main-scan).

This data is the single source of truth for component adoption across the organisation. It helps us:

- Surface emerging patterns worth promoting.
- Gauge Beta adoption to decide readiness for Stable.
- Scope deprecation impact.
- Identify consumers and contributors.
- Guide where Design System investment is most valuable.

## Component States

### Experimental

**Definition.** An early-stage Design System component that lives inside the Design System, in Figma and the `@aleph-alpha/ui-library/experimental` package export, but has not yet met full Stable governance.

**Characteristics:**

- Lives in the Design System itself: a dedicated Experimental Figma library or section, unpublished to consumers by default, and a separate code export such as `@aleph-alpha/ui-library/experimental` with an explicit instability warning.
- Built on the same tokens, primitives, and tooling as the rest of the Design System, so there is no divergence in token usage or accessibility patterns.
- Maintained by the team that introduced it, with Design System team awareness.
- Skips the full review, documentation, and accessibility process required for Stable.
- API and visual treatment can still change.

**When to build Experimental.** Build Experimental when you need to ship a new pattern faster than full Stable governance allows. Experimental is a deliberate trade-off: lower governance now, with the foundations in place to mature into Beta and Stable later. Living in the Design System from day one gives the component visibility across teams, enabling the cross-team validation that drives promotion.

**Key distinction from Stable.** Governance, not location. Both live in the Design System. Experimental skips the heavy review, docs, and accessibility process while still using Design System foundations.

> Components built directly in product repos, not in `@aleph-alpha/ui-library/experimental`, are not Experimental in the lifecycle sense. They are discovery signals. See [Discovery / Triage](#discovery--triage).

### Beta

**Definition.** A component that has been promoted from Experimental after showing demand and cross-team value. It lives in the Design System, with design exploration in progress to standardise it, but the API and visual treatment can still change before promotion to Stable.

**Characteristics:**

- Built in the Design System as an Experimental component that has demonstrated cross-team value, or surfaced via Discovery / Triage from product-code patterns the Design System team decides to standardise.
- Pattern has potentially broad reach and could scale across multiple industries or product areas.
- Documented as a promotion candidate; design exploration is in progress to standardise it.
- May be published in the Design System package marked `Beta`; API and visual treatment can still change before promotion to Stable.

**What to expect from Beta.** Beta components are opt-in. They are usable, but expect the API or styling to change before they reach Stable. Pin the version if you need consumer-side stability.

### Stable

**Definition.** A fully standardised, accessible, production-grade Design System component, documented in Figma and in code.

**Characteristics:**

- 1:1 Figma to code mapping.
- Tokenized, documented, versioned.
- Stable API and behaviours; changes follow the [Deprecation Workflow](#deprecation-workflow).
- Maintained long-term by the Design System team.

**When to use.** Default to Stable for any production UI. Stable components are reliable, reusable, customisable, and supported long-term.

Previously known as Custom (Experimental), Shadow (Beta), and True (Stable). The old names may still appear in older diagrams and tickets.

### Code And Storybook Tags

Use `pnpm tag-component` to keep Storybook tags and generated docs metadata aligned with the lifecycle state:

```bash
pnpm --filter @aleph-alpha/ui-library tag-component UiAutocomplete experimental
pnpm --filter @aleph-alpha/ui-library tag-component UiAutocomplete beta
pnpm --filter @aleph-alpha/ui-library tag-component UiAutocomplete stable
pnpm --filter @aleph-alpha/ui-library tag-component UiAutocomplete deprecated
```

`experimental`, `beta`, and `deprecated` appear as visible Storybook badges. `stable` removes lifecycle tags and notes instead of adding a `stable` tag. `deprecated` adds a generic JSDoc `@deprecated` marker in `types.ts`; complete the full deprecation workflow below manually.

## Discovery / Triage

Components found in product repos by `vue-component-analyzer` that do not exist in the Design System are **not part of the lifecycle**. They are discovery signals, similar to product discovery ideas in Jira, that need triage before they can become a Design System component.

When the analyzer detects an unfamiliar component pattern in a product codebase, the Design System team triages with one of these outcomes:

| Outcome | What happens |
| ------- | ------------ |
| Duplicate | The pattern is already covered by an existing Design System component. Close the finding; advise the owner to migrate. |
| Won't do | The pattern is too narrow or does not fit the Design System. Close. |
| Spike | Worth more exploration before committing. Create a research ticket. |
| Move into DS | Pattern is worth standardising. Create a Design System ticket; the component is built in `@aleph-alpha/ui-library/experimental` and enters the lifecycle as Experimental. |
| Advise owner | Recommend the owner move the component into the Design System as best practice. Flag and follow up. |

Only the **Move into DS** outcome brings a component into the lifecycle as Experimental. All other outcomes keep the pattern repo-local with no Design System commitment.

## Promotion Criteria

### From Experimental To Beta

An Experimental component is promoted to Beta when the pattern recurs across PoCs, demonstrates cross-team relevance, and can be articulated as a coherent, generalisable interaction. The purpose of the Beta stage is to stabilise and refine the emerging pattern through focused design exploration, without yet committing it to the Design System. Beta candidates are continuously evaluated and iterated by the design team so that prioritised candidates can progress toward a mature, standardisable form.

Consider promoting when one or more factors are true:

1. **Recurrence:** appears repeatedly across PoCs, teams, or product areas, and is no longer a one-off need.
2. **Cross-team relevance:** used or requested by multiple incubation or application teams, signalling shared value.
3. **Market potential:** supports workflows with clear customer demand, validated opportunity, or strong GTM alignment.
4. **Stability of interaction model:** shows consistent behaviour across variations and can be expressed as a clean, repeatable pattern.
5. **Generalisability:** can be abstracted away from a single PoC and applies broadly across scenarios or industries.
6. **Accessibility baseline:** pattern can meet keyboard navigation, focus behaviour, and accessibility expectations without bespoke workarounds.
7. **Benchmark support:** exists in other mature systems, industry patterns, or open-source libraries, signalling standard viability.
8. **Reduction of fragmentation:** promoting it removes duplication, decreases custom hacks, and increases overall system coherence.
9. **Low risk of over-specialisation:** pattern is not too narrow, domain-specific, or brittle to support as part of the core Design System.
10. **Maintenance justification:** the long-term effort of maintaining it as a Design System asset is outweighed by adoption and impact.

### From Beta To Stable

A Beta component is promoted to Stable when its design, behaviour, and technical model prove stable, accessible, token-aligned, and ready for high-quality implementation in both Design System Figma and frontend code. At this stage, it is reliable enough to become an official Design System asset used across all teams. A Stable component is done when it is well documented and easily consumable by building teams.

## Component Contribution

The full flow a component follows from a developer's first need through evaluation, promotion to Beta, and finally to Stable. The diagram covers both consumption, using an existing component, and contribution, building a new one, paths.

See the [Component Contribution diagram in FigJam](https://www.figma.com/board/3QqtZZ6FJbeXn4dXj2msdy/Design-System-Processes?node-id=1071-845&t=5tkoAE26K6g9etqn-4).

## Deprecation Workflow

When a Stable component is replaced or retired, it follows a phased deprecation flow that gives consumer teams time to migrate without surprise breakage. The flow runs from approval, through consumer mapping using `vue-component-analyzer`, through marking the component as deprecated in code and Storybook, through migration support, and ends with removal on or after the agreed removal date.

See the [Deprecation Workflow diagram in FigJam](https://www.figma.com/board/3QqtZZ6FJbeXn4dXj2msdy/Design-System-Processes?node-id=1071-818&t=5tkoAE26K6g9etqn-4).

| # | Step | Owner |
| - | ---- | ----- |
| 1 | **Approve:** confirm replacement, record reason, get sign-off | DS |
| 2 | **List consumers:** run `vue-component-analyzer` using the latest [main-scan](https://animated-funicular-jzw7q73.pages.github.io/pipeline/main-scan) | DS |
| 3 | **Set removal date:** the date after which the component may be removed. Default is 3 months after announcement. | DS + Eng |
| 4 | **Mark in code:** add JSDoc `@deprecated` on `.vue`, `types.ts`, and `index.ts` | DS |
| 5 | **Mark in Storybook:** use `tags: ['autodocs', 'deprecated']` and a `parameters.docs.description.component` banner | DS |
| 6 | **Write migration guide:** before/after, replacement, edge cases, codemod if cheap | DS |
| 7 | **Announce:** Design System Mattermost public channel, release notes, direct message each consumer team | DS |
| 8 | **Follow up:** track usage, remind lagging teams, offer pairing | DS |
| 9 | **Remove on or after removal date:** delete component, types, index export; link migration guide in release notes | DS |

### Reference Deprecation Pattern (`UiIconButton`)

The current `UiIconButton` deprecation in `frontend-hub/packages/ui-library/src/components/UiIconButton/` is the working example. JSDoc `@deprecated` is added on the `.vue` component, `types.ts`, and `index.ts`. The Storybook meta uses `tags: ['autodocs', 'deprecated']` with a `parameters.docs.description.component` banner that explains the migration path.

JSDoc on `*.vue`, `types.ts`, and `index.ts`:

```typescript
/**
 * @deprecated `UiIconButton` will be removed in `@aleph-alpha/ui-library` **v1.26.0**.
 * It is being merged into `UiButton`. Use `UiButton` with an icon-only child and an
 * `aria-label` instead.
 */
```

Storybook meta:

```typescript
const meta: Meta<typeof UiIconButton> = {
  title: 'Components/UiIconButton',
  component: UiIconButton,
  tags: ['autodocs', 'deprecated'],
  parameters: {
    docs: {
      description: {
        component:
          '> **Deprecated, scheduled for removal in `@aleph-alpha/ui-library` v1.26.0.** ' +
          '`UiIconButton` is being merged into `UiButton`. Migrate to `UiButton` with an ' +
          'icon-only child and an `aria-label` instead, e.g. ' +
          '`<UiButton size="icon-sm" aria-label="Close"><UiIcon name="x" /></UiButton>`.',
      },
    },
  },
};
```

