Design Systems

DESIGN.md for Tailwind CSS

Use DESIGN.md to stop Tailwind-generated UI from collapsing into generic utility soup.

6 min read

Why Tailwind alone produces inconsistent AI output

Tailwind's utility-first approach makes it fast to implement any visual style — which means an AI agent can generate visually inconsistent code just as quickly as consistent code. Without DESIGN.md, the agent picks from the full Tailwind utility set based on training distribution, not product decisions. You get p-4 in one card and p-5 in another, text-gray-700 on one label and text-slate-600 on another, rounded-md in one button and rounded-lg in the next. The inconsistency is not random — it reflects the most common Tailwind patterns seen in training data, which average out to no specific product's design choices. The problem compounds across sessions: each new component is internally consistent but inconsistent with components built in previous sessions, because the agent has no stable reference for which Tailwind classes your product prefers. By the time ten screens have been implemented, the codebase contains three or four competing interpretations of the same visual intent. Refactoring them into a consistent system requires more effort than writing a DESIGN.md would have taken at the start of the project.

Translating your Tailwind config into DESIGN.md

The tailwind.config.ts extend section is the closest thing Tailwind has to a token system. Custom colors, custom spacing steps, custom font families, and custom border radius values defined there represent the brand vocabulary. DESIGN.md takes that vocabulary and adds semantic meaning. Instead of documenting a token name, it documents a usage rule: "Use bg-brand-500 for primary action backgrounds, text-brand-600 for interactive links, and border-brand-400 for focus rings. Never use bg-brand-300 or lighter for interactive elements — the contrast is insufficient." For spacing: "The product spacing scale uses Tailwind steps 3 (12px), 4 (16px), 6 (24px), 8 (32px), and 12 (48px). Do not introduce intermediate values like p-5 or gap-7 — they break the visual rhythm." If the Tailwind config has not been extended yet, DESIGN.md can specify stock Tailwind preferences directly: "All borders use border-slate-200. Hover backgrounds use hover:bg-slate-50. Do not use gray-* and slate-* interchangeably — pick one neutral family and stay consistent throughout." These rules are trivial to state but eliminate a major source of visual drift in AI-generated code.

The class preference problem

Tailwind offers too many valid ways to express the same visual intent, and AI agents pick among them inconsistently. Text at 14px can be text-sm. Hover states can be hover:bg-gray-100, hover:bg-gray-50, or hover:opacity-90. Dividers can be border-gray-200, border-neutral-200, or border-slate-200 — visually similar in most color profiles but semantically inconsistent and harder to update globally. Without DESIGN.md specifying the canonical choice, an agent makes independent decisions each time, accumulating drift that becomes expensive to normalize later. DESIGN.md's role in a Tailwind project is to canonicalize these choices with explicit class names, not just semantic intent. "Interactive hover backgrounds use hover:bg-muted. Never use hover:opacity for background changes." "Borders use border-border throughout. Dividers use divide-y divide-border." "Focus rings use focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2." Specifying the exact class names is what makes the rule actionable. An agent implementing "use a subtle hover state" is making a judgment call that will differ across sessions; an agent implementing "hover:bg-muted" is matching an exact string.

Page-level layout rules for Tailwind projects

Layout is where Tailwind inconsistency is most visible and hardest to repair after the fact. When different pages use different max-width containers, different section spacing, different sidebar widths, and different responsive breakpoint logic, the product feels structurally incoherent even when individual components look correct in isolation. DESIGN.md should document the main content container class string (e.g., "max-w-6xl mx-auto px-4 sm:px-6 lg:px-8"), the standard vertical spacing between major page sections (e.g., "space-y-8 between top-level sections, space-y-4 between grouped cards"), the sidebar width if the product uses a nav layout (e.g., "w-64 fixed at desktop, hidden on mobile with a slide-in drawer"), and how responsive breakpoints are used in the product. For a B2B tool never used on mobile, documenting "responsive breakpoints below md are not used — do not add sm: variants" saves agents from adding mobile styles that will never apply. For a mobile-first consumer product, documenting the baseline mobile layout before tablet and desktop variants ensures agents start from the right default. Layout rules are the most commonly skipped section in a first DESIGN.md draft and the most valuable once they exist.

Anti-patterns and the maintenance loop

The anti-patterns section for a Tailwind project captures the utility combinations that agents reach for automatically but that are wrong for this specific product. Common anti-patterns to document: "Do not use arbitrary values like w-[723px] or pt-[18px] — if a spacing step is missing from the scale, add it to the config." "Do not use bg-gradient-to-r or any gradient background on operational UI surfaces." "Do not mix Tailwind with CSS modules in the same component." "Do not add excessive interactive utility stacks — hover and focus-visible states together should use at most two modifier utilities." "Do not use text-pretty or leading-relaxed outside of documentation or prose content pages." Each anti-pattern was born from a real mistake, either observed in AI output or learned from a past inconsistency. Maintaining DESIGN.md as a living document means updating the anti-patterns section after every session where the agent produced something that needed correction. Over time the file becomes a Tailwind style guide tested against actual AI output in this specific codebase — not a generic best-practices document, but a record of exactly what this agent needs to be told to produce consistent work.

Use DESIGN.md with a real product reference

Browse curated DESIGN.md examples from product teams, design systems, developer tools, SaaS dashboards, and AI-native apps. Use them as references before your agent builds the next screen.

Related guides