Design Systems

DESIGN.md for shadcn/ui

How to keep shadcn/ui fast without letting your product feel generic.

6 min read

Why shadcn/ui alone is not enough for AI agents

shadcn/ui gives AI agents a component vocabulary — Button, Card, Table, Dialog, Badge — but it does not give them usage rules. When an agent builds a new screen using shadcn primitives without a DESIGN.md file, it makes independent decisions for every visual detail: which Card variant to use, what Button size is appropriate, how much padding the page needs, whether the Table should feel compact or generous. Each decision defaults to the most common pattern seen during training, which is frequently the most generic one. The result is a product that looks like every other shadcn/ui app — not because the components are bad, but because the agent had no information about how your product differs from the default. shadcn/ui's strength is that components are highly customizable; the default look, applied uniformly by an agent with no context, produces a template feeling instead of a product identity. A DESIGN.md file tells the agent which defaults to override, how to combine primitives for your specific product surfaces, and which patterns to explicitly avoid. It is the layer between a capable component library and a product with a distinct visual character.

Documenting theme tokens and density

The first thing to document in a DESIGN.md for a shadcn/ui project is your globals.css token overrides. shadcn/ui uses CSS variables for its design tokens — --radius, --background, --foreground, --primary, --secondary, and so on. If your product sets --radius: 0.375rem instead of the shadcn default of 0.5rem, --primary to a custom HSL value, or --card to a slightly different background, record those exact values and their implications. An agent generating new components will use these tokens correctly when they are documented explicitly rather than inferred. The second thing to document is density preference. shadcn components default to a spacing profile appropriate for consumer apps; many SaaS and developer tools products use tighter density. If your product uses size="sm" on most Button instances, keeps TableCell padding compact, or reduces internal padding in Card components, specify those preferences clearly. An entry like "Default button size in data contexts is sm; use the default size only for standalone primary actions like form submissions" gives the agent a concrete decision rule instead of leaving it to interpret what "compact" means in practice.

Component decisions by surface

For each shadcn component used regularly in the product, a DESIGN.md entry should cover the default variant and size preference, when to deviate from those defaults, and the most important anti-pattern to avoid. For Button: "Primary actions use variant='default' at the default size. Secondary and inline actions use variant='ghost' at size='sm'. Destructive actions always use variant='destructive'. Never use variant='outline' as the sole action in a form — it reads as secondary even when it is the only option." For Dialog: "Confirmation dialogs use max-w-sm. Multi-field forms in dialogs use max-w-lg. Never use full-screen dialogs." For Table: "Use compact row height in dashboard and list contexts. TableHead cells use text-xs font-medium text-muted-foreground. Do not use alternating row backgrounds — rely on hover state only." For Badge: "Use variant='secondary' for status labels and variant='outline' for count indicators. Reserve variant='default' (high contrast) for alerts, not informational labels." These entries are not theoretical — they capture the real decisions your product makes, which an agent cannot infer from the shadcn source code alone.

Page-level patterns for shadcn products

Beyond individual components, DESIGN.md should document how shadcn primitives combine into full page patterns. The dashboard overview pattern might specify: a top-row stats grid using four compact Card components with a single metric number and a label, a main content area using a CardHeader plus Table structure, and a sidebar panel using a Card with a distinct background. The settings page pattern might specify: stacked Card components with CardHeader for section titles and CardContent for form fields, with each section separated by 24px of vertical space rather than dividers. The form pattern specifies: Label plus Input pairs with 4px gap, error messages as text-destructive text-sm below the field, form actions right-aligned with the primary action last. Documenting these layouts explicitly means that when an agent builds a new settings section or a new data view, it has a structural model to follow rather than inventing a layout from scratch. The most common failure in shadcn-based AI code is not wrong component usage in isolation — it is wrong component composition, where the right components are arranged in the wrong structural relationship to each other.

Building a product identity on top of the library

The finish line for DESIGN.md on a shadcn project is a file specific enough that a new agent can generate UI that does not feel like the shadcn starter template. The critical entries are the ones that diverge from shadcn defaults: custom radius values, custom primary color HSL, adjusted density preferences, component variant choices specific to your product type. Include the two or three visual anti-patterns most likely to make the product look generic: for a developer tool that might be "no decorative gradients," "no hero-style sections inside the app shell," and "no card shadows — use border instead." For a consumer product it might be different choices. The point is that the anti-patterns section captures the difference between your product and the library default — the exact gap that agents would otherwise fill with template behavior. A maintained DESIGN.md for a shadcn project lets the team move fast with the library while preserving the visual identity that makes the product distinct. Components stay up to date with shadcn releases; the product identity stays defined in DESIGN.md and is applied consistently whether a human or an agent is doing the implementation.

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