The problem: buttons that feel dead
If you build with Lucide like I do, your icons look clean — and do absolutely nothing.
Hover a button, click a tab, and the icon just sits there. It's a small thing, but it's the kind of small thing that makes an interface feel static.
PulsoIcon is what happens when someone decides every icon deserves its own motion.
Not one generic hover effect stamped onto everything — a motion written for that specific icon.
The bell rings. The trash can opens its lid. The clock's hand goes around.
What it is
- 9,955 animated icons, each with a hand-written motion.
- Five platforms from one source: React, Vue, Svelte, Jetpack Compose, and SwiftUI.
- About 3,700 custom-drawn icons, including approximately 2,770 line-art brand logos. The rest build on Lucide, Tabler, and Iconoir shapes, all credited in the LICENSE.
- Automatic hover and focus animations: Icons respond when you hover over or focus on the nearest interactive button, link, or tab.
- Accessibility built in: Animations respect the user's
prefers-reduced-motionsystem setting.
You can browse and try all the icons live here:
Explore the PulsoIcon Playground
The part that sold me: it's a one-line switch
The React package is designed as a drop-in replacement for lucide-react.
Same component names. Same props.
Before:
import { Bell, Trash2 } from "lucide-react"; After:
import { Bell, Trash2 } from "pulsoicon-react"; That's the whole migration for most components.
Your existing size, color, and strokeWidth props keep working.
No need to manually write animation code for every icon.
How it's built (for the curious)
Every icon is defined in a single data file within a core package.
Each file contains the icon's shapes and optional motion settings for individual shapes:
- 36 motion recipes, including draw, swing, lift, and more.
- Delay, controlling when the animation begins.
- Direction, determining how elements move.
- Amplitude, controlling the intensity of the motion.
- Pivot points, defining where a shape rotates or transforms on the 24×24 grid.
A generator takes this single source and produces packages for all five supported frameworks:
- React
- Vue
- Svelte
- Jetpack Compose
- SwiftUI
Browser tests also run icons side by side in React, Vue, and Svelte to help verify that animations behave consistently across frameworks.
Open source on GitHub
CityPulso / PulsoIcon
Animated React icons — every Lucide icon plus extra icons and brand logos, each with its own hand-written motion. Drop-in replacement for lucide-react, built on Motion.
PulsoIcon
9955 animated icons. Every one has its own motion.
For React, Vue, Svelte, Jetpack Compose and SwiftUI. Icons come alive on hover; in React they replace lucide-react in one line
pulsoicon.com: browse all icons, try them live and copy the code · Playground · Documentation
Docs: React · Vue · Svelte · Android (Compose) · iOS / macOS (SwiftUI) · Core data
A bell rings. A calendar lifts its rings. A trash can opens its lid. A clock's hand goes round.
PulsoIcon gives every icon a motion written for that icon, not one effect stamped on all of them. At rest each icon is a clean 24×24 icon; it plays when someone hovers or focuses the button, link or tab it sits in.
Every one of the 9955 motions is written for this set. About 3,700 icons are drawn here, including the line-art brand logos; the rest build…
The project is available under the ISC License.
Current limitations
There are a couple of things worth mentioning:
- Web packages are the most polished. React, Vue, and Svelte have received the most refinement. The Jetpack Compose and SwiftUI ports are newer.
- Animation quality can vary. With 9,955 individually tuned motions, some animations naturally feel better than others.
If you find an icon whose animation feels unnatural or doesn't match its meaning, opening an issue with the specific icon name would be genuinely helpful.
Verdict
If your UI already uses Lucide and feels more static than you'd like, PulsoIcon offers a straightforward way to introduce meaningful micro-interactions.
For many React components, all it takes is changing one import statement.
No complex animation setup. No manually defining hover effects for hundreds of icons.
Just icons that respond to the interface around them.
Try it yourself:
- Playground: https://pulsoicon.com
- GitHub: https://github.com/CityPulso/PulsoIcon
I'd love your feedback
Two things I'm especially interested in:
Does the parent-hover animation model fit your workflow? Would you prefer icons to animate automatically when hovering over their parent button, or would you rather control animation triggers manually?
Which icon animations feel wrong? If you notice an animation that seems unnatural, distracting, or inconsistent with the icon's meaning, I'd love to know which one.
And if you try the playground, let me know which icon's animation is your favorite.
Mine's the trash can. 🗑️


