Get your first animated icon working in under 5 minutes. This guide assumes you already have a React project set up with shadcn/ui .
Don’t have shadcn/ui installed yet? Check out the Installation guide first.
Add Your First Icon
Install an icon component
Use the shadcn CLI to install your first animated icon. Let’s start with the Heart icon: npx shadcn@latest add https://anicon.dev/r/icon-heart.json
This installs the icon component and the motion dependency if needed.
Import the icon in your component
Import the icon component in your React file: import { IconHeart } from "@/components/ui/icon-heart"
Use the icon
Add the icon to your JSX. Try hovering over it to see the animation! export default function MyComponent () {
return (
< div >
< h1 > My Animated Icon </ h1 >
< IconHeart size = { 32 } className = "text-rose-500" />
</ div >
)
}
See it in action
Run your development server and hover over the heart icon. You’ll see it scale up smoothly! The icon automatically respects the user’s motion preferences and will disable animations if they have prefers-reduced-motion enabled.
Complete Example
Here’s a complete working example using multiple icons:
import { IconHeart } from "@/components/ui/icon-heart"
import { IconBell } from "@/components/ui/icon-bell"
import { IconStar } from "@/components/ui/icon-star"
export default function Dashboard () {
return (
< div className = "flex gap-4 p-8" >
< button className = "flex items-center gap-2 px-4 py-2 rounded-lg bg-rose-500 text-white hover:bg-rose-600" >
< IconHeart size = { 20 } />
< span > Like </ span >
</ button >
< button className = "flex items-center gap-2 px-4 py-2 rounded-lg bg-blue-500 text-white hover:bg-blue-600" >
< IconBell size = { 20 } />
< span > Notifications </ span >
</ button >
< button className = "flex items-center gap-2 px-4 py-2 rounded-lg bg-amber-500 text-white hover:bg-amber-600" >
< IconStar size = { 20 } />
< span > Favorite </ span >
</ button >
</ div >
)
}
Icon Props
All Anicon components accept these common props:
The width and height of the icon in pixels
The stroke width of the icon paths
CSS classes to apply to the icon (e.g., Tailwind classes)
...props
React.SVGProps<SVGSVGElement>
All standard SVG attributes are supported (onClick, onMouseEnter, style, etc.)
Customization Examples
Custom Size
Custom Colors
< IconHeart className = "text-rose-500" />
< IconBell className = "text-blue-600" />
< IconStar className = "text-amber-400" />
Custom Stroke Width
< IconHeart strokeWidth = { 3 } />
Click Handlers
< IconHeart
onClick = { () => console . log ( 'Heart clicked!' ) }
className = "cursor-pointer"
/>
Understanding the Icon Component
Let’s look at what makes these icons special. Here’s a simplified version of the Heart icon:
import { motion , useReducedMotion } from "framer-motion"
export function IconHeart ({ size = 24 , strokeWidth = 2 , className , ... props }) {
const prefersReducedMotion = useReducedMotion ()
return (
< motion.svg
width = { size }
height = { size }
viewBox = "0 0 24 24"
fill = "none"
stroke = "currentColor"
strokeWidth = { strokeWidth }
initial = { prefersReducedMotion ? false : "rest" }
whileHover = { prefersReducedMotion ? undefined : "hover" }
variants = { {
rest: { scale: 1 },
hover: {
scale: 1.1 ,
transition: { duration: 0.5 , repeat: Infinity , repeatType: "reverse" }
}
} }
className = { className }
{ ... props }
>
< path d = "M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z" />
</ motion.svg >
)
}
Motion Variants - The icon uses Motion’s variant system to define different animation states (rest and hover).Accessibility - The useReducedMotion() hook detects user preferences and disables animations when needed.TypeScript - Full type safety with proper prop types for size, strokeWidth, and all SVG attributes.Customization - Accepts all standard React and SVG props, making it fully customizable.
Animation Customization
Want to customize the animation behavior? You can override the default variants:
< motion.div
whileHover = { { scale: 1.2 } }
whileTap = { { scale: 0.95 } }
>
< IconHeart />
</ motion.div >
Or create your own animated wrapper:
import { motion } from "framer-motion"
< motion.button
whileHover = { { rotate: 15 } }
whileTap = { { rotate: - 15 } }
className = "p-2"
>
< IconStar size = { 24 } />
</ motion.button >
Common Patterns
function IconButton ({ icon : Icon , label , onClick }) {
return (
< button
onClick = { onClick }
className = "flex items-center gap-2 px-4 py-2 rounded-lg bg-gray-100 hover:bg-gray-200"
aria-label = { label }
>
< Icon size = { 20 } />
< span > { label } </ span >
</ button >
)
}
// Usage
< IconButton icon = { IconHeart } label = "Like" onClick = { handleLike } />
Icon with Label
< div className = "flex items-center gap-2" >
< IconBell size = { 16 } className = "text-blue-500" />
< span className = "text-sm" > 3 new notifications </ span >
</ div >
Icon Grid
const icons = [ IconHeart , IconBell , IconStar , IconHome , IconSettings ]
< div className = "grid grid-cols-5 gap-4" >
{ icons . map (( Icon , i ) => (
< Icon key = { i } size = { 32 } className = "text-gray-700" />
)) }
</ div >
Next Steps
Now that you have your first animated icon working, explore more:
Browse All Icons Explore all 572+ animated icons
Customization Learn how to customize size, color, and stroke
Animation Config Dive into animation variants and transitions
Accessibility Learn about reduced motion and ARIA support