Tailwind CSS SVG Icons, Free Icon Sets for Tailwind
Best free SVG icon packs for Tailwind CSS. Material Symbols, Heroicons, Phosphor, and more with practical color and sizing patterns.
On this page
- Best icon libraries for Tailwind CSS
- Color via currentColor
- Sizing with h-* and w-* classes
- Heroicons with Tailwind
- Lucide React with Tailwind
- Dark mode icons
- When dark: classes don’t work
- Filled icons vs stroked icons
- Icon button with Tailwind
- Tailwind plugin: @tailwindcss/forms icons
- Inline SVG approach (no package)
- Frequently asked questions
Tailwind CSS and SVG icons pair naturally through currentColor, your icon inherits any text color class you apply. Here’s how to get clean, scalable icons with Tailwind.
Best icon libraries for Tailwind CSS
Heroicons is built by the Tailwind team and uses the exact same sizing scale. Lucide is the second most popular choice for Tailwind projects.
Color via currentColor
Stroked SVG icons (Lucide, Heroicons, Tabler) use currentColor by default, so they inherit Tailwind text color classes:
<!-- Tailwind text color classes control the icon color -->
<svg class="h-5 w-5 text-indigo-600" ...>...</svg>
<!-- Dark mode variant -->
<svg class="h-5 w-5 text-gray-800 dark:text-gray-200" ...>...</svg>
<!-- Hover color -->
<svg class="h-5 w-5 text-gray-500 hover:text-gray-900 transition-colors" ...>...</svg>
Sizing with h-* and w-* classes
Tailwind’s spacing scale maps directly to icon sizes:
| Tailwind class | Size |
|---|---|
h-4 w-4 |
16px |
h-5 w-5 |
20px |
h-6 w-6 |
24px |
h-8 w-8 |
32px |
h-10 w-10 |
40px |
<svg class="h-5 w-5" ...>...</svg> <!-- inline, 20px -->
<svg class="h-6 w-6" ...>...</svg> <!-- standard, 24px -->
Heroicons with Tailwind
Heroicons was designed for Tailwind. It ships two variant sets matching Tailwind’s design language:
import {
HomeIcon, // outline variant (24px)
BellIcon,
Cog6ToothIcon,
} from '@heroicons/react/24/outline';
import {
HomeIcon as HomeSolid, // solid variant
} from '@heroicons/react/24/solid';
// 20px mini variant (matches Tailwind's text-sm ui density)
import { HomeIcon as HomeMini } from '@heroicons/react/20/solid';
export function Nav() {
return (
<nav className="flex items-center gap-3">
<HomeIcon className="h-5 w-5 text-gray-600" />
<BellIcon className="h-5 w-5 text-gray-600 hover:text-indigo-600 transition" />
</nav>
);
}
Lucide React with Tailwind
import { Home, Bell, Settings } from 'lucide-react';
// Use className for color, size prop or h-/w- classes for size
<Home className="h-5 w-5 text-gray-700 dark:text-gray-300" />
// strokeWidth for thinner or bolder strokes
<Home className="h-5 w-5" strokeWidth={1.5} />
<Home className="h-5 w-5" strokeWidth={2.5} />
Dark mode icons
Use Tailwind’s dark: prefix on text-* classes, the icon color follows automatically because SVG uses currentColor.
<!-- Light: gray-700, Dark: gray-300 -->
<svg class="h-5 w-5 text-gray-700 dark:text-gray-300" ...>...</svg>
<!-- Light: indigo-600, Dark: indigo-400 -->
<svg class="h-5 w-5 text-indigo-600 dark:text-indigo-400" ...>...</svg>
When dark: classes don’t work
currentColor only helps if the SVG uses it. Raw files from Figma or AI tools often ship with a hardcoded fill="#111827", which stays dark on a dark background no matter what class you add. Replace hardcoded colors with currentColor first. For the cases you can’t edit:
| Situation | Fix |
|---|---|
Hardcoded fill or stroke in an inline SVG |
Replace the value with currentColor |
Black single-color icon in an <img> tag |
dark:invert (never on colored or brand icons: invert turns blue into orange) |
| Many icon tones in a design system | CSS variables per theme, used as text-[var(--icon-muted)] |
| Icons vanish in Windows High Contrast | Use currentColor; it follows forced colors automatically |
:root { --icon-muted: #9ca3af; --icon-accent: #2563eb; }
.dark { --icon-muted: #6b7280; --icon-accent: #60a5fa; }
With the tokens in place, <Bell className="h-5 w-5 text-[var(--icon-muted)]" /> switches theme without a dark: class on every icon. Check that icons still reach a 3:1 contrast ratio against the background in both modes.
Filled icons vs stroked icons
Filled icons (like Heroicons solid) use fill="currentColor", not stroke. The rules are the same: control color via Tailwind text-* classes.
<!-- Stroked icon -->
<svg stroke="currentColor" fill="none" class="h-5 w-5 text-gray-600" ...>...</svg>
<!-- Filled icon -->
<svg fill="currentColor" stroke="none" class="h-5 w-5 text-indigo-600" ...>...</svg>
Icon button with Tailwind
<button
className="inline-flex items-center justify-center h-9 w-9 rounded-md
text-gray-500 hover:bg-gray-100 hover:text-gray-900
dark:hover:bg-gray-800 dark:hover:text-gray-100
transition-colors"
aria-label="Settings"
>
<Settings className="h-4 w-4" aria-hidden="true" />
</button>
Keep icon button states consistent: hover:text-* for hover, active:text-* for press, disabled:opacity-50 for disabled, and a focus-visible:ring-2 so keyboard users can see focus. Stick to two or three icon sizes (h-4 w-4, h-5 w-5, h-6 w-6) across the product; a shared icon wrapper component with a fixed size prop stops one-off sizes from drifting in.
Tailwind plugin: @tailwindcss/forms icons
The Tailwind forms plugin uses background-image SVG for checkboxes and radios, those are different from component icons. For UI component icons, use an icon library component, not a background image.
Inline SVG approach (no package)
Copy from AllSVGIcons and paste directly, add Tailwind classes on the <svg> element:
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 text-gray-600 hover:text-indigo-600 transition-colors"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path stroke-linecap="round" stroke-linejoin="round"
d="M21 21l-4.35-4.35M17 11A6 6 0 1 1 5 11a6 6 0 0 1 12 0z" />
</svg>
Frequently asked questions
How do I change SVG icon color in Tailwind CSS?
Which icon library works best with Tailwind CSS?
How do I make SVG icons responsive in Tailwind?
How do I set SVG icon size with Tailwind?
Do SVG icons work with Tailwind dark mode?
Related posts