281 animated SVG icons for React. Hover and imperative triggers, configurable size, color, and duration. Built on motion/react.
Pick one of the two paths below. Both ship the same icons and the same API — the only difference is whether you depend on the package or own the source.
Recommended for most apps. One install, all 281 icons available.
1. Install the package — motion is bundled, no separate install needed.
pnpm add @animateicons/react2. Import an icon — Lucide and Huge are exposed as scoped subpaths because some icon names overlap (HeartIcon, CopyIcon, etc.).
import { BellRingIcon } from "@animateicons/react/lucide";
export function Notifications() {
return <BellRingIcon size={24} color="#f45b48" />;
}That's it — the icon animates on hover by default.
Use this if you want each icon copied into your codebase as a single file you can edit.
1. Set up shadcn — if your project doesn't have it yet, follow the shadcn installation guide.
2. Add an icon — browse the Lucide or Huge gallery, click any tile to copy its install command, or replace lu-bell-ring below with the icon you want.
pnpm dlx shadcn@latest add https://animateicons.in/r/lu-bell-ring.jsonThe icon lands at components/ui/<name>.tsx.
3. Import and use
import { BellRingIcon } from "@/components/ui/bell-ring";
export function Notifications() {
return <BellRingIcon size={24} color="#f45b48" />;
}Every icon strokes currentColor, so it inherits the surrounding text color. You can also pass color, className, or use the duration and isAnimated props to control playback.
// Color — sets currentColor inline
<EyeIcon color="#f45b48" />
// Tailwind utility — works because icons stroke="currentColor"
<EyeIcon className="text-primary" />
// Speed — duration is a multiplier (lower = faster)
<EyeIcon duration={0.6} />
// Disable hover animation
<EyeIcon isAnimated={false} />Need to trigger an animation from a parent — on click, on focus, or programmatically? Pass a ref. Each icon exports its own *Handle type.
"use client";
import { useRef } from "react";
import { EyeIcon, type EyeIconHandle } from "@/components/ui/eye";
export function Demo() {
const ref = useRef<EyeIconHandle>(null);
return (
<button
onMouseEnter={() => ref.current?.startAnimation()}
onMouseLeave={() => ref.current?.stopAnimation()}
>
<EyeIcon ref={ref} size={28} />
</button>
);
}interface IconProps {
size?: number;
color?: string;
className?: string;
duration?: number;
isAnimated?: boolean;
onMouseEnter?: (e: React.MouseEvent<HTMLDivElement>) => void;
onMouseLeave?: (e: React.MouseEvent<HTMLDivElement>) => void;
style?: React.CSSProperties;
}
interface IconHandle {
startAnimation: () => void;
stopAnimation: () => void;
}Animations respect the OS-level Reduce Motion preference — no extra setup required.
animateicons/
├── icons/
│ ├── lucide/ 248 Lucide-style icons
│ └── huge/ 33 Huge-style icons
├── npm/ @animateicons/react published package
├── app/
│ ├── icons/[library]/ gallery routes
│ └── icons/docs/ install guide (MDX)
├── components/ shared UI (Hero, Section, etc.)
├── hooks/ useIconFilter, useIconAnimation
├── tests/ Vitest + React Testing Library
└── scripts/ registry codegen, codemods
git clone https://github.com/Avijit07x/animateicons.git
cd animateicons
pnpm install
pnpm devCommon scripts:
pnpm dev # gallery dev server (Turbopack)
pnpm build # production build
pnpm test # vitest run
pnpm typecheck # tsc --noEmit
pnpm --filter @animateicons/react build # build the npm package
pnpm --filter @animateicons/react test:smoke # smoke-test the built distPRs adding icons are welcome. Each icon is a single React component file — copy any existing one as a template.
- Create
icons/<library>/<name>-icon.tsxfrom an existing icon - Register it in
icons/<library>/index.ts - Run
pnpm gen:iconsto regenerate the public registry - Open a PR against
dev
Full workflow in CONTRIBUTING.md.
MIT.
If AnimateIcons saves you time, consider sponsoring the project.
Built with Next.js, motion/react, and shadcn/ui.