# React Lucide Icons

React Lucide icons in AdminKit: import each icon as a component, size it with a class, color it with text utilities and give icon-only buttons a label.

Icons help people scan a page: a bell for notifications, a pen to edit, a trash can to delete. AdminKit for React uses [Lucide](https://lucide.dev/icons/), a set of 2,015 open-source icons drawn on a 24×24 grid. They are in the free and PRO versions of [AdminKit for React](/react/).

Each icon is a React component from the `lucide-react` package. You import the ones you need and write them like any other element: `<Bell />`. Each one renders an inline `<svg>` that takes the color of the text around it.

## Example

```html
<div class="d-flex gap-3">
  <i data-lucide="house"></i>
  <i data-lucide="bell"></i>
  <i data-lucide="mail"></i>
  <i data-lucide="message-square"></i>
  <i data-lucide="users"></i>
  <i data-lucide="credit-card"></i>
  <i data-lucide="chart-pie"></i>
  <i data-lucide="settings"></i>
</div>
```
```tsx code
import {
  Bell,
  ChartPie,
  CreditCard,
  House,
  Mail,
  MessageSquare,
  Settings,
  Users,
} from "lucide-react";

export function IconRow() {
  return (
    <div className="d-flex gap-3">
      <House />
      <Bell />
      <Mail />
      <MessageSquare />
      <Users />
      <CreditCard />
      <ChartPie />
      <Settings />
    </div>
  );
}
```

## Find an icon

Search for an icon on [lucide.dev](https://lucide.dev/icons/), or open the Lucide page of the template (`/icons-lucide`). That page lists every icon and filters them by name and tag as you type.

Lucide names are in kebab-case, and the component has the same name in PascalCase. Drop the dashes and start each word with a capital:

| Lucide name | Component |
| --- | --- |
| `bell` | `Bell` |
| `chart-pie` | `ChartPie` |
| `circle-check-big` | `CircleCheckBig` |
| `message-square` | `MessageSquare` |

Some old names still import, as aliases of the current ones: `Home` gives you `House`. The template always uses the current names from lucide.dev, and so should you.

## Import only what you use

Import each icon by name, as the template does in every file:

```tsx
import { Download, Printer, Send } from "lucide-react";
```

The build then keeps only those icons and leaves the rest of the package out of your JavaScript. This is called tree shaking.

`lucide-react` also exports an `icons` object with every icon in it. Only the Lucide demo page imports it, in `src/components/pages/icons/lucide/lucide-icons.tsx`, because it shows them all. Every route in `src/routes/` loads on its own with `React.lazy`, so that full set only loads when someone opens that page. Anywhere else, stick to named imports.

## Sizes

AdminKit's CSS gives every icon the `lucide` class: 18×18 pixels with a stroke width of 2. Add `lucide-sm` for 14 pixels or `lucide-lg` for 36 pixels. Inside a `.btn`, icons are 14 pixels.

```html
<i data-lucide="bell" class="lucide-sm"></i>
<i data-lucide="bell"></i>
<i data-lucide="bell" class="lucide-lg"></i>
```
```tsx code
<Bell className="lucide-sm" />
<Bell />
<Bell className="lucide-lg" />
```

For any other size, set the width and height with a `style` or a class of your own:

```html
<i data-lucide="bell" style="width:24px;height:24px;"></i>
<i data-lucide="bell" style="width:48px;height:48px;"></i>
```
```tsx code
<Bell style={{ width: 24, height: 24 }} />
<Bell style={{ width: 48, height: 48 }} />
```

The `size` and `strokeWidth` props of `lucide-react` don't change much here. They set attributes on the `<svg>`, and the `lucide` class in the CSS overrides them. A `style`, such as `style={{ strokeWidth: 1.5 }}`, does win over the class.

## Colors

Icons draw with `currentColor`, so they take the text color of their parent. To give one its own color, add a Bootstrap text color class:

```html
<i data-lucide="bell" class="text-primary"></i>
<i data-lucide="bell" class="text-secondary"></i>
<i data-lucide="bell" class="text-success"></i>
<i data-lucide="bell" class="text-danger"></i>
<i data-lucide="bell" class="text-warning"></i>
<i data-lucide="bell" class="text-info"></i>
```
```tsx code
<Bell className="text-primary" />
<Bell className="text-secondary" />
<Bell className="text-success" />
<Bell className="text-danger" />
<Bell className="text-warning" />
<Bell className="text-info" />
```

## Icons next to text

When an icon sits next to a label, the template adds `align-middle` to line it up with the text and `me-1` for a small gap:

```html
<button type="button" class="btn btn-primary">
  <i data-lucide="download" class="align-middle me-1"></i> Download PDF
</button>
```
```tsx code
<button type="button" className="btn btn-primary">
  <Download className="align-middle me-1" /> Download PDF
</button>
```

## Icon-only buttons

A button with only an icon has no text for a screen reader to read. Give the button an `aria-label` that says what it does. The icon itself is decoration: `lucide-react` adds `aria-hidden="true"` to it for you, as long as you don't give it an `aria-*`, `role` or `title` prop.

```html
<button type="button" class="btn btn-light" aria-label="Edit">
  <i data-lucide="pen" aria-hidden="true"></i>
</button>
<button type="button" class="btn btn-light" aria-label="Delete">
  <i data-lucide="trash" aria-hidden="true"></i>
</button>
```
```tsx code
import { Pen, Trash } from "lucide-react";

<button type="button" className="btn btn-light" aria-label="Edit">
  <Pen />
</button>
<button type="button" className="btn btn-light" aria-label="Delete">
  <Trash />
</button>
```

## Pass an icon as a prop

Sometimes a component shows an icon that its parent picks, like a stat card or a menu item. Type the prop as `LucideIcon` and pass the component itself. The dashboard stat cards (`Stats`) and the sidebar menu (`src/data/navigation.ts`) do this:

```tsx
import { DollarSign, type LucideIcon } from "lucide-react";

function StatCard({ icon: Icon, title }: { icon: LucideIcon; title: string }) {
  return (
    <div className="card">
      <div className="card-body">
        <Icon className="align-middle" /> {title}
      </div>
    </div>
  );
}

<StatCard icon={DollarSign} title="Income" />;
```

## Accessibility

- `lucide-react` hides an icon from screen readers with `aria-hidden="true"`, unless you give it an `aria-*`, `role` or `title` prop.
- A button or link with only an icon needs an `aria-label`, as the edit and delete links of the tables demo have.
- An icon that carries meaning on its own, without text next to it, needs a text alternative. Put an `aria-label` on the element around it, or add a visually hidden `<span class="visually-hidden">` with the text.

## Related

- [Next.js Lucide icons](/nextjs/docs/icons/lucide-icons/): the same icons in AdminKit for Next.js
- [Bootstrap 5 Lucide icons](/bootstrap/docs/icons/lucide-icons/): the icons of the HTML version
- [Font Awesome icons](/react/docs/icons/font-awesome/): the second icon set of AdminKit PRO
- [Buttons](/react/docs/components/buttons/): buttons with icons
- [Lucide icons demo](https://react-demo.adminkit.io/icons-lucide)

---

Canonical HTML page: https://adminkit.io/react/docs/icons/lucide-icons/

Site overview for agents: https://adminkit.io/llms.txt (expanded: https://adminkit.io/llms-full.txt) · Documentation: https://adminkit.io/bootstrap/docs/ · Questions: support@adminkit.io
