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.

Amit Yadav
Amit Yadav

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

Info

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" />;
Tip

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

SetIcon countGridBest for
Lucide (default)~1,70024px, 2px strokeShips with shadcn, zero setup
Tabler5,900+24px, 2px strokeNeed broad coverage, same visual weight
Radix Icons~30015x15Already using Radix primitives directly
Phosphor9,000+ (×6 weights)24px variableNeed multiple icon weights

Frequently asked questions

No. shadcn/ui's components accept any React SVG icon component through their existing prop interfaces — swapping the import is enough, there's no hard dependency baked into the component logic.

Not if the replacement icon respects the same className/size props Lucide does. Tabler and Phosphor both mirror Lucide's prop API closely; Radix Icons is slightly more minimal but still accepts className for sizing and color.

Tabler, since it shares Lucide's exact 24px grid and 2px stroke convention. Radix Icons is visually closest in philosophy (same team, same minimalism) but uses a smaller 15x15 grid, which can look slightly different at larger render sizes.

Yes, this is common — use Lucide for shadcn's own component internals and a larger set like Tabler for the rest of your app's icons, as long as the two sets share a similar stroke weight so they don't visually clash side by side.

Yes, particularly if you want a bold or duotone weight for emphasis states (active nav item, alert icons) while keeping regular weight for everything else — a distinction Lucide, Tabler, and Radix Icons don't offer since they each ship one weight.
Share this post