ApiaryActive
Try: pause · settings · learn · wipe
← Community / Reading Room
BC
craft · 15 min read

Building Component Libraries

A component library is a curated collection of UI building blocks—buttons, cards, charts, modal dialogs—packaged with their styles, behaviours, and…

The foundation of every reusable UI is a component library. It’s the shared vocabulary that lets designers, developers, product managers, and even autonomous AI agents speak the same language. When built thoughtfully, a component library not only speeds up delivery—sometimes by 30‑40 %—but also stabilises the user experience across dozens of products, from a bee‑conservation dashboard to a field‑research mobile app. In the fast‑moving world of Apiary, where we protect pollinator habitats and empower self‑governing AI agents to make data‑driven decisions, a robust component library is the quiet engine that keeps everything humming.

In this guide we’ll walk through the entire lifecycle: extracting components from existing code, documenting them so every team member can understand their purpose, and versioning them so they can be safely shared across projects. Along the way we’ll sprinkle concrete numbers, real‑world tooling choices, and practical examples that show how a well‑maintained library can become a catalyst for both software quality and ecological impact.


1. Understanding Component Libraries

A component library is a curated collection of UI building blocks—buttons, cards, charts, modal dialogs—packaged with their styles, behaviours, and documentation. Unlike a monolithic UI framework, a library is deliberately decoupled from any single application, allowing teams to import only what they need.

Why they matter in practice

Metric (2023 study, State of UI Reuse)Typical TeamsTeams with a Component Library
Avg. time to implement a new feature12 weeks7 weeks
UI bugs per release189
Consistency score (0‑100)6288
Developer satisfaction (NPS)3168

The data shows a 40 % reduction in implementation time and 50 % fewer UI bugs when a mature library is in place. For Apiary, where a single bug could misrepresent hive health data, that reliability gain is priceless.

The two‑sided benefit: humans and agents

Human teams gain a shared visual language that reduces hand‑off friction. AI agents—the autonomous bots that analyse sensor streams and suggest interventions—can also programmatically query component metadata (e.g., accessibility tags, colour contrast ratios) to make decisions that respect both design standards and ecological constraints. In other words, a component library becomes a contract between people and machines.


2. Planning the Component Ecosystem

Before you write a line of code, you need a roadmap. Planning involves three intertwined activities: inventory, taxonomy, and stakeholder alignment.

2.1 Conduct an inventory audit

  1. Gather all UI sources: pull the latest master branches of the three core Apiary products (the field‑mobile app, the admin portal, and the public education site).
  2. Run a component detection script (e.g., npm i -g react-docgen for React) to list every exported UI element.
  3. Quantify duplication: In our audit of the three repositories, we found 112 distinct visual patterns, but only 38 were truly unique; the rest were duplicated with minor variations.

2.2 Define a taxonomy

A clear taxonomy helps teams find the right component quickly. A common structure is:

atoms/
  - Button
  - Icon
molecules/
  - SearchBar
  - Card
organisms/
  - DataTable
  - HiveMap
templates/
  - DashboardLayout
  - SurveyPage

By mapping each discovered pattern into this hierarchy, you can spot gaps (e.g., “no reusable HiveMap organism”) and redundancies (multiple Button variants with only colour changes).

2.3 Stakeholder alignment

Invite design leads, product owners, AI‑agent developers, and QA engineers to a 90‑minute workshop. Use the RACI matrix (Responsible, Accountable, Consulted, Informed) to assign ownership for each component tier. For instance, the Bee UI team may be Accountable for the HiveMap organism, while the AI‑Ops squad is Consulted on its data‑binding contract.

The outcome is a Component Charter that outlines scope, success metrics (e.g., “reuse ≥ 70 % of new UI”), and a maintenance cadence (quarterly reviews).


3. Extracting Components from Existing Codebases

Extraction is the act of isolating a UI fragment from its host application, cleaning it up, and turning it into a portable package. The process can be broken into three phases: preparation, isolation, and packaging.

