---
title: Icons
description: Lucide Icons animated with Motion.
alpha: true
---

import { CodeTabs } from '@/registry/components/code-tabs';
import { Icons } from '@/components/docs/icons';
import { ArrowRight } from '@/registry/icons/arrow-right';
import { IconShowcase } from '@/components/docs/icon-showcase';

We animated [Lucide Icons](https://lucide.dev) with [Motion](https://motion.dev), one of the most popular icon libraries on the web.

## Installation

You need to install the icon wrapper components to use the animated icons.

<CodeTabs
  codes={{
    npm: `npx shadcn@latest add "https://animate-ui.com/r/icon.json"`,
    pnpm: `pnpm dlx shadcn@latest add "https://animate-ui.com/r/icon.json"`,
    yarn: `npx shadcn@latest add "https://animate-ui.com/r/icon.json"`,
    bun: `bun x --bun shadcn@latest add "https://animate-ui.com/r/icon.json"`,
  }}
/>

## Icons

<Icons />

## Usage

### Install an icon

<CodeTabs
  codes={{
    npm: `npx shadcn@latest add "https://animate-ui.com/r/[lucide-icon-name]-icon.json"`,
    pnpm: `pnpm dlx shadcn@latest add "https://animate-ui.com/r/[lucide-icon-name]-icon.json"`,
    yarn: `npx shadcn@latest add "https://animate-ui.com/r/[lucide-icon-name]-icon.json"`,
    bun: `bun x --bun shadcn@latest add "https://animate-ui.com/r/[lucide-icon-name]-icon.json"`,
  }}
/>

### How to use an icon

Each icon has at least 3 animations:

- `path`: an animation of the pathLength from 0 to 1
- `path-loop`: pathLength animation from 1 to 0 to 1
- `default`: the default animation, customized for each icon

You can use the `animation` prop to select the animation.

```tsx
<Icon animation="path" />
```

Some icons also have other animations created specifically for them.

<div className="grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-4">
  <IconShowcase icon={ArrowRight} animation="default-loop" loop loopDelay={2} />
  <IconShowcase
    icon={ArrowRight}
    animation="pointing-loop"
    loop
    loopDelay={2}
  />
  <IconShowcase icon={ArrowRight} animation="out" loop loopDelay={2} />
</div>

Animations ending with `-loop` are animations that start at the initial state, do the animation and return to the initial state.

<div className="grid sm:grid-cols-2 grid-cols-1 gap-4">
  <IconShowcase icon={ArrowRight} animation="pointing" loop loopDelay={2} />
  <IconShowcase
    icon={ArrowRight}
    animation="pointing-loop"
    loop
    loopDelay={2}
  />
</div>

### Trigger animation by parent element

You can use the `AnimateIcon` component to manage child icon animations.

```tsx
<AnimateIcon animateOnHover>
  <div>
    <Icon />
  </div>
</AnimateIcon>
```

You can choose the animation on the `AnimateIcon` component.

```tsx
<AnimateIcon animateOnHover animation="path">
  <div>
    <Icon />
  </div>
</AnimateIcon>
```

But you can also specify it directly on the icon, which will be given priority.

```tsx
<AnimateIcon animateOnHover animation="path">
  <div>
    <Icon animation="out" />
    <Icon2 />
    <Icon3 />
  </div>
</AnimateIcon>
```

### Props

<TypeTable
  type={{
    size: {
      description: 'The size of the icon',
      type: 'number',
      required: false,
      default: '28',
    },
    onAnimateChange: {
      description: 'The callback function to call when the animation changes',
      type: 'onAnimateChange?: (value: boolean, animation: StaticAnimations | string) => void;',
      required: false,
      default: 'undefined',
    },
    onAnimateStart: {
      description: 'The callback function to call when the animation starts',
      type: '() => void',
      required: false,
      default: 'undefined',
    },
    onAnimateEnd: {
      description: 'The callback function to call when the animation ends',
      type: '() => void',
      required: false,
      default: 'undefined',
    },
    animate: {
      description:
        'Whether to animate the icon. You can also specify the animation to use.',
      type: 'boolean | string',
      required: false,
      default: 'false',
    },
    animateOnHover: {
      description:
        'Whether to animate the icon on hover. You can also specify the animation to use.',
      type: 'boolean | string',
      required: false,
      default: 'false',
    },
    animateOnTap: {
      description:
        'Whether to animate the icon on tap. You can also specify the animation to use.',
      type: 'boolean | string',
      required: false,
      default: 'false',
    },
    animation: {
      description: 'The animation to use',
      type: 'string',
      required: true,
    },
    loop: {
      description: 'Whether to loop the animation',
      type: 'boolean',
      required: false,
      default: 'false',
    },
    loopDelay: {
      description: 'The delay before looping the animation',
      type: 'number',
      required: false,
      default: '0',
    },
  }}
/>

## Credits

We use the [Lucide Icons](https://lucide.dev) library to create the icons and [Motion](https://motion.dev) to animate them.

We took our inspiration from:

- [Iconly](https://iconly.pro/)
- [Lordicon](https://lordicon.com/)
- [Flaticon](https://www.flaticon.com/)
- [pqoqubbw/icons](https://icons.pqoqubbw.dev/)
