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 |