Bedrock Flows — Documentation
Design systems

Variants & auto-generation

How variants.json drives the build, and why the whole catalogue is generated from the content.

You author three files per component — component.css, macro.njk, variants.json. Everything else (the rendered variants, the bundled stylesheet, the Storybook) is generated from those files. This page explains how, and why it's done that way.

How the variant logic works

Each entry in a component's variants.json is a named prop set rendered through the component's macro. Given:

{
  "macro": "button",
  "variants": [
    { "name": "Primary", "filename": "primary", "props": { "label": "Continue", "variant": "primary" } }
  ]
}

the generator calls the button macro with { "label": "Continue", "variant": "primary" } and writes the rendered markup to primary.html in the component folder. Add a variant by adding an entry; there's no other file to edit.

The build pipeline

npm run build runs three steps, in order:

  1. generate-variants.mjs — for each component, renders the macro with each variant's prop set and writes <filename>.html. (These are the GENERATED files you never edit.)
  2. generate-stories.mjs — concatenates global.css + every component's component.css into the version's style.css, and writes one Storybook story per variant.
  3. build-storybooks.mjs — builds a Storybook once per design-system version.

During local development the dev server also recompiles /ds/<version>/style.css on every request, so edits to a component.css show up live without a full rebuild.

Why auto-generate

The design system is generated from the content itself — the authored CSS, the macro, and the variant prop sets. Because the storybook and the rendered <variant>.html pages are produced from those same three files, they can never drift from the source: there's no separate, hand-maintained component catalogue to keep in sync. One source of truth, regenerated on every build.

Just as important, authoring needs no framework or build tooling — only CSS, Nunjucks, and JSON. That keeps the barrier to authoring low and the whole design system portable: a version is just a folder you can copy, re-theme, and freeze.

Don't

  • Edit a generated <variant>.html. It's overwritten on every build — edit macro.njk or variants.json instead.
  • Edit style.css directly. It's generated from global.css + the component CSS.
  • Add story-scaffolding CSS (e.g. .story-grid, .frame-demo) to a component.css. That's storybook layout, not the component.
  • Reach across versions. A component in one version must never reference paths inside another. Each version is a self-contained snapshot.

On this page