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

Let's Work Together

Have a project, role, or idea in mind? Reach out and let’s explore how I can help.

Get in Touch

Location

🇩🇪 Berlin, Germany

© 2025. All rights reserved.