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.
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 5,900+ icons versus Lucide’s ~1,700, 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 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" />;
Quick comparison
| Set | Icon count | Grid | Best for |
|---|---|---|---|
| Lucide (default) | ~1,700 | 24px, 2px stroke | Ships with shadcn, zero setup |
| Tabler | 5,900+ | 24px, 2px stroke | Need broad coverage, same visual weight |
| Radix Icons | ~300 | 15x15 | Already using Radix primitives directly |
| Phosphor | 9,000+ (×6 weights) | 24px variable | Need multiple icon weights |