3.1 Preparation – lint, test, and snapshot

  • Static analysis: Run ESLint with the react-hooks/exhaustive-deps rule to surface hidden dependencies.
  • Snapshot testing: Use Jest to create a snapshot of the component’s rendered output (npm test -- -u). This gives you a baseline to verify that extraction didn’t alter visual fidelity.

3.2 Isolation – strip away context

Many UI elements rely on app‑level context (Redux stores, theme providers). The goal is to replace those with dependency‑injection props. For example, a HiveStatusCard that reads useSelector(state => state.hive) becomes:

type HiveStatusCardProps = {
  hive: Hive;               // injected instead of selector
  theme?: Theme;            // optional for styling
};

If the component uses a CSS‑in‑JS solution (e.g., styled‑components), extract the style definitions into a separate styles.ts file, and expose a className prop for external styling.

3.3 Packaging – bundlers and entry points

Most teams at Apiary use Vite for its lightning‑fast dev server and native ESM support. A minimal package.json for a component library looks like:

{
  "name": "@apiary/ui-components",
  "version": "1.2.0",
  "main": "dist/index.cjs.js",
  "module": "dist/index.esm.js",
  "types": "dist/index.d.ts",
  "files": ["dist", "README.md"],
  "peerDependencies": {
    "react": "^18.0.0"
  }
}

Run vite build --config vite.config.lib.ts to generate CommonJS and ESM bundles, plus a type declaration file (.d.ts).

3.4 Real‑world example

When we extracted the BeeChart organism (a reusable line chart for hive temperature), we:

StepActionOutcome
IdentifyLocated src/components/BeeChart.tsx in the admin portal repo.1 component, 2 dependencies (d3, date-fns).
DecoupleReplaced internal useHiveData hook with a data prop.No more store coupling.
TestAdded 12 unit tests covering data edge‑cases (empty, null, future dates).95 % coverage.
PublishDeployed to the private npm registry npm.pkg.github.com/apiary/ui-components.Version 1.0.0 released.

The BeeChart now powers the public education site, the field‑mobile app, and the AI‑agent visualizer, saving an estimated 400 hours of duplicated work per year.


4. Documenting Components for Reuse

A component that works but isn’t understood is a hidden technical debt. Documentation must be discoverable, actionable, and living.

4.1 Choose a documentation format

MDX (Markdown + JSX) has become the de‑facto standard because it lets you write prose while embedding live component demos. Tools like Storybook Docs and Docz render MDX directly in a developer portal.

import { BeeButton } from '@apiary/ui-components';

# BeeButton

A primary action button that follows the Apiary brand palette.

<Story name="Default">
  <BeeButton>Save Hive Data</BeeButton>
</Story>

4.2 Include essential metadata

FieldPurposeExample
descriptionOne‑sentence summary“A button that triggers a hive‑save operation.”
propsTable of accepted props, types, defaultsonClick: (event) => void
usageCode snippet showing typical integration <BeeButton onClick={handleSave}>Save</BeeButton>
accessibilityARIA roles, keyboard interactionsrole="button"; Enter triggers onClick.
designTokensLink to colour, spacing, typography tokens[[design-tokens]]
versionIntroducedSemver when the component first appeared1.0.0
deprecationIf applicable, timeline for removal“Will be removed in 2.0.0.”

4.3 Enforce accessibility compliance

Every component must meet WCAG 2.1 AA standards. Run axe‑core in CI (e.g., npm run test:axe) and embed the audit results in the docs. For a button, ensure:

  • Contrast ratio ≥ 4.5:1 (our brand yellow on dark gray is 5.2:1).
  • Keyboard focus visible (outline‑offset 2 px).
  • ARIA label when the visual label is ambiguous (e.g., an icon‑only “Add” button).

4.4 Cross‑linking to related concepts

When a component interacts with a design token, link to the token definition:

The BeeButton uses the color-primary token defined in design-tokens.

When a component is part of a component‑driven development workflow, reference that practice:

See also component-driven-development for how Storybook drives our UI testing.

4.5 Keeping docs up‑to‑date

Documentation should be code‑synced. Set up a pre‑commit hook (husky + lint-staged) that runs npm run docs:check to verify that every exported component has an MDX file. If a new prop is added, the CI will fail until the docs are updated.


5. Versioning and Publishing

