Best SVG Icons for shadcn/ui – Lucide and 3 Solid Alternatives
shadcn/ui ships with lucide-react by default. Here's why, plus three icon sets, Tabler, Radix Icons, and Phosphor, that swap in cleanly if you need something different.
On this page
Every shadcn/ui component that needs an icon (the Select chevron, Checkbox check, Toast close button, Calendar arrows), imports from lucide-react by default. You don’t have to keep it, but it’s worth understanding why it’s the default before you swap it out.
Why Lucide is the default
Lucide is a community-maintained fork of Feather Icons: a 24px grid, 2px stroke, rounded caps, ~1,700 icons. shadcn/ui’s own components, buttons, inputs, dialogs, use a similarly minimal, low-visual-weight style, so Lucide’s icons don’t fight the rest of the design system for attention.
npm install lucide-react
import { ChevronDown } from "lucide-react";
<ChevronDown className="h-4 w-4 opacity-50" />;
Tree-shakes cleanly, ships TypeScript types, and every icon accepts standard SVG props (className, size, strokeWidth), which is exactly what shadcn’s component internals expect.
Alternative 1: Tabler Icons: when you need more coverage
Tabler uses the same 24px/2px-stroke visual language as Lucide, so it drops into shadcn components without a visual mismatch, but ships 6,200+ icons versus Lucide’s 1,900+, useful once your app needs brand logos, niche domain icons, or filled variants Lucide doesn’t cover.
npm install @tabler/icons-react
import { IconChevronDown } from "@tabler/icons-react";
<IconChevronDown className="h-4 w-4 opacity-50" stroke={1.5} />;
See the full Tabler vs Lucide comparison for stroke-weight and coverage differences.
Alternative 2: Radix Icons: the most literal match
Radix Icons is maintained by the same team behind Radix UI, the headless primitives shadcn/ui itself builds on top of. If you’re already using Radix primitives directly (not just via shadcn), Radix Icons keeps every dependency in the same design lineage, same 15x15 grid discipline, same minimal aesthetic.
npm install @radix-ui/react-icons
import { ChevronDownIcon } from "@radix-ui/react-icons";
<ChevronDownIcon className="h-4 w-4 opacity-50" />;
Radix Icons are fill-based on a 15x15 viewBox and take width and height (default 15) instead of a size prop, so size them with className="h-4 w-4". Projects set up with the older shadcn “new-york” style may still import @radix-ui/react-icons inside src/components/ui/ (CheckIcon, ChevronDownIcon, DotFilledIcon). If the rest of your app uses Lucide, swap those imports so stroke and fill icons don’t sit side by side.
Radix Icons is deliberately small (~300 icons) and not actively expanding: fine for UI chrome (chevrons, checks, close buttons) but you’ll likely need a second, larger set for content icons.
Alternative 3: Phosphor: when you want icon weight variants
Phosphor ships six weights per icon (thin, light, regular, bold, fill, duotone), useful if your design system needs a heavier icon for emphasis states without switching libraries.
npm install @phosphor-icons/react
import { CaretDown } from "@phosphor-icons/react";
<CaretDown weight="regular" className="h-4 w-4 opacity-50" />;
Install single icons with the shadcn CLI
If you only need a handful of icons, you can skip the npm package entirely. AllSVGIcons serves every icon as a shadcn registry item, so the shadcn CLI copies the SVG straight into your project:
pnpm dlx shadcn@latest add https://i.allsvgicons.com/r/lucide:plus.json
Swap lucide:plus for any pack:icon name, for example tabler:chevron-down or ph:caret-down. To shorten the command, register a namespace in components.json:
{
"registries": {
"@allsvgicons": "https://i.allsvgicons.com/r/{name}.json"
}
}
pnpm dlx shadcn@latest add @allsvgicons/lucide:alarm-clock
The file lands in your codebase with no colors baked in, so Tailwind text-* classes style it. If you’d rather describe an icon than name it, the allsvgicons MCP server lets a coding agent search across packs and insert the SVG for you.
Quick comparison
| Set | Icon count | Grid | Best for |
|---|---|---|---|
| Lucide (default) | 1,900+ | 24px, 2px stroke | Ships with shadcn, zero setup |
| Tabler | 6,200+ | 24px, 2px stroke | Need broad coverage, same visual weight |
| Radix Icons | 330+ | 15x15 | Already using Radix primitives directly |
| Phosphor | 9,000+ (6 weights) | 24px variable | Need multiple icon weights |
Frequently asked questions
Do I have to use Lucide with shadcn/ui?
Will swapping icon libraries break shadcn component styling?
Which icon set matches shadcn's visual style most closely?
Can I mix Lucide with another icon set in the same shadcn project?
Is Phosphor good for a shadcn dashboard UI?
Related posts