Design Systems at Scale
Using Claude Code to build, extend, and maintain component libraries and design systems
You have a CLAUDE.md with design tokens and conventions. You can generate individual components. This chapter scales up from one-off component work to system-level thinking — auditing entire libraries, generating variants in batches, managing tokens across themes, and keeping documentation from going stale. Design systems are systematic by nature. Claude Code excels at systematic work. That alignment is the entire thesis of this chapter.
Think of Claude Code as a design system assistant that never tires of generating variants, updating tokens, and writing documentation. You define the rules. It executes at scale. That is the mental model for this entire chapter.
6.1 Why Design Systems + AI
Why Design Systems and AI Are a Natural Pair
Design systems are systematic by definition. AI tools are systematic by nature. That overlap is not coincidental — it is the reason Claude Code is unusually effective at design system work.
Most design system maintenance is not creative work. It is extending existing patterns, auditing for consistency, generating variants from a base component, and keeping documentation in sync with code. These tasks are repetitive and rule-based — exactly the kind of work where AI assistance pays off.
Four properties make design systems a natural fit for Claude Code:
| Property | Why It Matters | What Claude Can Do |
|---|---|---|
| Code-first artifacts | Modern design systems live in code repositories, not Figma files alone | Read, edit, and validate code natively |
| Maintenance bottleneck | Creating a system is glamorous; maintaining it is tedious | Handle repetitive extension and audit tasks at scale |
| Cross-platform drift | Components diverge across React, React Native, and native platforms | Compare implementations and flag inconsistencies |
| Documentation staleness | Docs drift from code the moment someone skips an update | Regenerate documentation from source code automatically |
When AI helps less
Claude Code is less useful for the creative decisions in design system work: choosing a type scale, defining a color palette, or establishing interaction patterns. Those require taste and context. Where it shines is the mechanical execution after the creative decisions are made — generating the 47 files that implement those decisions consistently.
6.2 Auditing an Existing System
Auditing an Existing Design System
Before extending a design system, audit what is there. Claude Code can perform a comprehensive audit in a single session using the explore-plan-implement pattern from Anthropic's best practices.
Think of auditing like running a spell check on your design system. You are not rewriting anything yet — you are finding every inconsistency, every hardcoded value, every missing piece. Claude Code reads every file, compares against your conventions, and produces a report.
Step 1: Explore in plan mode
Start with plan mode so Claude reads without writing anything. This keeps the audit read-only.
claude --permission-mode plan
Read the entire design system in @src/components, @src/tokens,
and @src/styles. Audit for:
1. Components missing from the design system but used in the app
2. Hardcoded colors, spacing, or typography values that should use tokens
3. Inconsistent prop naming across similar components
4. Accessibility issues (missing aria labels, keyboard navigation)
5. Components that are exported but unused anywhere in the codebase
Step 2: Generate the report
Create a prioritized audit report with:
- Category (consistency, accessibility, coverage, tokens)
- Severity (critical, high, medium, low)
- Affected files
- Suggested fix approach
Step 3: Fix what matters
Fix all critical and high severity issues from the audit.
Run the test suite after each fix.
That last instruction is important. Design system changes can be verified — linters, type checks, visual regression tests all catch problems. Anthropic's best practices recommend giving Claude a way to verify its work. Design systems make this easy because the verification tooling already exists.
Parallel audits with subagents
For large design systems, a single audit can fill the context window before finishing. The solution is subagents — separate Claude sessions that run in parallel, each investigating a different aspect.
Research the component library using separate subagents:
- Subagent 1: Find all components missing JSDoc or TypeScript docs
- Subagent 2: Find all hardcoded color values that bypass tokens
- Subagent 3: Check accessibility across all interactive components
- Subagent 4: Find components exported but never imported elsewhere
Report a consolidated summary with file references.
Each subagent runs in its own context window and returns only findings. The main session gets a consolidated report without having read every file itself.
My Take
The fan-out pattern — having Claude operate on every file that matches a pattern — is the most powerful technique in this chapter. It turns what would be hours of tedious find-and-replace into a single prompt. The parallel audit pattern is a specific instance of this: instead of one slow pass through every file, you get four simultaneous passes each focused on one concern.
Caution: Always test on a small subset first, review the output, then run at scale. A bad audit prompt applied to 200 files produces 200 bad reports.
6.3 Generating Component Variants
Generating Component Variants
Generating variants is the most straightforward design system task for Claude Code. You point it at a base component, describe the variants you need, and it produces files that follow the same conventions.
Think of this like creating component variants in Figma. You define a base component, then create variants for different states, sizes, and colors. The difference is that Claude Code generates working code with types, styles, stories, and tests — not visual frames.
Generating button variants
Start by pointing Claude Code at your existing Button component and asking for new variants:
Read @src/components/Button/Button.tsx and
@src/components/Button/Button.stories.tsx.
The existing Button supports 'primary', 'secondary', and 'ghost' variants.
Generate the following new variants following the exact same patterns:
1. 'destructive' — red background, white text, for dangerous actions
2. 'outline' — transparent background, colored border, colored text
3. 'link' — no background or border, underlined text, for inline actions
For each variant:
- Add the variant to the TypeScript union type
- Add the style mapping in the styled component
- Add a Storybook story
- Add a Jest test for rendering and interaction
The critical instruction is "following the exact same patterns." Claude Code will match whatever conventions exist in the base component — prop naming, style structure, file organization. This is where your CLAUDE.md conventions from Chapter 5 pay off. If you defined how components are structured, Claude follows that structure.
Batch variant generation
When you need variants across many components, use the fan-out pattern to process them in parallel:
Cap the blast radius
Run the pattern on two or three components first, review the diffs, then increase the batch size. Add a concurrency cap, budget note, and rate-limit handling before running dozens of claude -p sessions. Parallel generation is useful only when the results are still reviewable.
for dir in src/components/*/; do
component=$(basename "$dir")
if [ ! -f "${dir}${component}.stories.tsx" ]; then
claude -p "Read src/components/$component/$component.tsx. \
Generate a Storybook story file following the pattern in \
src/components/Button/Button.stories.tsx. \
Write to src/components/$component/$component.stories.tsx. \
Return OK or FAIL." \
--allowedTools "Read,Write,Glob,Grep" &
fi
done
wait
echo "All stories generated"
This script finds every component that lacks a Storybook story, then generates one for each in parallel. Each invocation runs in its own context, reads the base Button story for reference, and produces a matching file.
Warning
Generating many variants without reviewing each one risks subtle inconsistencies — a few pixels off on padding, a color shifted slightly, a hover state that behaves differently. Generate in batches of 5-10 components. Review each batch. Then proceed. Use visual testing (covered in Section 6.6) to catch drift.
6.4 Token Management and Themes
Token Management and Themes
Design tokens are the atomic values of your design system — colors, spacing, typography, shadows. Claude Code can audit token usage, generate theme variations, and convert between formats.
Think of tokens like the variables panel in Figma. Every color, spacing value, and font size that appears in your design system should trace back to a token. In practice, hardcoded values creep in. Claude Code can find them.
Auditing token usage
Read @src/tokens/colors.ts, @src/tokens/spacing.ts,
and @src/tokens/typography.ts.
Then search the entire codebase for:
1. Hardcoded hex/rgba colors not in the token set
2. Hardcoded pixel values for spacing that should use spacing tokens
3. Hardcoded font-size values that should use typography tokens
4. Any file in src/ that imports tokens but overrides them with raw values
Generate a report grouped by file, with suggested token replacements
for each hardcoded value.
Generating a dark theme from tokens
Once your light theme tokens are defined, generating a dark theme is a structured transformation — the kind of task Claude Code handles well:
Read @src/tokens/colors.ts which defines our light theme color tokens.
Generate a dark theme by:
1. Creating semantic color mappings (background -> dark background,
surface -> dark surface)
2. Ensuring WCAG AA contrast ratios for all text/background combinations
3. Following the exact same TypeScript structure as the light theme
4. Writing the result to src/tokens/colors-dark.ts
Then create a ThemeProvider component that:
- Accepts 'light' | 'dark' | 'system' as a theme prop
- Switches CSS custom properties at the :root level
- Persists the choice to localStorage
- Respects prefers-color-scheme media query for 'system' mode
Converting tokens to Tailwind config
If your project uses Tailwind, Claude Code can bridge between your token definitions and the Tailwind configuration:
Read @src/tokens/colors.ts, @src/tokens/spacing.ts,
and @src/tokens/typography.ts.
These contain our design tokens as TypeScript objects.
Generate a tailwind.config.ts that:
1. Extends the Tailwind theme with our custom colors, spacing, and typography
2. Maps each token to the correct Tailwind config path
3. Preserves any existing Tailwind config for plugins and content paths
4. Includes comments linking back to the source token file for each value
Enforcing token usage with hooks
Audits find problems after they happen. Hooks prevent them from happening in the first place. You can set up a PreToolUse hook that blocks file writes containing hardcoded color or spacing values:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"if": "Edit(src/components/**)",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/check-hardcoded-values.sh",
"args": []
}
]
}
]
}
}
#!/bin/bash
# .claude/hooks/check-hardcoded-values.sh
INPUT=$(cat)
CONTENT=$(echo "$INPUT" | jq -r '.tool_input.newString // .tool_input.content // empty')
if echo "$CONTENT" | grep -qE '#[0-9a-fA-F]{3,8}[^0-9a-fA-F]'; then
echo "Blocked: Hardcoded hex color detected. Use a design token from src/tokens/colors.ts" >&2
exit 2
fi
if echo "$CONTENT" | grep -qE '(margin|padding|gap):\s*[0-9]+px'; then
echo "Blocked: Hardcoded pixel spacing detected. Use a spacing token from src/tokens/spacing.ts" >&2
exit 2
fi
exit 0
Exit code 2 blocks the tool call. The write never happens. This is deterministic enforcement — unlike CLAUDE.md instructions, which are advisory, hooks cannot be ignored. Think of it like an auto-layout constraint in Figma: you set it once, and it enforces consistency from that point forward.
6.5 Cross-Platform Consistency
Cross-Platform Consistency
Design systems that span web, mobile, and native platforms face a constant drift problem. Claude Code can compare implementations across platforms and flag where they diverge.
A button component might have 10 variants on web but only 6 on mobile. Spacing tokens might be defined differently across platforms. Color values may diverge through copy-paste. These inconsistencies accumulate slowly and are expensive to find manually.
Parity check across platforms
Compare the design system implementations across platforms:
- Web components: @src/web/components/
- React Native components: @src/native/components/
- Design tokens (Figma-exported): @tokens/
For each component that exists in the web implementation:
1. Check if an equivalent exists in the native implementation
2. Compare the props/variants available in each
3. Flag any prop or variant that exists on one platform but not the other
4. Check that both platforms use the same token values for colors and spacing
Generate a parity report with:
- Component name
- Platform availability (web / native / both)
- Missing props or variants per platform
- Token value mismatches
Cross-platform token diff
For a focused check on whether token values have diverged across platform implementations:
claude -p "Compare the color token values in:
1. src/web/tokens/colors.ts
2. src/native/tokens/colors.ts
3. tokens/colors.json (Figma export)
List any values that differ across the three sources.
Return a JSON object with token name, web value, native value,
and figma value." \
--output-format json > token-diff.json
Using agent teams for large-scale checks
When the parity check spans a large system, delegate to agent teams running in parallel:
I need to audit our design system across three platforms in parallel.
Use an agent team:
- Agent 1 (Web): Audit all React components in src/web/components/
for prop completeness and token usage
- Agent 2 (Native): Audit all React Native components in
src/native/components/ for the same
- Agent 3 (Compare): After Agent 1 and 2 complete, compare their
findings and generate a parity report
Each agent should use the Explore subagent for investigation.
Agent teams coordinate multiple Claude sessions. Each agent works independently, then Agent 3 synthesizes the results. For a design system with 50+ components, this pattern finishes in minutes instead of the hours a manual comparison would take.
6.6 Visual Regression and Accessibility Gates
Visual Regression and Accessibility Gates
A design system is not done when the code compiles. It is done when the rendered components match the intended system across states, breakpoints, and accessibility constraints.
Add a verification pass before documentation. Ask Claude Code to open Storybook or your component preview, capture screenshots for mobile, tablet, and desktop, run automated accessibility checks, and compare the output against the reference design or previous baseline.
Run design-system visual QA for Button, Card, Modal, and Tabs:
1. Open Storybook.
2. Capture default, hover, focus, disabled, and error states.
3. Check keyboard focus order and visible focus rings.
4. Run axe or the project's accessibility test command.
5. Compare screenshots against the previous baseline.
6. Report only actionable visual or accessibility drift.
Automated checks do not certify legal accessibility compliance, but they catch common failures: missing labels, broken focus order, contrast issues, responsive overflow, and component states that no longer match the design system.
6.7 Documenting Your System
Documenting Your Design System
Documentation is the task everyone skips and everyone needs. Claude Code can generate and maintain component documentation, prop tables, usage guidelines, and migration guides directly from source code.
The reason documentation stays stale is that it requires a human to read code, extract information, and write prose — every time a component changes. Claude Code does this in seconds. Not perfectly, but well enough that a human review pass is faster than writing from scratch.
Component reference documentation
For each component in @src/components:
1. Extract the TypeScript interface and generate a props table
2. Read the Storybook stories and extract usage examples
3. Read the test file and infer behavior from test descriptions
4. Generate a markdown doc with: description, import statement,
props table, variants, examples, accessibility notes
5. Write to docs/components/[Name].md
Follow the template in @docs/templates/component-doc-template.md
Creating a reusable documentation skill
For documentation you regenerate frequently, create a skill that wraps the workflow:
---
name: document-component
description: Generate or update documentation for a design system component
argument-hint: [component-name]
---
Generate documentation for the $ARGUMENTS component.
1. Read the component source at src/components/$ARGUMENTS/$ARGUMENTS.tsx
2. Read the test file at src/components/$ARGUMENTS/$ARGUMENTS.test.tsx
3. Read the Storybook stories at src/components/$ARGUMENTS/$ARGUMENTS.stories.tsx
4. Extract the TypeScript props interface
5. Generate documentation following the template at
docs/templates/component-doc-template.md
6. Write the result to docs/components/$ARGUMENTS.md
Invoke it with /document-component Button. The skill reads the component source, tests, and stories, then generates documentation following your template. If you update a component, run the skill again. The documentation stays in sync.
Migration guides
When you release a new version of your design system, Claude Code can generate migration guides from the git diff:
Compare the current version of the design system (in @src/) with
the previous version (run: git diff v2.0..v3.0 -- src/).
Generate a migration guide that:
1. Lists all breaking changes with before/after code examples
2. Lists deprecated components with recommended replacements
3. Lists renamed props with find/replace instructions
4. Provides a codemod script for automated migrations where possible
Scheduled documentation updates
For ongoing maintenance, schedule a routine that regenerates documentation weekly:
Schedule a routine that runs every Monday at 9am:
"Check if any component files in src/components/ have been modified
in the past week. For each modified component, regenerate its
documentation in docs/components/. Create a PR with the updates."
My Take
Documentation generation is the highest-value use of Claude Code for design systems. Not because it is the most technically impressive thing Claude can do, but because it is the task everyone skips and everyone needs. Documentation always falls behind. The component gets built on Tuesday, the doc gets written never. Claude Code can regenerate it from code in seconds. You still review it — but reviewing takes five minutes. Writing from scratch takes an hour.
Caution: Generated documentation needs review for accuracy, especially around edge cases, keyboard interaction patterns, and accessibility behavior that is not captured in TypeScript types.
Batch documentation generation
To generate documentation for every component at once, use the fan-out pattern:
ls -d src/components/*/ | sed 's|src/components/||;s|/||' > components.txt
for component in $(cat components.txt); do
claude -p "Read src/components/$component/$component.tsx and \
generate documentation following the pattern in \
docs/templates/component-doc-template.md. \
Write to docs/components/$component.md. Return OK or FAIL." \
--allowedTools "Read,Write,Glob,Grep" &
done
wait
Each component gets its own Claude session running in parallel. For a system with 40 components, this generates 40 documentation files in the time it would take to generate one sequentially.