Lucide Animated icons are fully integrated with the shadcn/ui ecosystem. You can install individual icons using the shadcn CLI, just like any other shadcn component.
Installation via shadcn CLI
Use the shadcn CLI to add icons to your project. Icons are installed as components in your components/ui directory:
npx shadcn@latest add https://lucide-animated.com/r/heart
This downloads the HeartIcon component and adds it to components/ui/heart.tsx in your project.
Installing Multiple Icons
You can install multiple icons at once:
npx shadcn@latest add https://lucide-animated.com/r/heart
npx shadcn@latest add https://lucide-animated.com/r/bell
npx shadcn@latest add https://lucide-animated.com/r/check
npx shadcn@latest add https://lucide-animated.com/r/activity
Registry Structure
Lucide Animated uses the standard shadcn registry format. Here’s how icons are defined in the registry:
{
"$schema" : "https://ui.shadcn.com/schema/registry.json" ,
"name" : "lucide-animated" ,
"homepage" : "https://lucide-animated.com" ,
"items" : [
{
"name" : "heart" ,
"type" : "registry:ui" ,
"registryDependencies" : [],
"dependencies" : [ "motion" ],
"devDependencies" : [],
"files" : [
{
"path" : "heart.tsx" ,
"type" : "registry:ui"
}
]
},
{
"name" : "bell" ,
"type" : "registry:ui" ,
"registryDependencies" : [],
"dependencies" : [ "motion" ],
"devDependencies" : [],
"files" : [
{
"path" : "bell.tsx" ,
"type" : "registry:ui"
}
]
},
{
"name" : "check" ,
"type" : "registry:ui" ,
"registryDependencies" : [],
"dependencies" : [ "motion" ],
"devDependencies" : [],
"files" : [
{
"path" : "check.tsx" ,
"type" : "registry:ui"
}
]
}
]
}
Dependencies
All icons have a single dependency: motion (Motion for React). The shadcn CLI automatically installs this when you add an icon:
Or if using pnpm, yarn, or bun:
pnpm add motion
yarn add motion
bun add motion
Using Installed Icons
Once installed via shadcn CLI, import icons from your components directory:
import { HeartIcon } from "@/components/ui/heart" ;
import { BellIcon } from "@/components/ui/bell" ;
import { CheckIcon } from "@/components/ui/check" ;
export default function App () {
return (
< div className = "flex gap-4" >
< HeartIcon />
< BellIcon />
< CheckIcon />
</ div >
);
}
Benefits of shadcn Integration
Full Control Icons are copied to your project as source code, giving you complete control to modify animations, styling, and behavior.
No Bundle Bloat Only install the icons you need. Unused icons don’t bloat your bundle.
Type Safety Full TypeScript support with proper types for props and ref handles.
Easy Updates Re-run the CLI command to update an icon to the latest version.
Using in shadcn Components
Lucide Animated icons work seamlessly with shadcn/ui components:
Button Component
Alert Component
Card Component
Toast Component
import { Button } from "@/components/ui/button" ;
import { CheckIcon } from "@/components/ui/check" ;
export default function ActionButton () {
return (
< Button >
< CheckIcon size = { 20 } className = "mr-2" />
Confirm
</ Button >
);
}
Customizing Installed Icons
Since icons are installed as source code, you can freely customize them:
Modify Animation Timing
// Change the animation duration
transition = {{
duration : 0.6 , // Changed from 0.45
repeat : 3 , // Changed from 2
}}
Change Animation Variants
// Customize the rotation animation
const SVG_VARIANTS : Variants = {
normal: { rotate: 0 },
animate: { rotate: [ 0 , - 15 , 15 , - 15 , 0 ] }, // Increased from -10, 10
};
Add Custom Props
interface CheckIconProps extends HTMLAttributes < HTMLDivElement > {
size ?: number ;
color ?: string ; // Add custom prop
animate ?: boolean ; // Add custom prop
}
Version Management
To update an icon to the latest version, simply re-run the CLI command:
npx shadcn@latest add https://lucide-animated.com/r/heart
The CLI will prompt you to overwrite the existing file.
If you’ve made custom modifications to an icon, they will be lost when you update. Consider creating a separate component that wraps the icon if you need custom behavior.
Finding Icon Names
Visit lucide-animated.com to browse all available icons. Each icon page shows the CLI command for installation.
Alternatively, icon names follow the pattern of Lucide icon names in kebab-case:
heart → HeartIcon
bell → BellIcon
check → CheckIcon
arrow-right → ArrowRightIcon
chevron-down → ChevronDownIcon
Complete Example
Here’s a complete example of a component using multiple shadcn components with Lucide Animated icons:
import { useState , useRef } from "react" ;
import { Card , CardContent , CardDescription , CardHeader , CardTitle } from "@/components/ui/card" ;
import { Button } from "@/components/ui/button" ;
import { HeartIcon , HeartIconHandle } from "@/components/ui/heart" ;
import { BellIcon , BellIconHandle } from "@/components/ui/bell" ;
import { CheckIcon } from "@/components/ui/check" ;
export default function SocialCard () {
const [ liked , setLiked ] = useState ( false );
const [ following , setFollowing ] = useState ( false );
const heartRef = useRef < HeartIconHandle >( null );
const bellRef = useRef < BellIconHandle >( null );
const handleLike = () => {
heartRef . current ?. startAnimation ();
setLiked ( ! liked );
};
const handleFollow = () => {
bellRef . current ?. startAnimation ();
setFollowing ( ! following );
};
return (
< Card className = "w-full max-w-md" >
< CardHeader >
< CardTitle className = "flex items-center justify-between" >
< span > Amazing Post </ span >
< button onClick = { handleLike } >
< HeartIcon
ref = { heartRef }
size = { 24 }
className = { liked ? "text-red-500" : "text-gray-400" }
/>
</ button >
</ CardTitle >
< CardDescription > Posted by @username </ CardDescription >
</ CardHeader >
< CardContent className = "space-y-4" >
< p > This is an example of using Lucide Animated icons with shadcn/ui components. </ p >
< div className = "flex gap-2" >
< Button onClick = { handleFollow } variant = { following ? "default" : "outline" } >
{ following ? (
<>
< CheckIcon size = { 16 } className = "mr-2" />
Following
</>
) : (
<>
< BellIcon ref = { bellRef } size = { 16 } className = "mr-2" />
Follow
</>
) }
</ Button >
</ div >
</ CardContent >
</ Card >
);
}