Any icon morphs into any other.
Optimal rotation solved in closed form, spring physics, and zero dependencies. Your icon library already works.
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. 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, 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