Theme Customization 
Headwind's theme system allows you to customize every aspect of your design tokens including colors, spacing, typography, and more. The theme is fully compatible with Tailwind CSS, making migration seamless.
Overview 
The theme configuration defines the design tokens that utilities are generated from. When you use a utility like bg-blue-500 or p-4, Headwind looks up the value in your theme configuration.
// headwind.config.ts
import type { HeadwindOptions } from 'headwind'
const config = {
  theme: {
    colors: {
      primary: '#3b82f6', // bg-primary
      secondary: '#8b5cf6', // bg-secondary
    },
    spacing: {
      4: '1rem', // p-4, m-4, etc.
      8: '2rem', // p-8, m-8, etc.
    },
  },
} satisfies HeadwindOptions
export default configColors 
Basic Colors 
Define simple color values:
const config = {
  theme: {
    colors: {
      black: '#000000',
      white: '#ffffff',
      primary: '#3b82f6',
      secondary: '#8b5cf6',
      danger: '#ef4444',
      success: '#10b981',
      warning: '#f59e0b',
    },
  },
}Usage:
<div class="bg-primary text-white">Primary</div>
<div class="bg-danger text-white">Danger</div>
<div class="border-2 border-success">Success</div>Color Scales 
Define color palettes with shades:
const config = {
  theme: {
    colors: {
      gray: {
        50: '#f9fafb',
        100: '#f3f4f6',
        200: '#e5e7eb',
        300: '#d1d5db',
        400: '#9ca3af',
        500: '#6b7280',
        600: '#4b5563',
        700: '#374151',
        800: '#1f2937',
        900: '#111827',
      },
      blue: {
        50: '#eff6ff',
        100: '#dbeafe',
        200: '#bfdbfe',
        300: '#93c5fd',
        400: '#60a5fa',
        500: '#3b82f6',
        600: '#2563eb',
        700: '#1d4ed8',
        800: '#1e40af',
        900: '#1e3a8a',
      },
    },
  },
}Usage:
<div class="bg-gray-100 text-gray-900">Light gray</div>
<div class="bg-blue-500 text-white">Blue 500</div>
<div class="border border-gray-300">Border</div>Custom Color Names 
Use any naming convention you prefer:
const config = {
  theme: {
    colors: {
      brand: {
        light: '#bfdbfe',
        DEFAULT: '#3b82f6',
        dark: '#1e40af',
      },
      accent: '#f59e0b',
      neutral: {
        100: '#f5f5f5',
        900: '#171717',
      },
    },
  },
}Usage:
<div class="bg-brand">Uses DEFAULT value</div>
<div class="bg-brand-light">Light brand</div>
<div class="text-accent">Accent text</div>RGB/HSL Colors 
Use any valid CSS color format:
const config = {
  theme: {
    colors: {
      primary: 'rgb(59, 130, 246)',
      secondary: 'hsl(258, 90%, 66%)',
      transparent: 'transparent',
      current: 'currentColor',
    },
  },
}CSS Variables 
Reference CSS custom properties:
const config = {
  theme: {
    colors: {
      primary: 'var(--color-primary)',
      secondary: 'var(--color-secondary)',
      background: 'var(--color-bg)',
      foreground: 'var(--color-fg)',
    },
  },
}CSS:
:root {
  --color-primary: #3b82f6;
  --color-secondary: #8b5cf6;
  --color-bg: #ffffff;
  --color-fg: #000000;
}
.dark {
  --color-bg: #000000;
  --color-fg: #ffffff;
}Spacing 
Control padding, margin, width, height, and other space-based utilities:
const config = {
  theme: {
    spacing: {
      0: '0',
      px: '1px',
      0.5: '0.125rem', // 2px
      1: '0.25rem', // 4px
      1.5: '0.375rem', // 6px
      2: '0.5rem', // 8px
      2.5: '0.625rem', // 10px
      3: '0.75rem', // 12px
      3.5: '0.875rem', // 14px
      4: '1rem', // 16px
      5: '1.25rem', // 20px
      6: '1.5rem', // 24px
      7: '1.75rem', // 28px
      8: '2rem', // 32px
      9: '2.25rem', // 36px
      10: '2.5rem', // 40px
      12: '3rem', // 48px
      14: '3.5rem', // 56px
      16: '4rem', // 64px
      20: '5rem', // 80px
      24: '6rem', // 96px
      32: '8rem', // 128px
      40: '10rem', // 160px
      48: '12rem', // 192px
      56: '14rem', // 224px
      64: '16rem', // 256px
    },
  },
}Usage:
<div class="p-4">Padding 1rem</div>
<div class="m-8">Margin 2rem</div>
<div class="w-64">Width 16rem</div>
<div class="gap-2">Gap 0.5rem</div>Applies to:
- Padding: p-*,px-*,py-*,pt-*,pr-*,pb-*,pl-*
- Margin: m-*,mx-*,my-*,mt-*,mr-*,mb-*,ml-*
- Width: w-*
- Height: h-*
- Gap: gap-*,gap-x-*,gap-y-*
- Inset: top-*,right-*,bottom-*,left-*,inset-*
Typography 
Font Family 
const config = {
  theme: {
    fontFamily: {
      sans: ['Inter', 'system-ui', 'sans-serif'],
      serif: ['Georgia', 'Cambria', 'serif'],
      mono: ['Fira Code', 'Menlo', 'monospace'],
      display: ['Montserrat', 'sans-serif'],
      body: ['Open Sans', 'sans-serif'],
    },
  },
}Usage:
<div class="font-sans">Sans-serif text</div>
<div class="font-serif">Serif text</div>
<div class="font-mono">Monospace text</div>
<div class="font-display">Display text</div>Font Size 
Font sizes include both size and line height:
const config = {
  theme: {
    fontSize: {
      'xs': ['0.75rem', { lineHeight: '1rem' }], // 12px, 16px line height
      'sm': ['0.875rem', { lineHeight: '1.25rem' }], // 14px, 20px line height
      'base': ['1rem', { lineHeight: '1.5rem' }], // 16px, 24px line height
      'lg': ['1.125rem', { lineHeight: '1.75rem' }], // 18px, 28px line height
      'xl': ['1.25rem', { lineHeight: '1.75rem' }], // 20px, 28px line height
      '2xl': ['1.5rem', { lineHeight: '2rem' }], // 24px, 32px line height
      '3xl': ['1.875rem', { lineHeight: '2.25rem' }], // 30px, 36px line height
      '4xl': ['2.25rem', { lineHeight: '2.5rem' }], // 36px, 40px line height
      '5xl': ['3rem', { lineHeight: '1' }], // 48px
      '6xl': ['3.75rem', { lineHeight: '1' }], // 60px
    },
  },
}Usage:
<p class="text-base">Base text</p>
<h1 class="text-4xl">Large heading</h1>
<small class="text-xs">Small text</small>Font Weight 
Font weights are built-in but can be customized via custom rules:
<div class="font-thin">Thin (100)</div>
<div class="font-light">Light (300)</div>
<div class="font-normal">Normal (400)</div>
<div class="font-medium">Medium (500)</div>
<div class="font-semibold">Semibold (600)</div>
<div class="font-bold">Bold (700)</div>
<div class="font-extrabold">Extrabold (800)</div>
<div class="font-black">Black (900)</div>Borders 
Border Radius 
const config = {
  theme: {
    borderRadius: {
      'none': '0',
      'sm': '0.125rem', // 2px
      'DEFAULT': '0.25rem', // 4px
      'md': '0.375rem', // 6px
      'lg': '0.5rem', // 8px
      'xl': '0.75rem', // 12px
      '2xl': '1rem', // 16px
      '3xl': '1.5rem', // 24px
      'full': '9999px', // Fully rounded
    },
  },
}Usage:
<div class="rounded">Default radius</div>
<div class="rounded-lg">Large radius</div>
<div class="rounded-full">Fully rounded</div>
<div class="rounded-none">No radius</div>Shadows 
Box Shadow 
const config = {
  theme: {
    boxShadow: {
      'sm': '0 1px 2px 0 rgb(0 0 0 / 0.05)',
      'DEFAULT': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
      'md': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
      'lg': '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
      'xl': '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
      '2xl': '0 25px 50px -12px rgb(0 0 0 / 0.25)',
      'inner': 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)',
      'none': 'none',
    },
  },
}Usage:
<div class="shadow">Default shadow</div>
<div class="shadow-lg">Large shadow</div>
<div class="shadow-none">No shadow</div>Breakpoints 
Screen Sizes 
const config = {
  theme: {
    screens: {
      'sm': '640px',
      'md': '768px',
      'lg': '1024px',
      'xl': '1280px',
      '2xl': '1536px',
    },
  },
}Usage:
<div class="text-base md:text-lg lg:text-xl">
  Responsive text
