Design SystemTailwind CSSRadix UIFrontend

Building a Design System with Tailwind CSS and Radix UI

Learn how to create a scalable, maintainable design system using Tailwind CSS and Radix UI primitives.

2 min read
Building a Design System with Tailwind CSS and Radix UI

The Foundation of Great UX

A well-designed system is the backbone of any successful application. By combining Tailwind CSS's utility-first approach with Radix UI's accessible primitives, we can create a robust design system that scales.

Why This Combination Works

Tailwind CSS Benefits:

  • Utility-first approach for rapid development
  • Consistent spacing and color scales
  • Responsive design built-in
  • Small production bundle sizes

Radix UI Benefits:

  • Accessible by default
  • Unstyled, composable primitives
  • Keyboard navigation support
  • Focus management

Setting Up Your Design System

1. Configure Tailwind CSS

Start by customizing your Tailwind configuration with your design tokens:

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: {
          50: '#eff6ff',
          500: '#3b82f6',
          900: '#1e3a8a',
        },
        gray: {
          50: '#f9fafb',
          500: '#6b7280',
          900: '#111827',
        }
      },
      fontFamily: {
        sans: ['Inter', 'sans-serif'],
      },
      spacing: {
        '18': '4.5rem',
        '88': '22rem',
      }
    }
  }
}

2. Create Base Components

Build your foundational components using Radix primitives:

// Button Component
import * as React from 'react'
import { Slot } from '@radix-ui/react-slot'
import { cn } from '@/lib/utils'

const buttonVariants = {
  variant: {
    default: 'bg-primary-500 text-white hover:bg-primary-600',
    outline: 'border border-gray-300 bg-white hover:bg-gray-50',
    ghost: 'hover:bg-gray-100',
  },
  size: {
    sm: 'h-8 px-3 text-sm',
    md: 'h-10 px-4',
    lg: 'h-12 px-6 text-lg',
  }
}

export function Button({ 
  className, 
  variant = 'default', 
  size = 'md',
  asChild = false,
  ...props 
}) {
  const Comp = asChild ? Slot : 'button'
  
  return (
    <Comp
      className={cn(
        'inline-flex items-center justify-center rounded-md font-medium transition-colors',
        'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500',
        'disabled:pointer-events-none disabled:opacity-50',
        buttonVariants.variant[variant],
        buttonVariants.size[size],
        className
      )}
      {...props}
    />
  )
}

Component Architecture

Layer Structure:

  1. Primitives: Radix UI components
  2. Base Components: Styled primitives with variants
  3. Composite Components: Complex UI patterns
  4. Page Components: Feature-specific components

Conclusion

By combining Tailwind CSS and Radix UI, you can create a design system that is both powerful and maintainable. This approach ensures consistency, accessibility, and scalability across your entire application.

More Articles

Continue reading with these related posts