Lucide Motion

Accessibility

Respect the OS prefers-reduced-motion setting.

The reducedMotion prop controls how the library responds to the user's OS-level reduced-motion preference (prefers-reduced-motion: reduce). Default is "system", which respects the OS setting.

Three modes

<Heart reducedMotion="system" />   // default — respect OS setting
<Heart reducedMotion="always" />   // force animation off
<Heart reducedMotion="never" />    // force animation on (use carefully)
"system" (default)
"always"
"never"

How it works

When reduced motion is active (either by OS setting with "system", or by the "always" override):

  • All trigger effects (mount, in-view, parent-hover) become no-ops
  • hover and click triggers don't fire their animation
  • The icon renders in its rest state — fully drawn, identical to a static lucide-react icon

The component is functionally identical to a static SVG icon in this mode. Layout, sizing, colors, and click handlers all still work.

Testing it

macOS — System Settings → Accessibility → Display → "Reduce motion"

Windows — Settings → Accessibility → Visual effects → Animation effects → Off

iOS — Settings → Accessibility → Motion → Reduce Motion

Chrome DevTools — Open DevTools → Rendering panel (⌘⇧P → "Show Rendering") → Emulate CSS media feature → prefers-reduced-motion: reduce

After toggling, refresh the page. The "system" and "always" demos above should now be static; the "never" demo still animates on hover.

App-wide

Set it once via the <MotionIconConfig> provider:

<MotionIconConfig reducedMotion="system">
  <App />
</MotionIconConfig>

Or override globally to keep animations on for an internal tool where you've validated motion is fine:

<MotionIconConfig reducedMotion="never">
  <App />
</MotionIconConfig>

Use 'never' sparingly

Overriding the OS preference disrespects an explicit accessibility choice your user made. Default to "system" unless you have a specific reason.

On this page