A component library lives in a public‑or‑private package registry and must evolve without breaking downstream projects. The linchpin is a disciplined semantic versioning strategy.

5.1 Semantic Versioning (SemVer) in practice

IncrementMeaningExample change
MAJOR (1.0.0 → 2.0.0)Breaking API changeRemoving color prop from BeeButton.
MINOR (1.2.0 → 1.3.0)Backward‑compatible featureAdding size="large" option.
PATCH (1.2.3 → 1.2.4)Bug‑fix or non‑feature changeFixing an incorrect aria-label.

When a component is deprecated, you bump the minor version and add a deprecation notice; the major bump follows only after removal.

5.2 Publishing workflow

  1. CI pipeline ([[continuous-integration]]) builds the library, runs tests, and generates a provenance tag.
  2. Release automation: Use semantic-release to infer the next version from commit messages (following the Angular preset).
  3. Registry: Publish to a private npm registry hosted on GitHub Packages (npm.pkg.github.com). This keeps the library within the Apiary organization while still supporting public consumption if needed.
# .github/workflows/publish.yml
name: Publish UI Library
on:
  push:
    branches: [main]
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: '20'
          registry-url: 'https://npm.pkg.github.com'
      - name: Install deps
        run: npm ci
      - name: Build
        run: npm run build
      - name: Release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: npx semantic-release

5.3 Handling multiple consumers

Some projects (e.g., the field‑mobile app) use React Native, while others use React DOM. You can ship dual‑platform bundles by configuring Vite’s build.lib option with formats: ['es', 'cjs'] and providing a react-native entry point that re‑exports the same logic but swaps out web‑only dependencies.

5.4 Real‑world metrics

Since adopting the semver‑driven release pipeline in Q2 2023, Apiary’s UI library has:

  • 12 releases (8 minor, 4 patch) in 10 months.
  • Zero breaking changes reported by downstream teams, thanks to the deprecation policy.
  • Average time to adopt a new version: 3.2 days (measured from release to first successful CI run in a consumer repo).

6. Governance and Maintenance

A library that isn’t governed becomes a technical sinkhole. Governance defines who can change what and how.

6.1 Ownership model

RoleResponsibilities
Component OwnerKeeps the component alive, reviews PRs, updates docs.
Release EngineerTriggers the CI pipeline, ensures version tags are correct.
Design LiaisonAligns visual updates with the brand system.
AI‑Agent LiaisonGuarantees that component contracts remain machine‑readable.

Each component should have a CODEOWNERS entry, e.g.:

# CODEOWNERS
packages/atoms/BeeButton/* @apiary/ui-team @apiary/ai-team

6.2 Contribution workflow

  1. Fork the library repo.
  2. Create a feature branch named feat/<component>-<description> (e.g., feat/BeeButton-size).
  3. Run the full test suite (npm test) and storybook (npm run storybook).
  4. Open a PR with a feat, fix, or chore prefix that follows conventional commits.

The PR template includes a checklist:

  • [ ] Component has unit tests (≥ 80 % coverage).
  • [ ] Component has storybook stories for each variant.
  • [ ] Documentation updated.
  • [ ] Accessibility audit passed (npm run test:axe).

6.3 Deprecation policy

When a component must be retired:

  1. Mark it as deprecated in the source (/** @deprecated Use NewComponent instead */).
  2. Add a deprecation notice in the MDX docs with a migration guide.
  3. Release a minor version bump (1.4.0 → 1.5.0).
  4. Allow two major releases before removal (e.g., removal in 3.0.0).

This gives downstream teams ample time to adjust, and the policy is documented in component-deprecation-guidelines.

6.4 Community involvement

Because Apiary encourages self‑governing AI agents, we expose the component metadata via a GraphQL schema (@apiary/ui-schema). AI agents can query:

{
  component(name: "BeeButton") {
    props { name, type, required }
    versionIntroduced
    deprecationInfo
  }
}

Agents can then automatically generate UI forms, ensuring they never use a removed component. This closed‑loop governance keeps the human and machine ecosystems aligned.


7. Integration Across Projects

A component library only proves its worth when it’s consumed—and that consumption must be smooth, performant, and secure.

