Package Exports
- motion-icons-react
- motion-icons-react/style.css
Readme
Motion Icons React
Animations without animation complexity.
No framer-motion boilerplate. No variants. Just props.
The Problem
Animating icons in React is annoyingly repetitive:
// With framer-motion - too much boilerplate
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0, rotate: 360 }}
transition={{ duration: 1 }}
>
<Bell />
</motion.div>The Solution
<MotionIcon name="Bell" animation="spin" entrance="fadeInUp" />One line. No wrappers. No complexity.
✨ Features
- 3500+ icons through Lucide React
- 15+ preset animations ready to use
- Entrance effects for eye-catching reveals
- Interactive states built-in (hover, click, focus)
- Accessible - respects
prefers-reduced-motion - Lightweight - ~5KB (minimal bundle impact)
- TypeScript - full type safety included
- Declarative API - just props, no complexity
Quick Start
Installation
npm install motion-icons-react lucide-reactBasic Usage
import { MotionIcon } from 'motion-icons-react';
import 'motion-icons-react/style.css';
// Minimal (1 prop)
<MotionIcon name="Heart" animation="pulse" />
// With entrance
<MotionIcon name="Bell" entrance="fadeInUp" />
// Interactive hover
<MotionIcon name="ThumbsUp" animation="bounce" trigger="hover" interactive />All props are optional except name. Defaults are subtle and production-friendly.
Why Motion Icons?
vs Framer Motion
| Framer Motion (12 lines) | Motion Icons (1 line) |
|---|---|
<motion.div
animate={{ rotate: 360 }}
transition={{
duration: 1,
repeat: Infinity,
ease: "linear"
}}
>
<Loader2 size={20} />
</motion.div> |
<MotionIcon
name="Loader2"
animation="spin"
size={20}
/> |
Motion Icons React:
- ✅ One line, no wrappers
- ✅ 15+ preset animations
- ✅ ~5KB bundle size
- ✅ Declarative API
Framer Motion:
- ❌ Wrapper div required
- ❌ Manual animation curves
- ❌ ~30KB bundle size
- ❌ Imperative API
When to use what
Use Motion Icons for animated icons (loading, notifications, buttons)
Use Framer Motion for complex layouts and page transitions
Props by Category
Core Props
name(required) - Lucide icon namesize(24) - Icon size in pixelscolor("currentColor") - Icon colorweight("regular") - Stroke weight: light, regular, bold
Animation Props
animation("none") - Main animation typeentrance(null) - Entrance animationtrigger("always") - When to animate: always, hover, click, focus
Timing Props
animationDuration(1000) - Duration in millisecondsanimationDelay(0) - Delay in milliseconds
Interaction Props
interactive(false) - Enable hover/focus statesonClick- Click handleronMouseEnter/onMouseLeave- Hover handlers
Accessibility Props
aria-label- Screen reader labelrole- ARIA role
Available Animations
Main Animations: pulse, spin, bounce, ping, wiggle, flip, heartbeat, shake, swing, tada, rubber
Entrance Animations: fadeIn, fadeInUp, fadeInDown, fadeInLeft, fadeInRight, scaleIn, slideInUp, slideInDown, rotateIn, zoomIn
See all animations in action →
Recipes
Like Button
const [isLiked, setIsLiked] = useState(false);
<MotionIcon
name="Heart"
animation={isLiked ? "heartbeat" : "none"}
trigger="always"
color={isLiked ? "#ef4444" : "#6b7280"}
onClick={() => setIsLiked(!isLiked)}
interactive
/>Loading Button
<button disabled={isLoading}>
{isLoading && <MotionIcon name="Loader2" animation="spin" size={16} />}
{isLoading ? "Submitting..." : "Submit"}
</button>Notification Badge
<MotionIcon
name="Bell"
animation={hasNotifications ? "wiggle" : "none"}
trigger="always"
interactive
/>Search Input
<MotionIcon
name={isSearching ? "Loader2" : "}
animation={isSearching ? "spin" : "none"}
size={16}
/>Success Toast
<MotionIcon
name="CheckCircle"
entrance="zoomIn"
animation="tada"
color="#10b981"
/>Advanced Usage
What's New in v1.0.3
🐛 Critical Bug Fix: Animations now work correctly in Next.js with Tailwind CSS!
Previous versions had animations that appeared static in Next.js applications due to CSS conflicts with Tailwind utility classes. This has been completely resolved.
Changes:
- Fixed Tailwind CSS conflicts that prevented animations from working
- Improved SSR hydration for Next.js compatibility
- Enhanced animation visibility (more dramatic effects)
- Better trigger handling for
trigger="always"
To update:
Upgrading from v1.0.2 or earlier?
npm install motion-icons-react@latest
rm -rf .next # Clear Next.js cache
npm run devAccessibility
Motion Icons automatically respects user preferences:
prefers-reduced-motion- Animations are disabled if the user has motion reduction enabled- Semantic HTML - Proper ARIA attributes
- Keyboard support - Focus states work with
trigger="focus"
Development
Local Setup
git clone https://github.com/Garvit1000/motion-icons.git
cd motion-icons
npm install
npm run devTesting Locally
npm run build
npm link
# In your test project
npm link motion-icons-reactContributing
We'd love your help! Here's how:
In your test project
yarn link motion-icons-react
#### bun
```bash
# In the package directory
bun run build
bun link
# In your test project
bun link motion-icons-reactContributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request