Lucide Motion

API reference

Full prop reference for DrawIcon and MotionIconConfig.

Icon components

Every Lucide icon is exported as a React component:

import { Heart, HeartIcon } from "lucide-motion";
//        ^^^^^  ^^^^^^^^^
//        Both names point to the same component.

Each icon accepts the props below. Generated icon files are thin wrappers around <DrawIcon /> — the type for their props is Omit<DrawIconProps, "nodes"> since nodes is supplied by the wrapper.


DrawIcon props

Lucide-parity props

PropTypeDefaultNotes
sizenumber24Pixel size of the rendered SVG
colorstring"currentColor"Stroke color (inherits parent CSS color by default)
strokeWidthnumber2Line thickness
absoluteStrokeWidthbooleanfalseKeep stroke pixel-constant regardless of size
className, styleStandard React attributes, spread onto the underlying <svg>
onClick, aria-*, data-*All standard SVG attributes are forwarded
refRef<MotionIconHandle>Imperative handle (see trigger="manual")

Timing props

See Animation for live demos.

PropTypeDefaultNotes
durationnumber0.55Seconds per stroke
delaynumber0Seconds before draw starts
staggernumber0.12Per-stroke delay increment
easingEasing or Easing[]"easeInOut"Motion easing curve
repeatnumber0Extra repetitions. Infinity = loop

Behavior props

PropTypeDefaultNotes
triggerTrigger"hover"When/how the animation fires. See Triggers.
onLeaveOnLeave"complete"What happens when trigger ends. See Leave behavior.
reducedMotionReducedMotion"system"Respect / force / disable reduced-motion. See Accessibility.
modeModeName or ModeFactory"draw"Which animation to play. See Modes.

Escape hatch

PropTypeNotes
variantsVariants or (i: number) => VariantsBypass mode and supply Motion variants directly. See Custom motion.

DOM attributes the engine writes

The rendered <svg> also carries an attribute that the engine owns. It is read-only from a consumer's perspective — passing it as a prop has no effect.

AttributeValuesNotes
data-motion-state"resting" | "drawing"Whether the stroke draw is currently animating. See Motion state.

Type definitions

type Trigger =
  | "hover"
  | "click"
  | "mount"
  | "in-view"
  | "parent-hover"
  | "manual";

type OnLeave = "complete" | "snap" | "redraw";

type ReducedMotion = "system" | "always" | "never";

type MotionState = "resting" | "drawing";

type ModeName = "draw" | "signature";

interface ModeContext {
  iconName: string;
  index: number;
  pathTag: string;                     // "path" | "circle" | "rect" | "line" | …
  pathAttrs: Record<string, string | number>; // the element's attrs (incl. `d`)
  duration: number;
  delay: number;
  stagger: number;
  easing: Easing | Easing[];
  repeat: number;
  pathLength: number;                  // engine-measured, from getTotalLength()
}

type ModeFactory = (ctx: ModeContext) => Variants;

interface ModeDefaults {
  duration?: number;
  delay?: number;
  stagger?: number;
  easing?: Easing | Easing[];
  repeat?: number;
}

interface Mode {
  factory: ModeFactory;
  defaults?: ModeDefaults;
  needsTransformOrigin?: boolean;       // engine sets transform-origin on each child
  transformOrigin?: string;             // override the pivot (default "12px 12px")
}

interface MotionIconHandle {
  play: () => void;
  reset: () => void;
  node: SVGSVGElement | null;
}

type IconNode = [tag: string, attrs: Record<string, string | number>];

All exported from lucide-motion.


MotionIconConfig

React Context provider for app-wide defaults. See App-wide defaults.

interface MotionIconConfigValue {
  size?: number;
  color?: string;
  strokeWidth?: number;
  absoluteStrokeWidth?: boolean;
  duration?: number;
  delay?: number;
  stagger?: number;
  easing?: Easing | Easing[];
  repeat?: number;
  trigger?: Trigger;
  onLeave?: OnLeave;
  reducedMotion?: ReducedMotion;
  mode?: ModeName | ModeFactory;
}

function MotionIconConfig(
  props: MotionIconConfigValue & { children: ReactNode }
): JSX.Element;

Other exports

import {
  DrawIcon,            // The animated SVG primitive every icon wraps.
  MotionIconConfig,    // Context provider for defaults.
  PARENT_HOVER_ATTR,   // = "data-motion-icon-group"
  type DrawIconProps,
  type IconNode,
  type Mode,
  type ModeContext,
  type ModeDefaults,
  type ModeFactory,
  type ModeName,
  type MotionIconConfigValue,
  type MotionIconHandle,
  type MotionState,
  type OnLeave,
  type ReducedMotion,
  type Trigger,
} from "lucide-motion";

Manifest

The package publishes a metadata list of every icon under the lucide-motion/manifest subpath. It's handy for building galleries, search, or your own "icons with signatures" filters — it carries no React/Motion code, just data.

import { manifest, type ManifestEntry } from "lucide-motion/manifest";

interface ManifestEntry {
  name: string;                 // lucide kebab name, e.g. "message-circle-dashed"
  component: string;            // PascalCase export name, e.g. "MessageCircleDashed"
  tags: readonly string[];      // lucide search/category tags
  hasSignature: boolean;        // true if mode="signature" plays a bespoke animation
                                // (false → it falls back to mode="draw")
}

const manifest: ManifestEntry[];
// Example: list only the icons that ship a bespoke signature.
import { manifest } from "lucide-motion/manifest";

const signed = manifest.filter((m) => m.hasSignature);

hasSignature is the same field the docs and gallery use to count and filter signed icons. Because it lives on the manifest, your filter stays correct automatically as signatures are added in future releases.

On this page