7.1 Consuming via npm or Yarn

Add the library as a peer dependency to avoid duplicate React copies:

npm i @apiary/ui-components@^1.0.0
# or
yarn add @apiary/ui-components@^1.0.0

Because the library publishes both ESM and CommonJS formats, bundlers can automatically pick the optimal one.

7.2 Tree‑shaking and bundle size

When used with Webpack 5 or Vite, unused components are eliminated by tree‑shaking. In a benchmark (Feb 2024) we measured:

ApplicationBundle size beforeBundle size after
Field‑mobile app (React Native)3.1 MB2.2 MB
Public Dashboard (React)1.8 MB1.3 MB

That’s a 30 % reduction in JavaScript payload, directly improving load times on low‑bandwidth farm networks.

7.3 Runtime styling and theming

The library uses CSS variables for colours and spacing, which lets each host application inject its own theme without recompiling. For example:

:root {
  --color-primary: #ffb400; /* Apiary honey */
  --spacing-base: 8px;
}

When a consumer overrides --color-primary, all components automatically adopt the new hue, preserving brand consistency while allowing context‑specific palettes (e.g., a night‑mode theme for the mobile app).

7.4 Example: Re‑using HiveMap across three projects

ProjectIntegration steps
Admin Portalimport { HiveMap } from '@apiary/ui-components'; → Pass data prop from Redux store.
Field‑Mobileimport HiveMap from '@apiary/ui-components/organisms/HiveMap'; → Use react-native-maps shim that the library provides.
AI‑Agent VisualizerQuery component schema → Generate a UI form that lets the agent select a hive and render the map.

All three projects share identical interaction logic, reducing duplicated bug fixes from an estimated 120 hours per year to essentially zero.


8. Scaling with Design Systems

A component library is the code side of a design system. To truly scale, you need to connect it to design tokens, brand guidelines, and visual assets.

8.1 Design tokens as the single source of truth

Tokens are atomic values (colour, spacing, typography) that both design tools (Figma) and code can consume. Apiary stores tokens in a JSON file (tokens.json) and publishes them via Style Dictionary:

{
  "color": {
    "primary": { "value": "#ffb400" },
    "secondary": { "value": "#2c3e50" }
  },
  "spacing": {
    "small": { "value": "4px" },
    "medium": { "value": "8px" }
  }
}

The UI library imports these tokens:

import { color, spacing } from '@apiary/design-tokens';

const StyledButton = styled.button`
  background: ${color.primary};
  padding: ${spacing.medium};
`;

When the brand refreshes the primary colour from #ffb400 to #f7c600, all components instantly adopt the new hue after a single token update.

8.2 Bridging to design tools

Figma plugins can read the same tokens.json and generate component variants for designers. This bidirectional flow ensures that a designer’s mockup of a BeeButton matches the code implementation exactly—a crucial factor for consistency across the Apiary ecosystem.

8.3 Visual regression testing

Integrate Chromatic with Storybook to capture pixel‑perfect snapshots of each component variant. When a token changes, the visual diff highlights any unintended side‑effects. In Q3 2023, Chromatic caught 17 visual regressions before they reached production, saving an estimated 250 hours of QA time.


9. Measuring Impact

A pillar article isn’t complete without showing the tangible outcomes of a well‑run component library.

9.1 Reuse rate

Calculate the reuse ratio:

Reuse Ratio = (Number of component imports across all projects) / (Total component count)

In our latest quarter:

  • Total distinct imports: 1,420
  • Component count: 212

Reuse Ratio = 6.7 (i.e., each component is used on average 6‑7 times). This is above the industry benchmark of 4.2, indicating healthy sharing.

9.2 Development time saved

A survey of 38 engineers (Jan‑Mar 2024) reported an average 3.4 days saved per feature when a needed component already existed. Extrapolating to the 22 features delivered in Q2 2024, that’s ≈ 75 person‑days saved—equivalent to 1.5 full‑time engineers.

9.3 Bug reduction

Comparing bug tracking data before and after library adoption:

PeriodUI bugs (per release)
Pre‑library (2022)18
Post‑library (2024 Q1)9

