Skip to content
All essays
CraftFebruary 14, 202511 min

Design Systems: Building Scalable UI Component Libraries

Learn to build design systems. From design tokens to component libraries, create consistent UI at scale.

Ü
Ümit Uz
Mobile & Full Stack Developer

What is a Design System?

A design system is a collection of reusable components, guided by clear standards, that can be assembled to build any number of applications.

Design Tokens

Color System

css
:root {
  /* Primary colors */
  --color-primary-50: #eff6ff;
  --color-primary-500: #3b82f6;
  --color-primary-900: #1e3a8a;

  /* Semantic colors */
  --color-success: #10b981;
  --color-warning: #f59e0b;
  --color-error: #ef4444;
  --color-info: #3b82f6;
}

Typography Scale

css
:root {
  --font-size-xs: 0.75rem;    /* 12px */
  --font-size-sm: 0.875rem;   /* 14px */
  --font-size-base: 1rem;     /* 16px */
  --font-size-lg: 1.125rem;   /* 18px */
  --font-size-xl: 1.25rem;    /* 20px */
  --font-size-2xl: 1.5rem;    /* 24px */
  --font-size-3xl: 1.875rem;  /* 30px */
}

Component Library

Button Component

typescript
// React component with variants
type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost';
type ButtonSize = 'sm' | 'md' | 'lg';

interface ButtonProps {
  variant?: ButtonVariant;
  size?: ButtonSize;
  children: React.ReactNode;
  onClick?: () => void;
}

export const Button: React.FC<ButtonProps> = ({
  variant = 'primary',
  size = 'md',
  children,
  onClick
}) => {
  const baseStyles = 'rounded-lg font-medium transition-colors';
  const sizeStyles = {
    sm: 'px-3 py-1.5 text-sm',
    md: 'px-4 py-2 text-base',
    lg: 'px-6 py-3 text-lg'
  };
  const variantStyles = {
    primary: 'bg-primary-500 text-white hover:bg-primary-600',
    secondary: 'bg-gray-500 text-white hover:bg-gray-600',
    outline: 'border-2 border-primary-500 text-primary-500 hover:bg-primary-50',
    ghost: 'text-primary-500 hover:bg-primary-50'
  };

  return (
    <button
      className={`${baseStyles} ${sizeStyles[size]} ${variantStyles[variant]}`}
      onClick={onClick}
    >
      {children}
    </button>
  );
};

Documentation

Storybook Integration

typescript
// Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';

const meta: Meta<typeof Button> = {
  title: 'Components/Button',
  component: Button,
  tags: ['autodocs'],
};

export default meta;
type Story = StoryObj<typeof Button>;

export const Primary: Story = {
  args: {
    variant: 'primary',
    children: 'Primary Button',
  },
};

export const Secondary: Story = {
  args: {
    variant: 'secondary',
    children: 'Secondary Button',
  },
};

Versioning Strategy

Semantic Versioning

json
{
  "name": "my-design-system",
  "version": "2.1.0"
}
  • MAJOR: Breaking changes
  • MINOR: New features, backward compatible
  • PATCH: Bug fixes

Distribution

npm Package

json
{
  "name": "@mycompany/ui-components",
  "version": "1.0.0",
  "main": "dist/index.js",
  "module": "dist/index.esm.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist"
  ]
}

Best Practices

  1. 1Document everything: Components, tokens, guidelines
  2. 2Version control: Use semantic versioning
  3. 3Accessibility: WCAG AA compliant
  4. 4Responsive: Mobile-first approach
  5. 5Test components: Visual regression testing

Conclusion

A good design system improves consistency and developer productivity. Start small, iterate often.

Related essays

Next essay
Testing Strategies: Unit, Integration, and E2E Testing