Skip to main content

Component library

Context: Choose library for component composition

We want a low-level solution for component definition in the Design System.

Core priorities are:

  • Developer Experience (DX)
  • Runtime performance
  • Minimal bundle size (allow dynamic loading or tree-shaking)
  • Stability

Nice to have:

  • Framework agnostic
  • Modular
  • Theme Specification support
  • Built-in QoL functionality
    • Accessibility
    • Keyboard navigation
    • Automatic color contrast
    • RTL

This ADR does not decide only on a library to use but overall approach on how we plan to implement reusability into the DS. The CSS library has already been decided in ADR - CSS. Other options are presented as representatives of an approach instead of specifically picking them for technical details.

Considered Options

Decision Outcome

Both libraries/approaches provide us with a great list of benefits, however, their means of achieving that are in opposition to each other. It would be very unintuitive to make them work together and this would result in a poor DX and poor adoption of the DX.

We did not want to hard-lock ourselves into a specific library API, so for every component we will ensure it is wrapped within a standardized Component API layer. This will be achieved by exposing a list of props which will align with the naming system from the design team. By applying this interface pattern we can maintain a unified DX without exposing the internals or tightly coupling dependencies into projects consuming the Design System.

In the beginning we will be using Stitches with its component definition and theme provider system due to its familiarity as it uses a similar API to styled-components. We hope this will ease the adoption of the system overall in the earlier versions. It also enables us to utilise some pre-made components from Radix-UI, for which Stitches comes with a first-class support.

Positive Consequences

  • Modularity
  • Standardized API of consumed components
  • DX
  • Easy migration to any other internals

Negative Consequences

  • React only
  • Need to build components from scratch
  • Small amount of extra boilerplate and verbosity to define the interface for each component

Pros and Cons of the Options

[Stitches]

  • Good - Familiarity
  • Good - Use of Theme Specification
  • Good - Native variants support
  • Good - Runtime performance
  • Good - Minimal size impact
  • Good - Tight interop with Radix-UI
  • Bad - React lock-in (There are options via @stitches/core, but we would still depend on implementing all components manually in a framework)
  • Bad - Implementing everything from scratch

[FAST]

  • Good - Runtime performance
  • Good - Minimal size impact
  • Good - Uses native browser component API (Framework agnostic)
  • Good - Built-in A11Y, keyboard support, auto-contrast, RTL, ...
  • Bad - Completely new API for a React consumer
  • Bad - Steeper learning curve to use without a React wrapper