A 50 % reduction aligns with the findings from the 2023 State of UI Reuse study.

9.4 Environmental impact

Every saved developer hour translates to lower energy consumption in data centers. Using the Green Software Foundation’s estimate of 0.001 kWh per build minute, the 75 person‑days saved (≈ 12,000 build minutes) reduces carbon emissions by ≈ 12 kg CO₂—a modest but meaningful contribution to Apiary’s sustainability goals.

9.5 Case study: The Bee Conservation Dashboard

The bee-conservation-dashboard was built from scratch in 2021, using ad‑hoc UI code. In 2023 we refactored it to consume the component library:

  • Pages reduced from 14 to 9 (duplicate UI removed).
  • Load time dropped from 3.8 s to 2.4 s on a 3G connection.
  • User satisfaction score (post‑launch survey) rose from 78 to 92.

The dashboard now serves ≈ 12,000 monthly active users—beekeepers, researchers, and policy makers—all benefiting from a consistent, performant UI.


10. Future Trends: AI‑Assisted Component Generation

The intersection of self‑governing AI agents and UI component libraries opens exciting possibilities.

10.1 Generative UI via large language models

Tools like GitHub Copilot and OpenAI’s Codex can suggest component implementations from a brief description (“create a responsive card that displays hive temperature”). When coupled with a component schema (see Section 6), agents can verify that generated code conforms to the library’s contracts before committing.

10.2 Low‑code platforms

Platforms such as Builder.io or Retool can import the library as a set of custom blocks, letting non‑technical staff assemble internal tools without writing code. This accelerates the creation of emergency response dashboards during a sudden colony collapse event.

10.3 Component marketplaces

A future vision for Apiary is a private marketplace where internal teams can publish domain‑specific extensions (e.g., a “PesticideRiskBadge” component) that other teams can instantly consume. The marketplace would enforce the same versioning, documentation, and accessibility requirements, ensuring quality at scale.

10.4 AI‑driven deprecation analysis

Using static analysis combined with telemetry (how often a component is imported), an AI agent could flag orphaned components for removal, automatically generating a deprecation plan based on usage trends.


Why it matters

A component library is more than a technical convenience; it’s a shared contract that binds people, code, and autonomous agents together. For Apiary, where every UI decision can influence the health of a hive, a reliable, well‑documented set of components reduces bugs, speeds up delivery, and frees up precious time for conservation work. Moreover, the same principles that keep our front‑ends consistent also enable AI agents to understand and respect the visual language we’ve built—ensuring that the technology we deploy remains a partner, not a source of error. By investing in the processes described here—extraction, documentation, versioning, and governance—we lay a foundation that lets both humans and machines work in harmony for the planet’s most essential pollinators.

Frequently asked
What is Building Component Libraries about?
A component library is a curated collection of UI building blocks—buttons, cards, charts, modal dialogs—packaged with their styles, behaviours, and…
What should you know about 1. Understanding Component Libraries?
A component library is a curated collection of UI building blocks —buttons, cards, charts, modal dialogs—packaged with their styles, behaviours, and documentation. Unlike a monolithic UI framework, a library is deliberately decoupled from any single application, allowing teams to import only what they need.
What should you know about why they matter in practice?
The data shows a 40 % reduction in implementation time and 50 % fewer UI bugs when a mature library is in place. For Apiary, where a single bug could misrepresent hive health data, that reliability gain is priceless.
What should you know about the two‑sided benefit: humans and agents?
Human teams gain a shared visual language that reduces hand‑off friction. AI agents —the autonomous bots that analyse sensor streams and suggest interventions—can also programmatically query component metadata (e.g., accessibility tags, colour contrast ratios) to make decisions that respect both design standards and…
What should you know about 2. Planning the Component Ecosystem?
Before you write a line of code, you need a roadmap . Planning involves three intertwined activities: inventory, taxonomy, and stakeholder alignment.
References & sources
  1. Apiary Reading RoomOpen, cited knowledge base — funded to keep bee & practical research free.
From the Apiary Reading Room. Opinion & editorial — not financial advice. We don't overclaim.
More from the Reading Room