How to make AI agents follow your design system

Give an AI coding agent a small design-system map, enforce tokens and components, expose real states, and verify the system on a second route.

You will give an AI coding agent a small, enforceable map of your design system, then prove that it uses the intended tokens, components, states, and screen patterns on two routes.

This workflow was tested on August 10, 2026 with Codex CLI 0.145.0 and Node.js 22.14.0. The test fixture started with a route that used a raw color, an unapproved pill radius, a duplicated button, and only a populated state. The verifier reported all six failures. After the route reused the shared button and exposed loading, empty, error, and populated states, the verifier passed on both the original route and a second settings route.

The file names in your project may differ. Keep the workflow and replace the example paths.

Prerequisites

You need:

  • a frontend repository that runs locally
  • a real token source
  • shared component source code
  • at least one complete product screen that uses the system correctly
  • a way to reach loading, empty, error, and populated states
  • the project's normal lint, test, and build commands
  • a coding agent that can read the repository and run those commands

Do not start by exporting the whole design library into the prompt. First identify the smallest sources that govern the route you are changing.

1. Choose one workflow to test

Select a route with enough behavior to expose system mistakes.

This tested example used a deployment history workflow:

text
Route: /deployments
User: A developer investigating a failed production deployment
Outcome: Find the failure, inspect its details, and redeploy safely
Primary action: Open deployment
Secondary action: Redeploy failed deployment
Required states:
- Loading
- Empty history
- Populated history
- No filter results
- Request error
- Details open
- Redeploy confirmation
- Redeploy pending
- Redeploy success
- Redeploy error
- Permission denied
Widths: 1440px, 768px, 390px

Avoid a decorative landing-page section for the first test. A real workflow makes component reuse, state coverage, density, and action hierarchy easier to evaluate.

2. Find the actual sources of truth

List the files that own each part of the system.

text
Tokens: src/styles/tokens.css
Button: src/components/Button.tsx
Field: src/components/Field.tsx
Status: src/components/Status.tsx
Page frame: src/layouts/AppFrame.tsx
Complete reference: src/routes/activity/ActivityPage.tsx
State fixtures: src/fixtures/activity.ts
Visual checks: npm run test:visual
Project checks: npm run lint && npm test && npm run build

Open the files and confirm they are current. Do not point the agent at a barrel export when it needs the component implementation, states, and usage examples.

If the code and design file disagree, choose the owner before asking the agent to build. The agent cannot enforce a system whose sources conflict.

3. Write a small agent map

Create docs/design-system-agent-map.md:

md
# Design system map

## Foundations

- Use color, spacing, type, radius, and elevation tokens from
  `src/styles/tokens.css`.
- Do not add raw colors, pixel radii, or one-off shadows in route code.

## Components

- Use `src/components/Button.tsx` for product actions.
- Use `src/components/Field.tsx` for labeled inputs and validation.
- Use `src/components/Status.tsx` for semantic status.
- Inspect every supported variant and state before adding a new one.

## Composition

- Use `src/layouts/AppFrame.tsx` for authenticated routes.
- Use `src/routes/activity/ActivityPage.tsx` as the density and hierarchy
  reference for operational lists.
- Copy relationships, not product content.

## States

- Make loading, empty, no-results, error, populated, pending, and permission
  states reachable through `src/fixtures`.

## Verification

- Run `npm run check:design-system`.
- Review the route at 1440px, 768px, and 390px.
- Test the same system decisions on a second route.

This map is a router. It tells the agent where to look and what each source owns. Keep detailed component documentation in the component source instead of copying it into this file.

4. Load the map through repository instructions

For Codex and other agents that load AGENTS.md, add a short UI section:

md
## Frontend UI

- Read `docs/design-system-agent-map.md` before changing product UI.
- Reuse existing tokens, components, layouts, and state fixtures.
- Do not add a component or token until you have traced the owning source.
- Make every required product state reachable.
- Run `npm run check:design-system` and the normal project checks.
- Review the changed route at 1440px, 768px, and 390px.

Codex reads repository AGENTS.md guidance automatically and applies more specific instruction files closer to the working directory. If your coding agent uses another repository-instruction file, put the same scoped rules in that supported location.

Keep the task contract in the task prompt. Keep stable repository rules in the instruction file.

5. Add checks for rules that code can prove

Do not rely on the agent to remember every token and component rule. Turn mechanical rules into checks.

This minimal Node.js verifier matches the tested fixture:

js
import { readFile } from "node:fs/promises";

const routes = ["deployments.html", "settings.html"];
const requiredStates = ["loading", "empty", "error", "populated"];
const failures = [];

