Getting Started
1300+ animated icons with 14 motion types and 4 trigger modes for React.
1Installation
Install LivelyIcons using your package manager of choice:
pnpm add livelyicons
# or
npm install livelyicons
# or
yarn add livelyiconsPeer Dependencies
LivelyIcons requires react >= 18.0.0 and motion >= 11.0.0
2CLI Tool
Use the CLI to search, explore, and quickly copy icons from your terminal:
# Search for icons by name (fuzzy matching)
npx livelyicons search arrow
# List all available icons
npx livelyicons list
# Copy import statement to clipboard
npx livelyicons copy heart
# Get detailed info about an icon
npx livelyicons info settings
# Compact list view
npx livelyicons list --compactsearch
Fuzzy search icons by name. Partial matches work (e.g., "arr" finds "arrow")
list
List all 350+ icons. Use --compact for condensed output
copy
Copy import statement directly to clipboard. Supports kebab-case or PascalCase
info
Get detailed information about a specific icon including file location
3Basic Usage
Import icons individually and use them as React components. Every icon supports lively and trigger props.
import { Heart, Loader, Star } from 'livelyicons'
function App() {
return (
<div>
{/* Default: scale animation on hover */}
<Heart size={24} />
{/* Custom lively type */}
<Star lively="rotate" />
{/* Continuous loop animation */}
<Loader lively="spin" trigger="loop" />
</div>
)
}Default Values
- size—24 pixels
- strokeWidth—2
- lively—"scale"
- trigger—"hover"
4Motion Types
Choose from 14 distinct animation styles using the lively prop:
Hover over icons to see each animation
// 14 lively types available
<Star lively="scale" /> // Grow/shrink (default)
<Settings lively="rotate" /> // Spin rotation
<ArrowRight lively="translate" /> // Slide movement
<Bell lively="shake" /> // Shake/wobble
<Heart lively="pulse" /> // Pulse effect
<Check lively="bounce" /> // Spring bounce
<Eye lively="draw" /> // SVG path draw
<Loader lively="spin" /> // Continuous spin
<Bell lively="ring" /> // Bell swing
<Zap lively="wiggle" /> // Playful wiggle
<Heart lively="heartbeat" /> // Double pulse
<Tag lively="swing" /> // Pendulum swing
<Cloud lively="float" /> // Gentle hover
<Menu lively="none" /> // No animationTransform
scale, rotate, translate, shake
Emphasis
pulse, bounce, heartbeat
Playful
ring, wiggle, swing, float
Special
draw, spin, none
5Trigger Modes
Control when animations play using the trigger prop:
hoverdefaultAnimate on mouse hover
loopContinuous looping animation
mountAnimate once when component mounts
inViewAnimate when scrolled into viewport
// 4 trigger modes
<Heart trigger="hover" /> // On hover (default)
<Heart trigger="loop" /> // Continuous loop
<Heart trigger="mount" /> // Once on mount
<Heart trigger="inView" /> // When scrolled into view6Animation Control
LivelyIcons provides three layers of animation control:
import { IconProvider } from 'livelyicons'
// Disable all animations globally
<IconProvider config={{ animated: false }}>
<App />
</IconProvider>
// Override at component level
<IconProvider config={{ animated: false }}>
<Check /> {/* Static */}
<Heart animated /> {/* Animated - overrides provider */}
</IconProvider>7Accessibility
Icons are decorative by default (aria-hidden="true"). Add meaning with the aria-label prop:
// Decorative icons (default)
<Heart /> {/* aria-hidden="true" */}
// Meaningful icons with labels
<Heart aria-label="Add to favorites" />
<Check aria-label="Task completed" />Animations disable automatically when prefers-reduced-motion is set
Use aria-label for meaningful icons, omit for decorative
8API Reference
Icon Props
| Prop | Type | Default |
|---|---|---|
| size | number | 24 |
| strokeWidth | number | 2 |
| lively | LivelyType | "scale" |
| trigger | TriggerType | "hover" |
| animated | boolean | undefined |
| className | string | undefined |
| aria-label | string | undefined |
LivelyType
"scale" | "rotate" | "translate" | "shake" | "pulse" | "bounce" | "draw" | "spin" | "ring" | "wiggle" | "heartbeat" | "swing" | "float" | "none"TriggerType
"hover" | "loop" | "mount" | "inView"IconProvider Props
| Prop | Type | Default |
|---|---|---|
| config.animated | boolean | true |
| config.defaultSize | number | 24 |
| config.defaultStrokeWidth | number | 2 |
Available Icons
350+ icons available. Browse all icons →
9Migration Guide
Migrating from another icon library? LivelyIcons is designed to be a drop-in replacement with minimal changes required.
Feature Comparison
| Feature | LivelyIcons | Lucide | Heroicons |
|---|---|---|---|
| Built-in Animations | |||
| 14 Motion Types | |||
| Trigger Modes | |||
| Context Provider | |||
| Reduced Motion Support | N/A | N/A | |
| Tree Shakeable |
Lucide ReactNear-identical API
LivelyIcons shares the same API as Lucide React. Change your imports and enjoy animations.
// Before: Lucide React
import { Heart, Star, Settings } from 'lucide-react'
<Heart size={24} strokeWidth={2} />
<Star className="text-yellow-500" />
<Settings onClick={handleClick} />
// After: LivelyIcons (drop-in replacement + animations)
import { Heart, Star, Settings } from 'livelyicons'
<Heart size={24} strokeWidth={2} /> // Works exactly the same
<Star className="text-yellow-500" lively="rotate" /> // Now with animation!
<Settings onClick={handleClick} trigger="hover" /> // Interactive feedbackHeroiconsSize prop conversion
Replace Tailwind size classes with the size prop.
// Before: Heroicons
import { HeartIcon, StarIcon } from '@heroicons/react/24/outline'
<HeartIcon className="h-6 w-6" />
<StarIcon className="h-6 w-6 text-yellow-500" />
// After: LivelyIcons
import { Heart, Star } from 'livelyicons'
<Heart size={24} /> // size prop instead of classes
<Star size={24} className="text-yellow-500" lively="pulse" />React IconsSingle import source
No more importing from different icon packs. All icons from one source.
// Before: React Icons
import { FaHeart, FaStar } from 'react-icons/fa'
import { FiSettings } from 'react-icons/fi'
<FaHeart size={24} />
<FaStar color="gold" />
<FiSettings />
// After: LivelyIcons
import { Heart, Star, Settings } from 'livelyicons'
<Heart size={24} lively="pulse" /> // Built-in animations
<Star className="text-yellow-500" /> // Use className for colors
<Settings lively="rotate" trigger="hover" /> // Interactive rotationFeather IconsAlmost identical
Same prop names, same API. Just swap the import and add animations.
// Before: Feather Icons
import { Heart, Star, Settings } from 'react-feather'
<Heart size={24} strokeWidth={2} />
<Star color="currentColor" />
// After: LivelyIcons (nearly identical API)
import { Heart, Star, Settings } from 'livelyicons'
<Heart size={24} strokeWidth={2} /> // Same props work!
<Star className="text-current" lively="scale" /> // className for colorMigration Checklist
- Update import statements to use
livelyicons - Replace
colorprop withclassName - Convert Tailwind size classes to
sizeprop - Add
livelyandtriggerfor animations - Wrap app in
IconProviderfor global config (optional)
10Framework Examples
LivelyIcons works with any React framework. Here are setup patterns for popular choices.
Next.jsApp Router (React Server Components)
Key insight: Use animated={false} in Server Components for static icons. Wrap interactive icons in Client Components with 'use client'.
// app/layout.tsx - Next.js App Router
// Icons work in both Server and Client Components
// Server Component (default) - static icons only
import { Star, Check } from 'livelyicons'
export default function Layout({ children }) {
return (
<html>
<body>
{/* Static icons render on server */}
<nav>
<Star size={24} animated={false} />
</nav>
{children}
</body>
</html>
)
}
// app/components/InteractiveIcon.tsx
// Client Component - for animations
'use client'
import { Heart } from 'livelyicons'
export function LikeButton() {
return (
<button>
<Heart lively="pulse" trigger="hover" />
</button>
)
}Next.jsPages Router
Standard client-side rendering. Wrap with IconProvider in _app.tsx.
// pages/_app.tsx - Next.js Pages Router
import { IconProvider } from 'livelyicons'
import type { AppProps } from 'next/app'
export default function App({ Component, pageProps }: AppProps) {
return (
<IconProvider config={{ animated: true }}>
<Component {...pageProps} />
</IconProvider>
)
}
// pages/index.tsx
import { Heart, Star, Loader } from 'livelyicons'
export default function Home() {
return (
<div>
<Heart lively="pulse" trigger="hover" />
<Star lively="rotate" />
<Loader lively="spin" trigger="loop" />
</div>
)
}RemixFull-stack React
Add IconProvider in your root layout for app-wide configuration.
// app/root.tsx - Remix
import { IconProvider } from 'livelyicons'
export default function App() {
return (
<html>
<head>
<Meta />
<Links />
</head>
<body>
<IconProvider config={{ animated: true }}>
<Outlet />
</IconProvider>
<Scripts />
</body>
</html>
)
}
// app/routes/_index.tsx
import { Heart, Star } from 'livelyicons'
export default function Index() {
return (
<div>
<Heart lively="pulse" />
<Star lively="scale" trigger="hover" />
</div>
)
}AstroIsland Architecture
Key insight: Use client:load directive for interactive icons. Static icons can render without JavaScript.
---
// src/components/AnimatedIcon.tsx
// Use client:load for interactive icons
---
// AnimatedIcon.tsx (React component)
import { Heart } from 'livelyicons'
export function AnimatedHeart() {
return <Heart lively="pulse" trigger="hover" />
}
// src/pages/index.astro
---
import { AnimatedHeart } from '../components/AnimatedIcon'
import { Star } from 'livelyicons'
---
<html>
<body>
<!-- Static icon (no JS needed) -->
<Star size={24} animated={false} />
<!-- Interactive icon (hydrated) -->
<AnimatedHeart client:load />
</body>
</html>ViteReact SPA
Standard React setup. Add IconProvider at the root.
// main.tsx - Vite + React
import React from 'react'
import ReactDOM from 'react-dom/client'
import { IconProvider } from 'livelyicons'
import App from './App'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<IconProvider config={{ animated: true }}>
<App />
</IconProvider>
</React.StrictMode>
)
// App.tsx
import { Heart, Star, Settings, Loader } from 'livelyicons'
function App() {
return (
<div>
<Heart lively="pulse" trigger="hover" />
<Star lively="scale" />
<Settings lively="rotate" trigger="hover" />
<Loader lively="spin" trigger="loop" />
</div>
)
}SSR Frameworks
Next.js, Remix, Astro - Use animated={false} for server-rendered icons
SPA Frameworks
Vite, Create React App - Full animation support out of the box
11Performance Best Practices
Optimize bundle size and runtime performance with these strategies.
Bundle Size Optimization
Tree shaking: Individual imports only bundle the icons you use. Avoid import * in production builds.
// Individual imports (recommended)
// Only bundles the icons you use
import { Heart, Star, Check } from 'livelyicons'
// Namespace import (larger bundle)
// Bundles entire icon library - avoid in production
import * as Icons from 'livelyicons'
// Dynamic imports for code splitting
const LazyHeart = lazy(() =>
import('livelyicons').then(mod => ({ default: mod.Heart }))
)When to Use Static vs Animated Icons
Not every icon needs animation. Use animations purposefully for better UX.
// Use static icons for:
// - Navigation menus with many icons
// - Lists with repeated icons
// - Server-rendered content
<Star animated={false} />
<Check animated={false} />
// Use animated icons for:
// - Call-to-action buttons
// - Interactive elements
// - Status indicators
// - Empty states
<Heart lively="pulse" trigger="hover" />
<Loader lively="spin" trigger="loop" />Static Icons
- Navigation menus
- Data tables with icons
- Lists with many items
- Server-rendered content
Animated Icons
- Call-to-action buttons
- Loading states
- Success/error feedback
- Interactive elements
Reducing Motion for Accessibility
MotionIcons automatically respects prefers-reduced-motion. You can also control it manually.
// LivelyIcons respects prefers-reduced-motion automatically
// No additional code needed!
// For manual control:
import { IconProvider } from 'livelyicons'
function App() {
// Disable animations for all icons
return (
<IconProvider config={{ animated: false }}>
<YourApp />
</IconProvider>
)
}
// Or per-icon override
<Heart animated={false} /> // Force static
<Heart animated /> // Force animated (override provider)Automatic Detection
When users have prefers-reduced-motion: reduce enabled in their OS settings, all animations are automatically disabled without any code changes.
Lazy Loading Strategies
Split icon bundles across routes for faster initial page loads.
// Lazy load icons for routes/sections not immediately visible
import { lazy, Suspense } from 'react'
// Create lazy icon components
const LazySettingsIcon = lazy(() =>
import('livelyicons').then(mod => ({ default: mod.Settings }))
)
function SettingsPanel() {
return (
<Suspense fallback={<div className="w-6 h-6 bg-gray-200 animate-pulse" />}>
<LazySettingsIcon lively="rotate" />
</Suspense>
)
}
// Route-based code splitting (Next.js example)
// Icons in dynamically imported components split automatically
const DashboardIcons = dynamic(() => import('./DashboardIcons'))Route-based Splitting
Icons in dynamically imported route components are automatically code-split by bundlers.
Component-based Splitting
Use React.lazy() for icons in modals, drawers, or below-fold content.
Performance Checklist
- Use individual imports, not namespace
- Set
animated={false}for static icons - Use
trigger="hover"overtrigger="loop"
- Lazy load icons in modals/drawers
- Use
inViewtrigger for long pages - Test with reduced motion enabled
12Next.js App Router
LivelyIcons provides multiple approaches for Next.js App Router with React Server Components (RSC). Choose the right approach based on your needs.
Import Paths Quick Reference
| Approach | Import Path | Client JS |
|---|---|---|
| Animated | livelyicons | |
| Static | livelyicons/static | |
| CSS | livelyicons/css |
Full Motion animations. Requires 'use client' directive.
Pure SVG, zero JS. Works in Server Components without any directive.
CSS keyframe animations. RSC-safe with animation support.
1Server Component with Static Icons
Best for: Navigation, headers, footers, and any server-rendered UI. Zero client-side JavaScript - icons render as pure SVG on the server.
// app/layout.tsx - Server Component (no "use client" needed)
import { StaticHeart, StaticStar, StaticHome } from 'livelyicons/static';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<nav className="flex items-center gap-4 p-4 border-b">
{/* Static icons render on server with zero client JS */}
<StaticHome size={24} className="text-gray-600" />
<StaticHeart size={20} className="text-red-500" />
<StaticStar size={20} className="text-yellow-500" />
</nav>
{children}
</body>
</html>
);
}2Client Component Boundary
Best for: Interactive icons that need hover effects, state changes, or Motion animations. Create a small client component wrapper for interactive icons.
// app/components/AnimatedHeart.tsx
'use client';
import { Heart } from 'livelyicons';
export function AnimatedHeart({ size = 24 }: { size?: number }) {
return (
<Heart
size={size}
lively="pulse"
trigger="hover"
className="text-red-500 cursor-pointer"
/>
);
}
// app/page.tsx - Server Component
import { AnimatedHeart } from './components/AnimatedHeart';
import { StaticStar } from 'livelyicons/static';
export default function Page() {
return (
<div>
{/* Client component for interactivity */}
<AnimatedHeart size={32} />
{/* Static icon renders on server */}
<StaticStar size={24} />
</div>
);
}3CSS Animation Alternative
Best for: When you need animations but want to avoid client JavaScript entirely. Use CSS classes with static icons for RSC-safe animations.
// app/globals.css - Import CSS animations
@import 'livelyicons/css/styles.css';
// Or inject programmatically in layout.tsx
import { cssStylesheet } from 'livelyicons/css';
// Include in your global styles or use a <style> tag
// The cssStylesheet contains all animation keyframes
// app/page.tsx - Server Component with CSS animations
import { StaticHeart, StaticLoader } from 'livelyicons/static';
export default function Page() {
return (
<div>
{/* Pulse animation via CSS - no client JS needed */}
<StaticHeart
size={24}
animationClass="motionicon-pulse"
className="text-red-500"
/>
{/* Continuous spin via CSS */}
<StaticLoader
size={24}
animationClass="motionicon-spin"
className="text-blue-500"
/>
</div>
);
}Available CSS Animation Classes
motionicon-scalemotionicon-rotatemotionicon-pulsemotionicon-bouncemotionicon-shakemotionicon-spinmotionicon-draw4Hybrid Pattern (Static Layout + Animated Content)
Best for: Real-world apps that need both fast server rendering and interactive elements. Use static icons in layouts, animated icons in specific client components.
// Hybrid Pattern: Static layout + Animated content
// app/dashboard/layout.tsx - Server Component
import { StaticHome, StaticSettings, StaticBell } from 'livelyicons/static';
import { NotificationBell } from './NotificationBell';
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex">
{/* Static sidebar renders on server */}
<aside className="w-64 border-r p-4">
<nav className="space-y-2">
<a href="/" className="flex items-center gap-2">
<StaticHome size={20} /> Home
</a>
<a href="/settings" className="flex items-center gap-2">
<StaticSettings size={20} /> Settings
</a>
</nav>
</aside>
<main className="flex-1">
{/* Client component for interactive notifications */}
<header className="p-4 border-b flex justify-end">
<NotificationBell />
</header>
{children}
</main>
</div>
);
}
// app/dashboard/NotificationBell.tsx
'use client';
import { Bell } from 'livelyicons';
import { useState } from 'react';
export function NotificationBell() {
const [hasNew, setHasNew] = useState(true);
return (
<button onClick={() => setHasNew(false)} className="relative">
<Bell
size={24}
lively={hasNew ? 'shake' : 'scale'}
trigger={hasNew ? 'loop' : 'hover'}
/>
{hasNew && (
<span className="absolute -top-1 -right-1 w-3 h-3 bg-red-500 rounded-full" />
)}
</button>
);
}5Lazy Loading with Suspense Fallback
Best for: Progressive enhancement where animated icons load after initial render. Use static icons as Suspense fallbacks for seamless loading states.
// app/page.tsx - Lazy loading with Suspense
import { Suspense, lazy } from 'react';
import { StaticLoader } from 'livelyicons/static';
// Lazy load the animated icon component
const AnimatedDashboard = lazy(() => import('./AnimatedDashboard'));
export default function Page() {
return (
<div>
{/* Static fallback while loading animated component */}
<Suspense
fallback={
<div className="flex items-center justify-center p-8">
<StaticLoader
size={32}
animationClass="motionicon-spin"
className="text-blue-500"
/>
</div>
}
>
<AnimatedDashboard />
</Suspense>
</div>
);
}
// app/AnimatedDashboard.tsx
'use client';
import { Heart, Star, Bell, Settings } from 'livelyicons';
export default function AnimatedDashboard() {
return (
<div className="grid grid-cols-4 gap-4 p-8">
<Heart lively="pulse" trigger="hover" size={48} />
<Star lively="rotate" trigger="hover" size={48} />
<Bell lively="shake" trigger="hover" size={48} />
<Settings lively="spin" trigger="hover" size={48} />
</div>
);
}Which Approach Should I Use?
Use livelyicons/static when:
You want zero client JS, need SSR/SSG, or icons are purely decorative.
Use livelyicons with 'use client' when:
You need hover effects, Motion animations, or interactive state changes.
Use livelyicons/css when:
You want RSC compatibility with CSS-based animations (spin, pulse, etc.).
13shadcn/ui Integration - Coming Soon
LivelyIcons provides a shadcn-compatible registry that installs icons directly into your project following shadcn conventions. No npm package needed - components live in your codebase and are fully customizable.
Why Use the shadcn Registry?
13.1Installation Quick Reference
| Command | What it installs |
|---|---|
npx shadcn@latest add https://livelyicons.com/r/lively-essentials.json | Provider, hook, types + popular icons |
npx shadcn@latest add https://livelyicons.com/r/heart-pulse.json | Individual icon component |
npx shadcn@latest add https://livelyicons.com/r/lively-provider.json | Context provider only |
npx shadcn@latest add https://livelyicons.com/r/lively-types.json | TypeScript types only |
13.2Installing the Essentials Bundle
The essentials bundle is the fastest way to get started. It includes the provider, animation hook, types, and a curated set of popular icons.
# Install the essentials bundle (provider, hook, types + popular icons)
npx shadcn@latest add https://livelyicons.com/r/lively-essentials.json
# This installs:
# - LivelyProvider context
# - useLivelyAnimation hook
# - TypeScript types
# - Popular icons (Heart, Star, Check, etc.)13.3Installing Individual Icons
Install only the icons you need for a minimal footprint. Each icon is self-contained with its own animation logic.
# Install individual icons as needed
npx shadcn@latest add https://livelyicons.com/r/heart-pulse.json
npx shadcn@latest add https://livelyicons.com/r/activity.json
npx shadcn@latest add https://livelyicons.com/r/globe.json
# Install just the animation infrastructure
npx shadcn@latest add https://livelyicons.com/r/lively-provider.json
npx shadcn@latest add https://livelyicons.com/r/use-lively-animation.json
npx shadcn@latest add https://livelyicons.com/r/lively-types.json13.4Using Installed Icons
After installation, import icons from your local @/components/icons directory.
// Import from your local components
import { HeartPulse } from "@/components/icons/heart-pulse"
import { Activity } from "@/components/icons/activity"
import { Globe } from "@/components/icons/globe"
function Dashboard() {
return (
<div className="flex items-center gap-4">
{/* Pulse animation on hover */}
<HeartPulse size={24} lively="pulse" />
{/* Draw animation */}
<Activity size={24} lively="draw" trigger="hover" />
{/* Continuous rotation */}
<Globe size={32} lively="rotate" trigger="loop" />
</div>
)
}13.5Global Configuration with LivelyProvider
Wrap your app with LivelyProvider to set default values for all icons.
// app/layout.tsx or _app.tsx
import { LivelyProvider } from "@/lib/lively-provider"
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<LivelyProvider
config={{
animated: true,
defaultSize: 24,
defaultStrokeWidth: 2,
}}
>
{children}
</LivelyProvider>
</body>
</html>
)
}
// Now all icons inherit these defaults
import { HeartPulse } from "@/components/icons/heart-pulse"
function Component() {
return <HeartPulse lively="pulse" /> // Uses default size of 24
}13.6Styling with cn() and Tailwind
Icons are fully compatible with Tailwind CSS and the shadcn cn() utility for conditional styling.
import { HeartPulse } from "@/components/icons/heart-pulse"
import { cn } from "@/lib/utils"
// Using className with Tailwind
<HeartPulse
size={24}
className="text-red-500 hover:text-red-600"
lively="pulse"
/>
// Using cn() for conditional styling
function LikeButton({ liked }: { liked: boolean }) {
return (
<button>
<HeartPulse
size={24}
lively="pulse"
className={cn(
"transition-colors",
liked ? "text-red-500 fill-red-500" : "text-muted-foreground"
)}
/>
</button>
)
}
// CSS variable customization
<style>
:root {
--lively-icon-size: 24px;
--lively-stroke-width: 2;
}
</style>13.7File Structure After Installation
Components are installed following shadcn conventions:
your-project/
├── components/
│ └── icons/
│ ├── heart-pulse.tsx # Individual icon components
│ ├── activity.tsx
│ ├── globe.tsx
│ └── ...
├── hooks/
│ └── use-lively-animation.ts # Animation hook
├── lib/
│ ├── lively-provider.tsx # Context provider
│ ├── lively-types.ts # TypeScript types
│ └── utils.ts # Your existing cn() utility
└── ...13.8Styling Conventions
CSS Variables
Icons support optional CSS variable customization:
--lively-icon-size--lively-stroke-widthComponent Pattern
All icons use React's forwardRef pattern, matching shadcn/ui components. Refs are forwarded to the underlying SVG element.
cn() Utility Required
Your project must have a cn() utility at @/lib/utils. This is standard in shadcn/ui projects.
13.9Available Icons
1300+
icons available via registry
All icons from the LivelyIcons library are available through the shadcn registry. Use the icon browser to find icons by name or category, then install them with the CLI.
Requirements
Motion library
Run npm install motion or pnpm add motion
cn() utility
Your project needs @/lib/utils with the cn() function (standard in shadcn/ui)
React 18+
Icons use modern React features like forwardRef