Iconography

One icon library, one stroke weight, one set of rules. Lucide ships with every shadcn project and covers every functional icon you’ll need. The diagonal up-right arrow stays as the signature gesture on CTAs, links, and “read more” affordances — rendered via Lucide’s arrow-up-right.

The arrow

Path

M4 12L12 4M12 4H5M12 4V11

Viewbox

0 0 16 16

Stroke

currentColor · 1.5px

Linecap / join

round · round

Default size

14×14 (inline) · 12×12 (small)

File

assets/arrow.svg

<!-- Canonical markup -->
<svg width="14" height="14" viewBox="0 0 16 16" fill="none">
  <path d="M4 12L12 4M12 4H5M12 4V11"
        stroke="currentColor" stroke-width="1.5"
        stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Hover behavior

On hover, the arrow shifts up and to the right: transform: translate(2px, -2px). The transition is 200ms ease. Paired with the pill button, the button fills and the arrow moves together.

Hover me

Hover the button to see the arrow nudge and the button fill.

The icon library — Lucide

Lucide is the icon library. ~1,400 outline icons, consistent 24×24 grid, stroke-customizable. It’s shadcn’s default, so every Button, Dialog, and Select primitive already uses it.

License

ISC (same family as MIT). Free for commercial use, modification, and redistribution. No attribution required in your UI. Ship it anywhere.

Preview

Every icon renders in currentColor, so it inherits whatever text color surrounds it. Toggle through the brand palette, semantic colors, stroke weight, and size to see every variant:

Color

Semantic colors (destructive, success, warning) are for status badges only. Previewed here to show the icon in context, not recommended as decoration.

Stroke

1.5 is the brand default (matches pill button border width).

Size

Coloring rules

  • Default: currentColor. Icons inherit the surrounding text color — usually --text-muted for inactive states, --foreground for primary contexts.
  • Active / emphasized: --accent (indigo). For selected sidebar items, active toggles, primary actions.
  • Disabled / tertiary: --text-faint.
  • Never tint a decorative icon in --destructive, --success, or --warning. Those colors are for status badges, not icons-as-decoration.

Sizing

  • 14px — inline with body text, inside small buttons
  • 16px — most common; toolbars, row actions, sidebar nav
  • 18–20px — featured list items, section headers
  • 22–24px — empty states, hero cards, large affordances

Stroke weight: always 1.5 (matches the pill button border).

Install

Shadcn projects already have it. For React without shadcn:

npm install lucide-react

Usage:

import { Search, Settings } from 'lucide-react'

<Search className="h-4 w-4" strokeWidth={1.5} />

Animated icons — Lucide Animated

Lucide Animated ships every Lucide icon with a tasteful hover or click animation, built on Motion. Same icon vocabulary, same stroke style — just alive when you need them to be. Use sparingly: marketing pages, empty states, micro-rewards. Never on dense toolbars.

License

MIT. Free for commercial use. Each icon is a copy-pasteable React component (Motion + Lucide). Installs through the shadcn CLI, so it slots into a project alongside the Shibin shadcn theme and inherits brand tokens via currentColor.

Preview

Hover any icon to play its animation. The recreations below use CSS to demonstrate the visual style — production usage installs the React components. The color and stroke toggles above apply here too.

Install

Each icon is its own component. Add one through the shadcn CLI:

pnpm dlx shadcn@latest add @lucide-animated/heart

Browse the full set at lucide-animated.com.

Usage:

import { Heart } from '@/components/ui/heart'

<Heart className="text-foreground" />

When to reach for it

  • Yes: primary CTA confirmations (heart on save, sparkles on AI), empty-state nudges, hero affordances on the homepage.
  • No: dense toolbars, table row actions, sidebar navigation. Motion in those contexts becomes noise.
  • Never both: on any single surface, pick animated or static — mixing makes the static icons feel broken.

What to avoid

Even with Lucide, a few rules stay non-negotiable:

  • ×Unicode arrows (→ ↗ ➜) — use Lucide’s arrow-up-right
  • ×Mixing icon libraries (no Heroicons, no Phosphor)
  • ×Emoji (🚀 ✨ 👉) in UI chrome
  • ×Filled / solid variants as default (outline only)
  • ×Multi-color icons (always single stroke color)
  • ×Stroke weights other than 1.5

If a surface seems to need more iconography, it usually needs better typography and spacing instead.

In use

Three common placements:

On a pill

Read

On a text link

View project

On a card

Field notes