The last pillar is the one teams postpone the longest. Godbolt's argument is simple: frontend code grew from one stylesheet and a few jQuery calls into a system of abstractions, dependencies and interfaces, yet the habit of keeping knowledge in people's heads stayed. Skipping documentation is technical debt like any other, and some of the most useful documentation is generated from the code rather than written by hand.
This part is also where the Red Hat story pays off. The case study in chapter 17 shows a style guide growing into a shared rendering engine and then into CMS automation, and it is the clearest account I know of how documentation tooling can end up shaping the architecture itself.
Chapters 15 to 17 in the book, plus the short conclusion in chapter 18.
Key ideas
Two kinds of documentation
The introduction to this part splits documentation into two families. Static documentation is prose you write, collected and published by a tool: Hologram pulls Markdown blocks out of comments in Sass or JS files and builds a browsable site; SassDoc reads annotated variables, functions and mixins and builds API docs for a Sass library. Code-driven documentation is produced by the system itself: a pattern library renders your real templates and styles, and a JSON schema documents the data each template expects while also validating it.
The distinction matters because the two fail differently. Static docs go stale when people forget to update them, so the book's answer is to keep them physically next to the code. Code-driven docs cannot go stale in the same way, but they only describe what the code does, not why or when to use it. A healthy system needs both.
| Kind | Book's tools | What it is good at | How it fails |
|---|---|---|---|
| Static | Hologram, SassDoc | Intent, guidelines, onboarding, API notes | Drifts from the code |
| Code-driven | Pattern Lab, JSON schema | Real rendering, every variant, data contracts | Shows what, not why |
Documentation next to the code, with a public surface
Chapter 15 walks through both static tools. The lasting lessons are not about their configuration. First, documentation that lives in the same file or folder as the code it describes gets reviewed in the same pull request. Second, SassDoc's distinction between public and private members is a design decision, not a formatting one: marking internals as private tells consumers which parts they may depend on, so you are free to refactor the rest. Third, automatically mapping dependencies (which mixin uses which function and variable) turns docs into a navigation tool.
In a TypeScript design system the same three lessons apply, with the type system doing much of the work. A story file sits next to the component, the props type is the public surface, and the docs page is generated from both:
import type { Meta, StoryObj } from "@storybook/react-vite";
import { PriceTag } from "./PriceTag";
const meta = {
title: "Commerce/PriceTag",
component: PriceTag,
tags: ["autodocs"],
args: { label: "Monthly plan", amount: "$12" },
argTypes: {
tone: {
control: "inline-radio",
options: ["default", "sale"],
description: "Use sale only when a discount is active.",
},
},
} satisfies Meta<typeof PriceTag>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {};
export const Sale: Story = {
args: { tone: "sale", amount: "$9" },
};
export const OnDarkSurface: Story = {
args: { tone: "sale" },
globals: { theme: "dark" },
};
Each exported story is one documented state, which is the code-driven half. The description explains when to use a variant, which is the static half. The theme global here assumes your Storybook setup defines one; the point is that every context the component supports gets its own story.
Atomic Design and pattern libraries
Chapter 16 introduces Brad Frost's Atomic Design: atoms (headings, inputs, images), molecules (a search form, a media block), organisms (a header, a comment thread), templates (page layouts) and pages (templates filled with realistic content). Pattern Lab turns those levels into a browsable site where each pattern is a template with its data, and larger patterns include smaller ones while switching the data context they pass down.
Two points from the walkthrough are worth keeping. The pattern library should share CSS and JS with the real site, so prototypes built there need no restyling when they reach the CMS. And abstracting even the smallest markup, such as all images rendering through one template, pays off when you later need to change every instance at once. Godbolt's broader claim is that building pages makes work harder over time, while building a system makes it easier. I think the strict five-level taxonomy matters less than the habit of composing from a shared inventory, and looser categories are fine if the team agrees on them.
The five stages of Red Hat's documentation
Chapter 17 tells how the system grew, and I find the sequence more instructive than any single tool:
Stage 1 Static style guide: docs blocks in each Sass partial, plus onboarding pages
Stage 2 Templates inside docs: one canonical template, included with different data
Stage 3 Library split from style guide: production and docs become equal consumers
Stage 4 Shared rendering engine: same templates in docs and CMS, validated by schemas
Stage 5 Generated editing UI: CMS fields created automatically from component schemas
Each stage was a response to pain in the previous one. Copying markup into docs went stale immediately, so they rendered docs from templates. Releasing the library every time someone reorganised the docs was noisy, so they split the repositories, and a side effect was that the style guide could only change markup through data, exactly like production. With one rendering engine, backend developers no longer matched markup by hand; they produced data that passed the schema. Finally the backend team built an importer that turned schemas into CMS entities, so a new pattern needed almost no backend work.
The quiet lesson is about constraint. Godbolt notes that once rendering started, the only lever anyone had was the data, with no room for one-off tweaks to markup or source order, and that this restriction is what made the system robust. He also notes that, unlike Pattern Lab, their layouts did not hardcode which components they contained; the data decided. In React terms that is a registry plus data-driven composition:
import type { ComponentProps, ComponentType } from "react";
import { PriceTag } from "./PriceTag";
import { Testimonial } from "./Testimonial";
const registry = {
priceTag: PriceTag,
testimonial: Testimonial,
} satisfies Record<string, ComponentType<any>>;
type Registry = typeof registry;
type Block = {
[Key in keyof Registry]: { type: Key; props: ComponentProps<Registry[Key]> };
}[keyof Registry];
export function Region({ blocks, columns }: { blocks: Block[]; columns: 2 | 3 | 4 }) {
return (
<div className="region" data-columns={columns}>
{blocks.map((block, index) => {
const Component = registry[block.type] as ComponentType<typeof block.props>;
return <Component key={index} {...block.props} />;
})}
</div>
);
}
The layout knows nothing about its children, the column count is a data attribute, and adding a block type means one registry entry. Validate the incoming blocks against schemas at the boundary and you have the 2026 version of Red Hat's design API.
Keep iterating
The conclusion is short: the team kept wondering why it had not built the final system from day one, and the answer is that each stage was only visible after the previous one. Expect to iterate, do not bet everything on one tool until it has proved itself repeatedly, and share what you learn.
Reading it in 2026
- Hologram and SassDoc. Hologram is a Ruby gem from a different era of tooling, and I would not start a new project on it. SassDoc is still relevant if you publish a Sass library, though fewer teams expose Sass APIs now that tokens and CSS custom properties carry most shared values.
- Pattern libraries. The role Pattern Lab played is usually filled by Storybook in React, Vue and Angular projects. Storybook 10, released in late 2025, went ESM-only, and its autodocs, controls and interaction tests cover much of what the book assembled from several tools.
- Design tokens are now the main way to document the visual language itself. The Design Tokens Community Group's 2025.10 format gives tools such as Style Dictionary, Tokens Studio and Terrazzo a shared JSON format, so colour, spacing and type scales can be documented and transformed from one source.
- Schemas and CMSs. JSON Schema (draft 2020-12) still works well as the data contract. Many headless CMSs and block editors model content as typed blocks, so Red Hat's stage 5 is now closer to a configuration task than a custom importer, though the specifics depend entirely on your CMS.
- Docs that test themselves. Stories now double as test targets for interaction and visual tests, which closes the loop between this pillar and the previous one.
Putting it to work
- Put docs next to code: a story file and a short usage note in every component folder, reviewed in the same pull request.
- Decide what is public. Export only the components, props and tokens you support; treat everything else as internal and say so.
- Write one story per variant and per context, so the docs page doubles as the list of visual test targets.
- Never copy markup into docs. Render examples from the real components with data.
- Generate token documentation from the token source instead of maintaining a separate colour page.
- If several apps consume your system, keep the library and the docs site as separate consumers of one published package.
Check yourself
What separates static from code-driven documentation? Static docs are prose people write and a tool collects; code-driven docs are produced by the running system, such as rendered patterns or schemas.
Why does marking members as private matter in SassDoc or a TypeScript library? It defines the public surface, so consumers know what they may depend on and maintainers can refactor the rest safely.
What problem pushed Red Hat from stage 1 to stage 2? Markup copied into documentation went out of date, so they rendered examples from one canonical template instead.
What was the side benefit of splitting the library from the style guide? The style guide and production became equal consumers that could only change output through data, which proved anything built in docs would work in production.
How does a component registry reproduce Red Hat's data-driven layouts? The layout renders whatever block types the data lists, so content composition changes without touching layout code.
Further reading
- Storybook 10 release notes: what changed with the ESM-only release.
- Storybook docs: Autodocs: generating documentation pages from stories and types.
- Atomic Design by Brad Frost: the author's own online book on the methodology used in chapter 16.
- Design Tokens Format Module 2025.10: the stable token format for documenting the visual language.