Skip to content
Blog

How to make Claude Code follow your design system

By Attuna · · Updated

Claude Code follows a design system reliably when three things are true: it can find the components and tokens, it has short rules saying when to use them, and something checks the result. Instructions alone are advisory. The Claude Code memory docs say it plainly: Claude treats CLAUDE.md “as context, not enforced configuration”. So the reliable setup combines guidance with checks.

Why agents drift from a design system

Visual drift in AI-written UI usually has one of four causes:

  • It can’t find the component, so it builds a new button or modal that looks almost the same.
  • Tokens are optional in practice. If the codebase already has hard-coded hex values, the model will treat that as acceptable.
  • Rules are vague. “Follow the design system” isn’t something the model can check itself against.
  • Nothing catches it. A page that compiles looks done, even when it uses 13px text where the scale has 12 and 14.

1. Make the system easy to find

Before any rules, check that the system is discoverable. Components should live in one place with predictable names. Tokens should be defined once, as CSS custom properties or a theme file, with semantic names like --text-muted rather than --grey-500. If you use Tailwind, map tokens into the theme so utilities resolve to them.

Then ask Claude Code to describe the system back to you. It’s a quick way to find gaps:

Prompt
Read components/ui and app/globals.css. Summarise our design system:
the components available and their variants, the colour, spacing,
radius and type tokens, and any places in app/ that hard-code values
instead of using them. Don't change anything yet.

2. Write rules Claude can verify

Put the rules in CLAUDE.md, and keep them concrete. The docs recommend instructions “concrete enough to verify” and files under about 200 lines, because longer files reduce adherence.

CLAUDE.md
## Design system
- Components: use components/ui. Search it before creating any
  button, input, select, dialog, menu, table or badge.
- New components need my approval. Propose them; don't create them.
- Colour: only semantic tokens from app/globals.css. No hex, rgb or
  Tailwind palette classes such as bg-zinc-800 in app/.
- Spacing: 4, 8, 12, 16, 24, 32, 48, 64. Nothing else.
- Type: text-xs (12), text-sm (14), text-base (16), text-xl (20),
  text-2xl (24). Body copy is text-sm.
- Radius: rounded-md for controls, rounded-xl for surfaces.
- Icons: lucide-react at 16px inline, 20px in buttons.

If a rule only matters for one part of the codebase, use a path-scoped rule in .claude/rules/. It loads only when Claude reads or edits matching files, which keeps the main file short:

.claude/rules/marketing.md
---
paths:
  - "app/(marketing)/**/*.tsx"
---

# Marketing pages
- Use the display type scale (text-4xl and above) for headings.
- Sections are full-bleed with the Container component inside.

3. Enforce what must never happen

Some rules are too important to leave to judgement, such as raw colour values or importing a second icon library. Turn those into checks the project already runs: an ESLint rule, a stylelint rule or a small script in CI. Claude Code reads failing output and fixes it, so a lint error becomes part of the loop rather than something you catch in review.

For checks that must run every time Claude edits a file, Claude Code hooks are deterministic, unlike instructions. A hook that runs your linter after each edit means drift is reported immediately.

Prompt
Write a hook that runs "pnpm lint --quiet" on any .tsx file you edit
and shows me the errors.

4. Give Claude a reference implementation

The fastest way to show how the system should be used is a page that already uses it well. Point to it directly: build the team page following the patterns in @app/settings/members/page.tsx. The best practices guide recommends referencing existing patterns in exactly this way.

5. Review for drift

Even with rules and lint, review the visual result. Ask Claude to screenshot the new page beside an existing one and look for differences in spacing, type and component use. Then run a separate pass on the diff:

Prompt
Review this diff against the design system rules in CLAUDE.md.
List any new components that duplicate ones in components/ui,
any values outside the spacing or type scale, and any colours that
aren't semantic tokens. Report only real violations.

If the result is close but off, the guide to improving AI-generated UI without a rebuild covers targeted fixes.

What a design system doesn’t cover

A design system tells an agent which pieces to use and what values are allowed. It doesn’t say what a new screen should feel like, which layout fits the content, or which of five valid compositions is right. That’s creative direction, and it comes from references and principles. We explain the split in design references vs design systems, and the brief-writing side in how to make Claude Code build better UI.

At Attuna we’re focused on the direction side. Each project holds a brief, a creative direction, project rules and references, and agents read them over MCP alongside the design system in your codebase. For the rules themselves, see CLAUDE.md for UI design. For the token layer, see design tokens for AI coding agents.

Sources