The first time I asked Claude Code to "add a settings panel", it shipped something that worked perfectly and looked nothing like the rest of the app. Wrong radius, wrong grey, a shadow we do not use anywhere.
That is not a model problem. It is a context problem. Claude Code had the code, but nobody had told it what the product looks like.
Here is the good news: fixing this takes about two minutes.
What Claude Code already reads
Claude Code automatically loads a file called CLAUDE.md from your project root at the start of every session. Anthropic documents this as project memory, and it is the supported place to put standing instructions for a repo.
It also supports imports. A line starting with @ pulls another file into that memory. That is the hook we want, because it means your DESIGN.md stays a separate, portable file instead of being copy-pasted into a config.
The setup
Drop your DESIGN.md in the repository root, next to package.json.
Then create or edit CLAUDE.md in the same folder:
# Project memory
## Design system
The visual contract for this product lives in DESIGN.md.
@DESIGN.md
Rules:
- Read DESIGN.md before writing or editing any component, page, or style.
- Use only the color tokens, type scale, radius, and spacing values it defines.
- If a value you need is not in DESIGN.md, ask before inventing one.
- Never introduce a new shadow, gradient, or font family without approval.That is the whole configuration. No plugin, no MCP server, no build step.
Why the "ask before inventing" line matters
This part is easy to skip, and it is the line that does the most work.
Without it, an agent that cannot find a token will quietly pick something reasonable. Reasonable is the problem. You get a #3b82f6 blue in a product that uses #0061ff, and nobody catches it until design review.
With it, the model surfaces the gap instead of papering over it. In my experience that turns a silent drift problem into a short conversation.
Verify it actually loaded
Do not trust it, test it. Start a fresh session and ask:
What is the primary button background color in this project, and where did you find it?You want an answer with the exact hex value and a reference to DESIGN.md. If you get a generic answer, or a hedge, the import is not resolving. Check that the path in the @ line matches the real filename, including case.
A second useful check: ask for a small component and watch which values come back.
Build a disabled secondary button using only tokens from DESIGN.md.Common mistakes
- Putting DESIGN.md somewhere clever. Subfolders work, but then the import path has to match exactly. Root is simpler.
- Writing the design rules inside CLAUDE.md instead of importing. It works, but now your design system only exists in one tool. Keeping DESIGN.md separate means Cursor, Codex, and Copilot can read the same file.
- Making it too long. A design contract that runs 400 lines competes with the rest of your context. Tokens, geometry, and component rules are enough.
What this means for you
Once the import is in place, every new session starts with your design language already loaded. You stop repeating yourself, and the output stops drifting.
If you do not have a DESIGN.md yet, grab one from the library and edit it. Starting from a documented system beats starting from a blank file, and you can have Claude Code building on-brand UI in the next five minutes.