Skip to main content
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

1

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.
2

Import the icon in your component

Import the icon component in your React file:
import { IconHeart } from "@/components/ui/icon-heart"
3

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>
  )
}
4

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:
size
number
default:24
The width and height of the icon in pixels
strokeWidth
number
default:2
The stroke width of the icon paths
className
string
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

<IconHeart size={48} />

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

Icon Button

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

Build docs developers (and LLMs) love