Design systems are one of those things that feel like overhead until you don't have one. This post documents how we built a production design system for a 40-screen SaaS product using Tailwind CSS and Radix UI.
Why Tailwind and Radix
Tailwind handles styling without the overhead of a traditional CSS-in-JS system. Radix provides unstyled, accessible component primitives that we style with Tailwind. The combination gives us full control over visual design while getting accessibility for free.
Folder Structure
Components are organized into ui (primitive components), composite (business components), and layout (layout components) folders. Everything begins with design tokens defined as CSS custom properties.
Design Tokens
We define colour, spacing, typography, and shadow scales as CSS custom properties. Tailwind's config references these properties — which means changing a token propagates through every component automatically.
Component API Design
Each primitive has a deliberate API. We follow Radix conventions for composition: asChild for polymorphic rendering, size and variant props that map to Tailwind class variants, and ref forwarding throughout.
Storybook Integration
Every component has a Storybook story that covers all variants and interactive states. We added accessibility checks and visual regression tests via Chromatic.