<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/morphicons-any-stroke-icon-morphs-into-any-other-b5tw4mfuj" -->

---
title: Morphicons: Any stroke icon morphs into any other
description: Morphicons is a new open-source library that morphs any stroke icon into any other by simply changing a prop, with no manual rotation groups or from/to pairs...
canonical: https://daily.dev/posts/morphicons-any-stroke-icon-morphs-into-any-other-b5tw4mfuj
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Morphicons: Any stroke icon morphs into any other | daily.dev
og:description: Morphicons is a new open-source library that morphs any stroke icon into any other by simply changing a prop, with no manual rotation groups or from/to pairs...
og:url: https://daily.dev/posts/morphicons-any-stroke-icon-morphs-into-any-other-b5tw4mfuj
og:image: https://api.daily.dev/og/posts/b5tW4mfuj.png
og:image:alt: Morphicons: Any stroke icon morphs into any other
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Morphicons: Any stroke icon morphs into any other

**[Open Source](https://daily.dev/sources/opensourcesquad)** · [@guillermolg](https://daily.dev/guillermolg) · 2 min read · 37 upvotes · 7 comments

## Summary

Morphicons is a new open-source library that morphs any stroke icon into any other by simply changing a prop, with no manual rotation groups or from/to pairs needed. It solves the optimal 2D similarity (Procrustes) between shapes and interpolates in polar space, so rotations emerge naturally rather than being hand-declared. It supports uncontrolled, controlled, and imperative modes, handles mid-flight interruptions with spring velocity preservation, renders clean SSR with zero flash, and respects prefers-reduced-motion. It's drop-in compatible with Lucide, Tabler, Heroicons, Iconoir, and shadcn icon sets as long as icons share a 24x24 grid. MIT licensed, zero runtime deps, 7.65 KB gzip for the React entry.

## Content

[morphicons ](https://www.morphicons.com)

I got tired of icon morphs that either need a hand-declared "rotation group" per pair, or interpolate raw coordinates and shear the shape in transit. So I built morphicons.

The whole API is: change the prop.

```
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>
```

No wrappers, no `AnimatePresence`, no keys, no from/to pairs, no config. State lives outside; the animation is an implementation detail the component picks up when the prop changes.

Three modes if you need them: uncontrolled (above), controlled (`from`/`to` + `progress`, for gestures/scroll) and imperative (`ref.morphTo()` / `ref.set()`).

What I actually care about:

- **Rotations emerge.** It solves the optimal 2D similarity between the two shapes (Procrustes) and interpolates in polar space. arrow-right → arrow-down gives θ = 90° on its own. plus → x gives 45°. Nobody declares that anywhere.
- **Real interruptions.** A `morphTo` mid-flight re-plans from the current intermediate shape and preserves the spring's velocity. Click spam never jumps.
- **Clean SSR.** The server emits the exact static SVG — zero flash, zero layout shift. The runtime is born on hydration.
- **Drop-in for lucide-react**: `size`, `strokeWidth`, `absoluteStrokeWidth`, `color`, `className` and the rest of the svg props pass through. `aria-hidden` by default, `label` → `role="img"` + `<title>`. `prefers-reduced-motion` degrades to an instant swap.
- One global rAF for every instance on the page.

Works with Lucide, Tabler, Heroicons (outline), Iconoir and the shadcn icon registry — no per-library adapters, because it just eats a `d` string or Lucide's `[tag, attrs][]` shape. Requirement is that the icons are stroke-drawn on a shared grid (all of the above are 24×24); off-grid packs go through `fitIcon(icon, 32)` once at module scope.

MIT, zero runtime deps, ESM, 7.65 KB gzip for the React entry (react external). React >= 18 as optional peer.

Playground with a scrubber so you can freeze any morph mid-flight: https://www.morphicons.com

Repo: [https://github.com/guillermolg00/morphicons](https://repo)

## Community discussion

Top comments from developers on daily.dev.

**@abdullahmukadam87** · 2 upvotes

> There is a typo mistake in GitHub url

**@agustinbarrientos** · 1 upvotes

> I could lose an afternoon judging icon transitions at exactly 43 percent

**@sauvage1212** · 1 upvotes

> Amazing function **and** a nice looking website :).

---

Tags: [#react](https://daily.dev/tags/react)

[View this post on daily.dev](https://daily.dev/posts/morphicons-any-stroke-icon-morphs-into-any-other-b5tw4mfuj)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"DiscussionForumPosting","mainEntityOfPage":"https://daily.dev/posts/morphicons-any-stroke-icon-morphs-into-any-other-b5tw4mfuj","headline":"Morphicons: Any stroke icon morphs into any other","text":"Morphicons is a new open-source library that morphs any stroke icon into any other by simply changing a prop, with no manual rotation groups or from/to pairs needed. It solves the optimal 2D similarity (Procrustes) between shapes and interpolates in polar space, so rotations emerge naturally rather than being hand-declared. It supports uncontrolled, controlled, and imperative modes, handles mid-flight interruptions with spring velocity preservation, renders clean SSR with zero flash, and respects prefers-reduced-motion. It's drop-in compatible with Lucide, Tabler, Heroicons, Iconoir, and shadcn icon sets as long as icons share a 24x24 grid. MIT licensed, zero runtime deps, 7.65 KB gzip for the React entry.","url":"https://daily.dev/posts/morphicons-any-stroke-icon-morphs-into-any-other-b5tw4mfuj","datePublished":"2026-08-13T17:52:05.757Z","dateModified":"2026-09-13T20:56:14.960Z","author":{"@type":"Person","name":"Guillermo López","url":"https://daily.dev/guillermolg","image":"https://avatars.githubusercontent.com/u/85084558?v=4","description":"Full Stack developer","interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"EndorseAction"},"userInteractionCount":780}},"image":"https://media.daily.dev/image/upload/s--UZB3peNz--/f_auto/v1785598516/posts/pY4P9NQck?_a=BAMAMicg0","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":37},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":7}],"comment":[{"@type":"Comment","text":"There is a typo mistake in GitHub url","datePublished":"2026-08-13T18:46:49.186Z","url":"https://daily.dev/posts/b5tW4mfuj#c-5DKsCfiAv","author":{"@type":"Person","name":"Abdullah Mukadam","url":"https://daily.dev/abdullahmukadam87","image":"https://lh3.googleusercontent.com/a/ACg8ocJ1YFIDSsJwf9YgilT4b0EcTcjOPRRxtGg8utbxrsEIH01pc-g=s96-c"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":2}},{"@type":"Comment","text":"I could lose an afternoon judging icon transitions at exactly 43 percent","datePublished":"2026-08-13T21:19:34.716Z","url":"https://daily.dev/posts/b5tW4mfuj#c-PQqOb5ZoV","author":{"@type":"Person","name":"Agustin Barrientos","url":"https://daily.dev/agustinbarrientos","image":"https://media.daily.dev/image/upload/s--5ayxQnqn--/f_auto/v1788281802/avatars/avatar_wQYYVe5Tbj0NJ7C7qPoa8?_a=BAMAMicg0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1}},{"@type":"Comment","text":"Amazing function and a nice looking website :).","datePublished":"2026-08-16T08:13:30.940Z","url":"https://daily.dev/posts/b5tW4mfuj#c-C4EwOt34h","author":{"@type":"Person","name":"Rory","url":"https://daily.dev/sauvage1212","image":"https://media.daily.dev/image/upload/s--j71P-rBC--/f_auto/v1776346177/avatars/avatar_oBC5XDv8Ueai4jqTDjWDn?_a=BAMAMiWQ0"},"interactionStatistic":{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1}}],"isPartOf":{"@type":"WebPage","url":"https://daily.dev/squads/opensourcesquad","name":"Open Source"}}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Open Source","item":"https://daily.dev/squads/opensourcesquad"},{"@type":"ListItem","position":3,"name":"Morphicons: Any stroke icon morphs into any other"}]}
```

