Tailwind Custom Config
Tailwind comes with a default set of colors, font sizes, spacing, and breakpoints. Custom configuration lets you change those defaults or add new ones to match your brand. Everything lives in one file: tailwind.config.js.
The Config File
When you set up Tailwind, a config file is generated with this structure:
// tailwind.config.js
module.exports = {
content: ['./src/**/*.{html,js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
};Each Key Explained
- content — tells Tailwind which files to scan so unused classes get removed
- theme — where you customize or add design values
- theme.extend — adds new values without removing Tailwind's built-in defaults
- plugins — adds extra functionality through official or third-party plugins
extend vs Override
This is the most important concept in Tailwind config. Understand this and everything else becomes simple.
// OVERRIDE — replaces all built-in colors with only red and blue
theme: {
colors: {
red: '#ef4444',
blue: '#3b82f6',
}
}
// EXTEND — keeps all built-in colors AND adds your custom brand color
theme: {
extend: {
colors: {
brand: '#7c3aed',
}
}
}Diagram: extend vs Override
Built-in Tailwind Colors:
[gray] [red] [blue] [green] [yellow] [purple] ... (100+ values)
After OVERRIDE with only red and blue:
[red] [blue] ← all others gone!
After EXTEND with brand:
[gray] [red] [blue] [green] [yellow] [purple] ... [brand]
↑ your new color added
Use extend almost always. Use direct override only if you want to completely replace a section of Tailwind's design system.
Custom Colors
Add your brand's colors so you can use them like any other Tailwind color.
theme: {
extend: {
colors: {
brand: {
50: '#eff6ff',
100: '#dbeafe',
500: '#3b82f6',
700: '#1d4ed8',
900: '#1e3a8a',
},
tomato: '#ff6347',
}
}
}Now you can write classes like bg-brand-500, text-brand-700, or bg-tomato directly in your HTML.
<button class="bg-brand-500 hover:bg-brand-700 text-white px-4 py-2 rounded">
Brand Button
</button>
<p class="text-tomato font-semibold">Alert message</p>Custom Font Family
Add a custom font family to use in your classes.
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'ui-sans-serif', 'system-ui'],
heading: ['Poppins', 'sans-serif'],
mono: ['Fira Code', 'monospace'],
}
}
}<h1 class="font-heading text-3xl font-bold">Page Title</h1>
<p class="font-sans text-base">Body paragraph text here.</p>
<code class="font-mono text-sm">const x = 42;</code>Custom Spacing
Tailwind spacing goes from 0 to 96 by default. Add values outside that range when needed.
theme: {
extend: {
spacing: {
'128': '32rem',
'144': '36rem',
'18': '4.5rem',
}
}
}<div class="w-128 h-128 bg-gray-200">Large Box</div>
<div class="mt-18">Custom top margin</div>Custom Font Size
theme: {
extend: {
fontSize: {
'xxs': '0.625rem', // 10px
'2xl-plus': '1.75rem', // 28px
'display': ['4.5rem', { lineHeight: '1.1' }],
}
}
}<p class="text-xxs text-gray-400">Fine print text</p>
<h1 class="text-display font-black">Hero Heading</h1>Custom Border Radius
theme: {
extend: {
borderRadius: {
'4xl': '2rem',
'pill': '9999px',
}
}
}<div class="rounded-4xl bg-blue-100 p-6">Rounded card</div>
<span class="rounded-pill bg-green-500 text-white px-4 py-1">Badge</span>Custom Breakpoints
Tailwind's default breakpoints: sm (640px), md (768px), lg (1024px), xl (1280px), 2xl (1536px). Add your own when a project needs different screen sizes.
theme: {
extend: {
screens: {
'xs': '480px', // custom small
'3xl': '1800px', // custom very large
'tablet': '960px', // custom named breakpoint
}
}
}<div class="text-sm xs:text-base tablet:text-lg 3xl:text-xl">
Responsive text at custom breakpoints
</div>Custom Box Shadow
theme: {
extend: {
boxShadow: {
'soft': '0 2px 20px rgba(0,0,0,0.08)',
'hard': '4px 4px 0px #000',
'glow': '0 0 15px rgba(99, 102, 241, 0.5)',
}
}
}<div class="shadow-soft rounded-xl bg-white p-6">Soft card</div>
<div class="shadow-glow rounded-lg bg-indigo-600 text-white px-6 py-3">Glow button</div>Custom Animation and Keyframes
theme: {
extend: {
keyframes: {
wiggle: {
'0%, 100%': { transform: 'rotate(-5deg)' },
'50%': { transform: 'rotate(5deg)' },
},
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
}
},
animation: {
wiggle: 'wiggle 0.5s ease-in-out infinite',
fadeIn: 'fadeIn 0.3s ease-in',
}
}
}<div class="animate-wiggle text-3xl">🔔</div>
<div class="animate-fadeIn">This fades in on load</div>Full Example Config
// tailwind.config.js
module.exports = {
darkMode: 'class',
content: ['./src/**/*.{html,js,jsx,ts,tsx}'],
theme: {
extend: {
colors: {
brand: {
500: '#7c3aed',
700: '#5b21b6',
},
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
},
spacing: {
'128': '32rem',
},
screens: {
'xs': '480px',
},
borderRadius: {
'pill': '9999px',
},
animation: {
fadeIn: 'fadeIn 0.3s ease-in',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
}
}
},
},
plugins: [],
};Config Changes Take Effect After Rebuild
After editing tailwind.config.js, save the file. If you run Tailwind with a watch command, it rebuilds automatically. New classes are available right after the rebuild.
npx tailwindcss -i ./src/input.css -o ./dist/output.css --watchKey Points
- Use
theme.extendto add custom values while keeping all Tailwind defaults - Use direct
themekeys (withoutextend) only when you want to fully replace a category - Custom colors, fonts, spacing, and breakpoints all follow the same pattern
- Custom animations require both
keyframesandanimationentries - Rebuild your CSS after every config change
