A design system isn't just components—it's constraints that enable consistency and speed. Combining Tailwind's utility-first approach with Radix's accessible primitives creates a powerful foundation.
Design Tokens: The Foundation
// tailwind.config.ts
export default {
theme: {
extend: {
colors: {
brand: {
50: '#faf5ff',
500: '#8b5cf6',
900: '#4c1d95',
},
semantic: {
success: '#22c55e',
warning: '#f59e0b',
error: '#ef4444',
},
},
spacing: {
'component-xs': '0.25rem',
'component-sm': '0.5rem',
'component-md': '1rem',
'component-lg': '1.5rem',
},
borderRadius: {
'component': '0.5rem',
},
},
},
}
Component Architecture with Radix
// components/ui/button.tsx
import * as React from 'react'
import { Slot } from '@radix-ui/react-slot'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '@/lib/utils'
const buttonVariants = cva(
'inline-flex items-center justify-center rounded-component font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
primary: 'bg-brand-500 text-white hover:bg-brand-600',
secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200',
ghost: 'hover:bg-gray-100',
destructive: 'bg-semantic-error text-white hover:bg-red-600',
},
size: {
sm: 'h-8 px-3 text-sm',
md: 'h-10 px-4',
lg: 'h-12 px-6 text-lg',
},
},
defaultVariants: {
variant: 'primary',
size: 'md',
},
}
)
interface ButtonProps extends React.ButtonHTMLAttributes,
VariantProps {
asChild?: boolean
}
const Button = React.forwardRef(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : 'button'
return (
)
}
)
export { Button, buttonVariants }
Accessible Primitives with Radix
// Dialog with full accessibility
import * as Dialog from '@radix-ui/react-dialog'
export function Modal({ trigger, title, children }) {
return (
{trigger}
{title}
{children}
)
}
Documentation with Storybook
// Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react'
import { Button } from './button'
const meta: Meta = {
component: Button,
tags: ['autodocs'],
argTypes: {
variant: {
control: 'select',
options: ['primary', 'secondary', 'ghost', 'destructive'],
},
size: {
control: 'select',
options: ['sm', 'md', 'lg'],
},
},
}
export default meta
type Story = StoryObj
export const Primary: Story = {
args: { children: 'Primary Button', variant: 'primary' },
}
export const AllVariants: Story = {
render: () => (
),
}
Key Takeaways
Design tokens establish the visual language. Colors, spacing, and typography should be systematic.
CVA manages variant complexity. Class Variance Authority makes multi-variant components maintainable.
Radix provides accessibility for free. Focus management, keyboard navigation, and ARIA are built in.
Documentation is part of the system. Storybook ensures components are discoverable and usable.
