Patterns

Patterns — Lucide

Import only the icons you use

When to use: any project using a framework package (lucide-react, lucide-vue-next, lucide-svelte, etc.). How: import each icon component by name (import { Smile } from 'lucide-react') instead of importing a namespace or the whole set. Trade-offs: this is what makes tree-shaking work — unused icons never reach the production bundle. Namespace imports (import * as icons) defeat this and bloat the bundle.

Bulk DOM replacement (vanilla JS)

When to use: no build step / no framework, or icons rendered from server-generated HTML. How: mark elements with data-lucide="icon-name", then call createIcons({ icons: {...} }) once after the DOM is ready. Trade-offs: simple, no component tree needed, but re-scanning the DOM on every dynamic update is more work than a framework's reactive re-render; use root to scope the scan when only part of the page changes.

Dynamic icon by name

When to use: the icon to render is data-driven (e.g. an icon name string from an API or config), not known at author time. How: use the framework's dynamic icon component/helper instead of a static per-icon import. Trade-offs: defeats some tree-shaking (the dynamic resolver typically needs access to a larger icon map), so prefer static imports whenever the icon set is known ahead of time.

Global default styling

When to use: an app wants consistent icon size/color/stroke-width everywhere without repeating props on every usage. How: set defaults once at a provider/wrapper level (framework-specific: context provider, global CSS custom properties, or a wrapper component), documented per framework under "Global Styling". Trade-offs: centralizes styling but makes a one-off icon override slightly more verbose (still fully supported via per-instance props, which win over the global default).

Color via currentColor inheritance

When to use: icon color should follow surrounding text/UI color automatically (e.g. inside a button that changes color on hover/disabled state). How: leave the default color="currentColor" and control color via CSS on a parent element instead of passing an explicit color prop. Trade-offs: one less prop to manage per icon, but requires the color to actually be set in CSS on an ancestor — a completely unstyled parent renders the icon in the browser's default text color.

Combining/layering icons

When to use: a composite visual like a badge, notification dot, or status overlay on top of a base icon. How: position two icon components absolutely within a relatively-positioned wrapper (per-framework "Combining Icons" guides show the exact markup). Trade-offs: pure CSS positioning, no special Lucide API — the pattern is about layout, not the icon library itself.

Custom/filled icon variants

When to use: the design calls for a filled version of an otherwise stroke-only icon set. How: follow the framework's "Filled Icons" guide, typically overriding fill while keeping or removing stroke. Trade-offs: Lucide's icon set is stroke-first by design; filled variants are a styling technique on top of the existing paths, not a separate icon set.

Static assets without a bundler

When to use: no JS build pipeline at all (e.g. a plain HTML site, email templates, or a CMS that only accepts static files). How: use the lucide-static package's SVG files directly, an <img> tag pointing at a sprite, or the webfont distribution. Trade-offs: no currentColor/prop-based customization at runtime for the webfont/sprite paths — styling has to happen through CSS on the <img>/font-icon element instead of component props.

Migrating from another icon set

When to use: replacing Feather Icons or an older major version of Lucide itself. How: follow the framework-specific "Migration" guide (React has a dedicated "migration-from-feather" guide; every framework has a general "migration" guide for version upgrades). Trade-offs: icon names and some prop names changed between Feather and Lucide, and between Lucide major versions — a mechanical find-and-replace is not safe without checking the migration guide's rename table.