📈 GH Trending Explorer 🎲 Surprise me

← all repos

guillermolg00 / morphicons

git clone https://github.com/guillermolg00/morphicons.git v2.0.0 · 7d ago

Any icon morphs into any other — universal morphing for stroke-based icons with spring physics. Zero dependencies, ~7 KB gzip.

+14
stars, 24h · #2,494
+~103
stars, 7 days · #2,066
+~440
stars, 30 days · #1,850
2.9k
★ total · +4% this week
88
forks · 8 open issues

Star history (as recorded here)

2026-10-20 · 2,897 ★ 2026-10-23 · 2,941 ★
LanguageTypeScript
LicenseMIT
Created2026-08-01 (2mo ago)
Last push3d ago
Watchers6
OwnerUser

GitHub topics

Links

README excerpt
morphicons 
 morphicons.com — live playground
Morph any SVG icon into any other, stroked or filled, with spring physics. Lucide, Tabler, Heroicons, Material Symbols, Phosphor or your own paths. Zero runtime dependencies.
 [code] 
Change the prop and the icon morphs. Nothing to configure.
## Install
 [code] 
Icons are **data**: an `IconNode` (Lucide's format) or a `d` string. For Lucide, import from `lucide`, not `lucide-react`.
| entry | |
|---|---|
| `morphicons/react` · `vue` · `svelte` · `react-native` | ` ` (the framework peer is optional) |
| `morphicons/astro` · `element` | Astro component · ` ` for plain HTML |
| `morphicons/dom` | `createMorph()`, no framework |
| `morphicons/adapters` | `svgToIcon`, `maskTarget`, `canvasTarget` |
| `morphicons` | the pure core, no DOM |
## Usage
Three modes, the same in every binding:
 [code] 
| prop | |
|---|---|
| `size`, `color`, `strokeWidth`, `absoluteStrokeWidth` | as in lucide-react; other ` ` attributes pass through |
| `spring` | `"snappy"` (default), `"smooth"`, `"bouncy"` or `{ stiffness, damping }` |
| `reducedMotion` | `"never"` (default), `"user"` (follow the OS) or `"always"` |
| `label` | accessible name; without it the icon is `aria-hidden` |
SSR renders the final SVG, so nothing flashes on hydration.
### Lifecycle contract
- Mounting without an icon is fine; the first one appears without animating.
- While `from` and `to` are set, they win over `icon`.
- Leaving controlled mode and coming back renders like a fresh mount.
### Other frameworks
 [code] 
 [code] 
React Native has the React API (it needs Metro with package `exports`, the default since 0.79). Astro renders the SVG on the server and upgrades it to a ` ` element in the browser. In plain HTML, use the element directly:
 [code] 
Without a framework:
 [code] 
## Fill icons
When either icon is filled, both morph as filled shapes. The code for that (5.4 KB gzip) loads the first time a filled icon shows up; stroke-only apps never download it. To bundle it instead:
 [code] 
Or call `preloadRegion()` early to fetch it before the first morph. For long lists of filled icons on low-end devices, run `toRegion(icon)` from `morphicons/region` at build time: the driver uses its output as is, with no normalization at runtime.
## Format adapters
- `svgToIcon(markup)`: SVG markup (an Iconify body, a full ` `) to an icon.
- `maskTarget(el)`: morphs CSS-mask icons in place (UnoCSS, Tailwind icon plugins).
- `canvasTarget(canvas)`: draws the morph into a canvas or 2D context.
 [code] 
`maskTarget` and `canvasTarget` draw strokes only.
## Icon library compatibility
Any set on a 24×24 grid works as is. For other grids, use `fitIcon(icon, 32)` from `morphicons`, or `svgToIcon`, which reads the `viewBox`.
## How it works
For each pair of shapes, morphicons solves the rotation, scale and translation that best map one onto the other, in closed form, and interpolates each separately. Two icons that are the same shape rotated simply rotate. Details in docs