Customizing Tailwind: Theme and Design Tokens
Extend Tailwind's theme with custom colors, spacing, and design tokens that scale across a real product without fighting the framework.
What you'll learn
- ✓theme vs extend
- ✓Color scales
- ✓CSS variables
- ✓Dark mode tokens
- ✓Token naming
Prerequisites
- •Comfortable with JS
What and Why
Tailwind ships with a sensible default theme: a color palette, a spacing scale, a type ramp. Real products outgrow defaults quickly. You need brand colors, custom radii, perhaps a denser spacing scale for tables. The goal is to extend Tailwind so your design system lives in one place and every utility class reflects it.
Design tokens are the bridge between Figma and code. When designers change a brand color, you change it once in tailwind.config.js (or in CSS variables) and every component updates. No find-and-replace, no drift.
Mental Model
Tailwind’s theme is a tree. theme.colors, theme.spacing, theme.fontSize, and so on. Replacing a branch wipes the defaults; extending it merges with them. Most teams want to extend for additive tokens (a new brand color) and replace for opinionated overrides (a fully custom spacing scale).
tailwind.config.js
theme.extend.colors.brand = { 500: 'oklch(...)' }
|
v
class="bg-brand-500"
|
v
background-color: oklch(...); Hands-on Example
Add brand colors and a custom radius:
// tailwind.config.js
export default {
content: ['./src/**/*.{astro,html,js,ts,jsx,tsx}'],
theme: {
extend: {
colors: {
brand: {
50: 'oklch(97% 0.02 270)',
500: 'oklch(60% 0.18 270)',
900: 'oklch(25% 0.10 270)',
},
},
borderRadius: { xl2: '1.25rem' },
fontFamily: { display: ['Inter Variable', 'sans-serif'] },
},
},
};
Use them like any utility:
<button class="bg-brand-500 text-white rounded-xl2 font-display">
Continue
</button>
For runtime theming (light, dark, branded tenants), drive tokens through CSS variables:
:root {
--color-bg: oklch(99% 0 0);
--color-fg: oklch(15% 0 0);
}
.dark {
--color-bg: oklch(15% 0 0);
--color-fg: oklch(95% 0 0);
}
// tailwind.config.js
extend: {
colors: {
bg: 'var(--color-bg)',
fg: 'var(--color-fg)',
},
}
Now bg-bg text-fg flips on .dark without rebuilding.
Common Pitfalls
A few common traps:
- Replacing instead of extending. Writing
theme: { colors: { brand: ... } }deletes every default color. Usetheme.extend. - Hex everywhere. Modern color spaces like
oklchgive perceptually even ramps and richer gradients. Hex is fine but limits you. - Magic numbers in markup.
mt-[17px]defeats the system. Add a token if you need a specific value more than once. - Forgetting safelist. Classes built from dynamic strings (
bg-${color}-500) get purged. Use safelist or precompute the full class. - Per-component custom CSS. If you find yourself opening a
.cssfile, ask whether a token is missing.
Best Practices
Name tokens by role, not by appearance. bg-surface survives a redesign; bg-slate-50 does not. Keep two layers: primitive tokens (color scales, raw spacing) and semantic tokens (surface, border, accent) that reference primitives. Components consume the semantic layer.
Limit the palette. Five or six colors with three to five steps each cover almost any app. Bigger palettes invite inconsistency. The same applies to spacing: a tight scale forces visual rhythm.
Document tokens where designers can find them. A simple page that renders every color and spacing utility keeps everyone aligned and surfaces gaps early.
Wrap-up
Extend Tailwind’s theme thoughtfully, lean on CSS variables for runtime theming, and name tokens by role. Done well, your tailwind.config.js becomes the single source of truth for visual language, and every component class reads like the design system speaking.
Related articles
- Tailwind Design Tokens and Theming with Tailwind CSS
Build a robust theming system using custom design tokens, CSS variables, theme extension, and multi-brand support in Tailwind CSS.
- Tailwind Dark Mode Strategies in Tailwind CSS
Master dark mode in Tailwind CSS with class strategy, media strategy, custom toggles, CSS variable theming, and flash-free server-side approaches.
- Tailwind Tailwind Dark Mode Strategies: Class, Media, and CSS Variables
Compare the class-based, media-based, and variable-driven approaches to dark mode in Tailwind, with code and the trade-offs of each.
- Tailwind Responsive Design Patterns with Tailwind CSS
Master mobile-first breakpoints, container queries, responsive grids, and real-world layout patterns using Tailwind CSS utilities.