Morph any SVG icon into any other.

Animate Lucide, Tabler, Heroicons or any stroke icon set. Optimal rotation solved in closed form, spring physics, zero dependencies.

Click an icon to add it to your set. Icons from different libraries morph into each other: they all share the 24×24 grid.

import { MorphIcon } from "morphicons/react"; import { Menu, X } from "lucide"; // data, not components <button onClick={() => setOpen(o => !o)} aria-expanded={open}> <MorphIcon icon={open ? X : Menu} /> </button>
That is the whole thing — in React, Vue, Svelte, React Native or Astro (no island needed: the icon upgrades to a web component). No wrappers, no keys, no from/to pairs, no configuration. Swap the pair for any two icons above.

Six kilobytes of math.

morphicons solves the optimal similarity between two shapes in closed form (2D Procrustes): if a pair is congruent under rotation, it rotates; if not, it morphs in the aligned frame. Nobody declares rotation groups by hand. Springs are interruptible, corners stay sharp at rest, and the core never touches the DOM, so React, Vue, Svelte, React Native, Astro, Next.js and plain JavaScript are all first-class drivers.

Icons are consumed as data, not components: a d attribute or Lucide’s IconNode format, structurally typed. No adapters, no per-library setup.

  • core, gzipped, everything included
  • 6.5 KB
  • runtime dependencies
  • 0
  • to plan any morph pair
  • <1 ms
  • shared rAF for every icon on screen
  • 1

core, gzipped, everything included

runtime dependencies

to plan any morph pair

shared rAF for every icon on screen

Works with any stroke icon set — on any grid, via fitIcon.

  • Lucide
  • Tabler
  • Heroicons outline
  • Iconoir
  • Akar
  • Untitled UI
  • Hugeicons
  • shadcn registry