</div>Custom Breakpoints 
const config = {
  theme: {
    screens: {
      mobile: '320px',
      tablet: '640px',
      laptop: '1024px',
      desktop: '1280px',
      wide: '1920px',
      ultrawide: '2560px',
    },
  },
}Usage:
<div class="grid-cols-1 tablet:grid-cols-2 desktop:grid-cols-4">
  Custom breakpoints
</div>Complete Theme Example 
import type { HeadwindOptions } from 'headwind'
const config = {
  theme: {
    // Colors
    colors: {
      transparent: 'transparent',
      current: 'currentColor',
      black: '#000000',
      white: '#ffffff',
      // Brand colors
      brand: {
        50: '#eff6ff',
        100: '#dbeafe',
        200: '#bfdbfe',
        300: '#93c5fd',
        400: '#60a5fa',
        500: '#3b82f6',
        600: '#2563eb',
        700: '#1d4ed8',
        800: '#1e40af',
        900: '#1e3a8a',
      },
      // Neutrals
      gray: {
        50: '#f9fafb',
        100: '#f3f4f6',
        200: '#e5e7eb',
        300: '#d1d5db',
        400: '#9ca3af',
        500: '#6b7280',
        600: '#4b5563',
        700: '#374151',
        800: '#1f2937',
        900: '#111827',
      },
      // Semantic colors
      success: '#10b981',
      warning: '#f59e0b',
      danger: '#ef4444',
      info: '#3b82f6',
    },
    // Spacing
    spacing: {
      0: '0',
      px: '1px',
      0.5: '0.125rem',
      1: '0.25rem',
      1.5: '0.375rem',
      2: '0.5rem',
      2.5: '0.625rem',
      3: '0.75rem',
      3.5: '0.875rem',
      4: '1rem',
      5: '1.25rem',
      6: '1.5rem',
      7: '1.75rem',
      8: '2rem',
      9: '2.25rem',
      10: '2.5rem',
      11: '2.75rem',
      12: '3rem',
      14: '3.5rem',
      16: '4rem',
      20: '5rem',
      24: '6rem',
      28: '7rem',
      32: '8rem',
      36: '9rem',
      40: '10rem',
      44: '11rem',
      48: '12rem',
      52: '13rem',
      56: '14rem',
      60: '15rem',
      64: '16rem',
      72: '18rem',
      80: '20rem',
      96: '24rem',
    },
    // Typography
    fontFamily: {
      sans: ['Inter', 'system-ui', 'sans-serif'],
      serif: ['Georgia', 'Cambria', 'Times New Roman', 'serif'],
      mono: ['Fira Code', 'Consolas', 'Monaco', 'monospace'],
    },
    fontSize: {
      'xs': ['0.75rem', { lineHeight: '1rem' }],
      'sm': ['0.875rem', { lineHeight: '1.25rem' }],
      'base': ['1rem', { lineHeight: '1.5rem' }],
      'lg': ['1.125rem', { lineHeight: '1.75rem' }],
      'xl': ['1.25rem', { lineHeight: '1.75rem' }],
      '2xl': ['1.5rem', { lineHeight: '2rem' }],
      '3xl': ['1.875rem', { lineHeight: '2.25rem' }],
      '4xl': ['2.25rem', { lineHeight: '2.5rem' }],
      '5xl': ['3rem', { lineHeight: '1' }],
      '6xl': ['3.75rem', { lineHeight: '1' }],
      '7xl': ['4.5rem', { lineHeight: '1' }],
      '8xl': ['6rem', { lineHeight: '1' }],
      '9xl': ['8rem', { lineHeight: '1' }],
    },
    // Borders
    borderRadius: {
      'none': '0',
      'sm': '0.125rem',
      'DEFAULT': '0.25rem',
      'md': '0.375rem',
      'lg': '0.5rem',
      'xl': '0.75rem',
      '2xl': '1rem',
      '3xl': '1.5rem',
      'full': '9999px',
    },
    // Shadows
    boxShadow: {
      'sm': '0 1px 2px 0 rgb(0 0 0 / 0.05)',
      'DEFAULT': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
      'md': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
      'lg': '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
      'xl': '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
      '2xl': '0 25px 50px -12px rgb(0 0 0 / 0.25)',
      'inner': 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)',
      'none': 'none',
    },
    // Breakpoints
    screens: {
      'sm': '640px',
      'md': '768px',
      'lg': '1024px',
      'xl': '1280px',
      '2xl': '1536px',
    },
  },
} satisfies HeadwindOptions
export default configAdvanced Patterns 
Theme Variants 
Create different themes for different projects:
// themes/light.ts
// headwind.config.ts
import { lightTheme } from './themes/light'
export const lightTheme = {
  colors: {
    background: '#ffffff',
    foreground: '#000000',
    primary: '#3b82f6',
  },
}
// themes/dark.ts
export const darkTheme = {
  colors: {
    background: '#000000',
    foreground: '#ffffff',
    primary: '#60a5fa',
  },
}
const config = {
  theme: lightTheme,
}Dynamic Themes 
const isDark = process.env.THEME === 'dark'
const config = {
  theme: {
    colors: {
      background: isDark ? '#000000' : '#ffffff',
      foreground: isDark ? '#ffffff' : '#000000',
    },
  },
}Extending Default Theme 
Merge with the default theme:
import { defaultConfig } from 'headwind'
const config = {
  theme: {
    ...defaultConfig.theme,
    colors: {
      ...defaultConfig.theme.colors,
      brand: '#3b82f6', // Add custom color
    },
  },
}Best Practices 
1. Use Consistent Scales 
Maintain consistent spacing and sizing:
// ✅ Good - consistent scale
spacing: {
  0: '0',
  1: '0.25rem',   // 4px
  2: '0.5rem',    // 8px
  3: '0.75rem',   // 12px
  4: '1rem',      // 16px
  // ... continues consistently
}
// ❌ Avoid - inconsistent scale
spacing: {
  0: '0',
  1: '0.3rem',    // Inconsistent increment
  2: '0.7rem',    // Inconsistent increment
  3: '1.2rem',    // Inconsistent increment
}2. Name Colors Semantically 
// ✅ Good - semantic names
colors: {
  primary: '#3b82f6',
  success: '#10b981',
  danger: '#ef4444',
}
// ❌ Avoid - non-semantic names
colors: {
  blue: '#3b82f6',
  green: '#10b981',
  red: '#ef4444',
}3. Document Custom Values 
const config = {
  theme: {
    // Brand colors from design system v2.0
    colors: {
      brand: '#3b82f6', // Primary brand color
      accent: '#f59e0b', // Accent for CTAs
      muted: '#6b7280', // Text muted state
    },
    // Spacing follows 4px grid
    spacing: {
      // ... spacing values
    },
  },
}4. Organize Large Themes 
// theme/colors.ts
// headwind.config.ts
import { colors } from './theme/colors'
import { spacing } from './theme/spacing'
import { typography } from './theme/typography'
export const colors = { /* colors */ }
// theme/spacing.ts
export const spacing = { /* spacing */ }
// theme/typography.ts
export const typography = { /* typography */ }
const config = {
  theme: {
    colors,
    spacing,
    ...typography,
  },
}Migration from Tailwind 
Headwind themes are 100% compatible with Tailwind CSS:
// Your existing Tailwind config works as-is
const config = {
  theme: {
    // Copy your entire Tailwind theme here
    extend: {
      // Or use extend pattern
      colors: {
        custom: '#123456',
      },
    },
  },
}Troubleshooting 
Color Not Working 
Check:
- Color is defined in theme: typescript- theme: { colors: { primary: '#3b82f6', // ✅ }, }
- Using correct utility: html- <div class="bg-primary">✅ Works</div> <div class="background-primary">❌ Wrong utility</div>
Spacing Values Not Applied 
Check:
- Using numeric keys: typescript- spacing: { 4: '1rem', // ✅ 'four': '1rem', // ❌ Won't work with p-four }
- Values are strings: typescript- spacing: { 4: '1rem', // ✅ 8: 2, // ❌ Should be '2rem' }
Related 
- Configuration - Full configuration reference
- Presets - Share theme configurations
- Custom Rules - Extend theme with custom rules
- Usage Guide - Using theme utilities