Get Pro Access

Icons

The Lucide-based icon layer and how to use it.

Lucide only

Every icon in Kiwa UI comes from Lucide. One icon set means a consistent stroke, weight, and geometry across components. No mixing styles, no duplicate visuals.

Blocks and primitives must not contain inline SVG icon components. SVG is only allowed for non-icon visuals like charts, gradients, or decorative patterns.

The icon layer

The canonical file is registry/ui/icon.tsx. It exposes:

ExportDescription
IconA component that takes an iconNode prop and renders a fixed 24×24 SVG.
createIcon(iconNode)A factory that turns any Lucide IconNode into a named component.
Semantic named exportsAround 190 of them, like ButtonIcon, CheckIcon, SearchIcon, ChevronDownIcon. Every name ends in Icon.

Sizing is applied via class. The viewBox stays fixed at 24×24 so icons scale crisply from 12px to 48px without blur.

Usage

import { CheckIcon, SearchIcon } from '@/components/ui/icon'

export const Status = () => (
  <div class='flex items-center gap-2'>
    <CheckIcon class='size-4 text-success' />
    <span>Saved</span>
  </div>
)

export const SearchButton = () => (
  <button class='flex items-center gap-2'>
    <SearchIcon class='size-5' />
    Search
  </button>
)

Adding a new icon

Lucide ships hundreds of icons. If the one you need isn't already exported from icon.tsx, add it with createIcon:

// registry/ui/icon.tsx
import { Sparkles } from 'lucide'

// …existing exports…

export const SparklesIcon = createIcon(Sparkles)

Use a semantic name when one fits (e.g. DeleteIcon for Trash2) so callers don't have to know the underlying Lucide name.

When to use SVG directly

Reach for raw <svg> only for visuals that aren't icons: chart primitives, gradient backgrounds, decorative patterns, product screenshots rendered as vectors. If it represents an action or object in the interface, it's an icon and it must come from Lucide.