for (const file of routes) {
  const source = await readFile(new URL(`routes/${file}`, import.meta.url), "utf8");

  if (/#[0-9a-f]{3,8}/i.test(source)) {
    failures.push(`${file} contains a raw color`);
  }
  if (/999px/.test(source)) {
    failures.push(`${file} contains an unapproved radius`);
  }
  if (!source.includes("components/Button.html")) {
    failures.push(`${file} does not reference the shared Button`);
  }

  for (const state of requiredStates) {
    if (!source.includes(`data-state=\"${state}\"`)) {
      failures.push(`${file} is missing ${state} state`);
    }
  }
}

if (failures.length) {
  console.error(failures.join("\n"));
  process.exit(1);
}

console.log("design-system verification passed");

Run it:

bash
node verify.mjs

The first tested run returned:

text
route contains a raw color
route contains an unapproved radius
route does not reference the shared Button
missing loading state
missing empty state
missing error state

After correction, the same command returned:

text
design-system verification passed

Adapt the check to your stack. Useful rules include banned raw values, restricted imports, component variants, accessibility checks, duplicate components, and fixture coverage.

Code checks cannot decide whether the hierarchy or composition is good. Keep visual review as a separate step.

6. Give the agent focused context

Start the task with the contract and the map:

text
Implement the deployment history workflow described below.

Read:
- docs/design-system-agent-map.md
- src/styles/tokens.css
- src/components/Button.tsx
- src/components/Status.tsx
- src/layouts/AppFrame.tsx
- src/routes/activity/ActivityPage.tsx
- src/fixtures/activity.ts

Before editing:
1. Map each required element to an existing token, component, layout, or
   complete-screen pattern.
2. List any requirement the system does not currently support.
3. Do not create fallback UI until the gap is confirmed.

Done when:
- every required state is reachable
- existing components and tokens are reused
- the route works at 1440px, 768px, and 390px
- design-system and project checks pass
- the same system decisions work on a second route

Focused context reduces accidental invention. It also makes omissions visible before code is written.

7. Ask for a mapping before implementation

The agent should return a short plan such as:

RequirementExisting sourcePlanned use
Page frameAppFrame.tsxPreserve navigation and content rail
Primary actionButton.tsx primary variantRedeploy confirmation
Deployment statusStatus.tsxSuccess, pending, and failed states
List densityActivityPage.tsxRow rhythm and metadata grouping
Empty and error statesNo matching componentReuse page spacing and propose local content

Review every row marked as missing. Decide whether it is a real system gap, a task-specific composition, or a source the agent failed to find.

8. Build behavior before visual polish

Ask the agent to work in three passes:

  1. Build the page frame, data relationships, and action hierarchy.
  2. Make all states and permissions reachable.
  3. Apply tokens, components, responsive behavior, and visual correction.

Run the design-system check after each pass. Early failures are easier to fix before one-off styles spread across the route.

9. Review the rendered route

Inspect the running interface at the target widths.

Check:

  • information priority
  • density and whitespace
  • action hierarchy
  • component variants
  • long and missing content
  • loading, empty, error, pending, and permission states
  • focus, disabled, and destructive behavior
  • whether responsive changes preserve the workflow

Record concrete differences. "Make it cleaner" gives the agent no stable target. "The failed status loses its label at 390px" names a state, width, and failure.

10. Test the system on a second route

Apply the same map and checks to another route with a different composition.

The tested fixture added a settings route. It reused the shared button and exposed the same four baseline states. The verifier passed across both routes.

A second route reveals whether the agent learned reusable rules or copied one screen. Check that it does not introduce a new button, radius, spacing scale, page width, or state pattern without a documented reason.

Troubleshooting

The agent keeps creating new components

The map may point to component names without showing variants or usage. Link the implementation, state examples, and one complete screen. Add a check for restricted imports or duplicate component names.

The result uses tokens but still looks wrong

Tokens can preserve values while composition remains generic. Add complete-screen references and state the relationship you want to transfer, such as density, hierarchy, or action placement.

The agent copies the reference product

State which relationships are reusable and which product content, brand, and workflow must remain original. Give the target product contract before the visual reference.

The first route passes but the second one drifts

The rule probably lives only in the first route. Move repeated behavior into a shared component, layout, fixture, or check, then rerun both routes.

The instruction file becomes too large

Keep stable routing rules in AGENTS.md. Move detailed system guidance into the design-system map and owning component files. Remove duplicated examples.

Verify the result

Finish only when:

  • the agent can name the source for every reused system decision
  • raw values and duplicate components are rejected by checks
  • required product states are reachable
  • the route was reviewed at all target widths
  • project checks pass
  • a second route follows the same system without copied local styles

For the readiness diagnosis behind this workflow, read Is your design system ready for AI coding agents?. For a broader build workflow, use How to get good UI from AI.

Don’t ship another forgettable app.

Give your agent structured interface references from products that set the standard, then turn them into something unmistakably yours.

Explore kits
Complete interface systemsCode-level referencesProven product decisionsFrom reference to production