A good CLAUDE.md for UI work is short, specific and checkable. It tells Claude Code where your components and tokens live, which values are allowed, how pages are composed and how to verify a change, in lines that each prevent a real mistake. It doesn’t try to be a design system document. Anything long or only occasionally relevant goes in path-scoped rules or skills instead.
Below: what the file is, how to structure the design sections, a complete example for a React and Tailwind app, and the mistakes that make Claude ignore it.
What CLAUDE.md is, and what it isn’t
CLAUDE.md is a markdown file Claude Code loads at the start of every session. A project file lives at ./CLAUDE.md or ./.claude/CLAUDE.md and is shared through version control. The memory documentation is explicit that Claude treats it “as context, not enforced configuration”, and recommends keeping each file under about 200 lines, because longer files reduce adherence.
If your repository already has an AGENTS.md for other coding agents, Claude Code can read that instead. To keep one source for every tool, put the shared rules in AGENTS.md and import it from a short CLAUDE.md with @AGENTS.md.
What belongs in the UI section
The test from Anthropic’s best practices is useful for every line: “Would removing this cause Claude to make mistakes?” For frontend work, lines that pass that test usually cover:
- Where things live: the component folder, the token file, an exemplary page.
- Allowed values: type scale, spacing scale, radii, which colour tokens to use.
- Composition rules: one primary action, how sections are spaced, what never to nest.
- Required states: empty, loading, error.
- Accessibility floors: labels, focus, contrast, target size.
- Verification: the commands to run and the screenshot widths to check.
- Precedence: what wins when a reference or a skill disagrees with the system.
Leave out what Claude can read from the code (it will see that you use Tailwind), generic advice (“write clean code”), and anything that changes often.
A complete example for a React and Tailwind app
This is a starting point for a Next.js App Router project using Tailwind CSS v4 and a local component library. Replace the paths and values with yours. It’s about 60 lines, which leaves room for your build and test commands.
# Project
Next.js App Router, React, TypeScript, Tailwind CSS v4.
Run `pnpm dev` (port 3000). Before finishing a change, run
`pnpm typecheck && pnpm lint`.
# UI
## Where things live
- Components: src/components/ui. Search here before building any
button, input, select, dialog, menu, table, tabs or badge.
- Tokens: src/app/globals.css (@theme). This is the only place
colours, fonts, radii and shadows are defined.
- Reference page: src/app/(app)/settings/members/page.tsx shows how
a standard page is composed. Follow it for new pages.
## Values
- Colour: semantic utilities only (bg-background, text-foreground,
text-muted-foreground, border-border, bg-primary). Never hex,
rgb or palette classes like bg-zinc-800 in src/app or
src/components.
- Spacing: Tailwind spacing steps 1, 2, 3, 4, 6, 8, 12, 16.
No arbitrary values such as p-[18px].
- Type: text-xs, text-sm (body), text-base, text-lg, text-2xl
(page titles). Weights: 400 and 500; 600 for page titles only.
- Radius: rounded-md for controls, rounded-xl for surfaces.
- Icons: lucide-react, 16px inline, 20px in buttons.
## Composition
- One primary button per view. Secondary actions use the ghost
variant.
- Group with spacing and hairline borders, not nested cards.
- Page header: title, one-line description, actions on the right.
- Tables: right-align numbers, tabular-nums, 40px rows.
## States and accessibility
- Every list, table and async view has empty, loading and error
states.
- Every input has a visible label. Errors say what went wrong and
how to fix it.
- Keep visible focus styles. Don't remove outlines.
- Interactive targets are at least 24 by 24 CSS pixels.
## New components
- Propose new components before creating them. Explain why the
existing ones don't fit.
## Precedence
- This file and the tokens win over reference images, Figma
output and skill suggestions. If they conflict, follow this
file and tell me about the conflict.
## Verify UI changes
- Open the page in the browser and take screenshots at 1440 and
390 wide. Compare with the brief or reference, list differences,
fix them, and show the final screenshots.Move detail into path-scoped rules
Rules that only matter for some files don’t need to load every session. Files in .claude/rules/ with a paths field load only when Claude reads or edits a matching file:
---
paths:
- "src/app/(marketing)/**/*.tsx"
---
# Marketing pages
- Use the display sizes (text-4xl and up) for section headings.
- Sections are full width with the Container component inside.
- One idea per section; no more than two buttons in a hero.
- Images use next/image with explicit width, height and alt text.---
paths:
- "src/components/forms/**/*.tsx"
- "src/app/**/*form*.tsx"
---
# Forms
- Use the Field component for label, control, hint and error.
- Validate on submit, then on change for fields that have errored.
- Disable submit only while submitting, never as validation.CLAUDE.md, rules, skills, MCP or hooks?
The Extend Claude Code guide lays out where each kind of instruction belongs. For UI work:
- CLAUDE.md: always-true rules and commands for this codebase.
- .claude/rules/: rules for specific folders or file types.
- Skills: long design guides and repeatable workflows such as a UI review. See Claude Code skills for frontend design.
- MCP: context that lives outside the repository, such as Figma frames or a reference library. See MCP vs Agent Skills.
- Hooks and lint: anything that must hold every time, such as “no hex values in components”. The docs call hooks deterministic, unlike instructions.
Common mistakes
- Writing a design system essay. Long explanations dilute the rules that matter. Link to docs instead.
- Unverifiable rules. “Keep it consistent” can’t be checked. “Spacing steps 1, 2, 3, 4, 6, 8” can.
- Contradictions. The docs warn that Claude may pick arbitrarily between conflicting instructions. Review nested files and rules together.
- Stale paths. A rule pointing at a deleted folder teaches Claude to ignore the file. Update it when you move things.
- Relying on it for enforcement. Back the important rules with lint or hooks.
- Never checking it loaded. Run
/contextand look under Memory files.
How to tell if it’s working
Treat the file like code. When Claude gets a convention wrong twice, add or sharpen a line. When a rule never comes up, cut it. If Claude keeps ignoring a rule that’s present, the file may be too long or the rule too vague.
CLAUDE.md is the right home for a codebase’s rules. For how those rules fit a design system with drift checks and reviews, read how to make Claude Code follow your design system, and for the token layer underneath them, design tokens for AI coding agents.