Skip to content

Icons

fastify-admin ships with HugeIcons as its default icon set. Every icon in the UI is registered in a central icon registry, so you can swap any of them for icons from Lucide React, Heroicons, Phosphor, Radix Icons, or any other React icon library — without touching the core package.


How It Works

There are two kinds of icons in the admin UI:

KindWhat it isHow to override
Named UI iconsFixed slots — sidebar defaults, theme toggle, action buttonsiconRegistry.override()
Entity iconsPer-entity icons shown in the sidebariconRegistry.registerEntityIcons()

Both are configured in your main.tsx before calling FastifyAdmin.initFromApi().


Named UI Icons

These are the built-in icon slots used throughout the admin panel:

KeyDefaultWhere it appears
entityDatabaseLightningDefault entity icon in the sidebar
securityShieldSecurity section in the sidebar
sunSunTheme toggle — light mode
moonMoonTheme toggle — dark mode
systemMonitorTheme toggle — system mode
viewEyeView button in list table
editPencilEdit button in list table
deleteTrashDelete button in list table
arrowLeftArrow leftBack button on show/edit pages

Override any of them by calling iconRegistry.override():

main.tsx
import { iconRegistry } from './lib/iconRegistry'
import { Trash2, Pencil, Eye } from 'lucide-react'
iconRegistry.override({
delete: Trash2,
edit: Pencil,
view: Eye,
})

You only need to provide the keys you want to change — the rest keep their defaults.


Entity Icons

Entity icons are set via EntityView.icon on the server as a string key. The bundled frontend pre-registers the following HugeIcons keys — just use one of these strings and it will resolve automatically:

CategoryAvailable keys
PeopleUser03, UserGroup, UserMultiple, UserAccount, UserCheck01, UserStar01
SecurityShieldUser, LockKey, Security, Lock, Key01
ProductsPackage01, Package02, ShoppingBag01, ShoppingCart01, Store01, Tag01
FinanceWallet01, Money01, CreditCard, Invoice01
CommunicationMail01, Message01, Notification01
AnalyticsAnalytics01, BarChart, PieChart01, Chart01, Database01, Table01
ContentFile01, Folder01, Image01, Note01, News01, BookOpen01
NavigationHome01, Search01, Settings01, Bookmark01, Star
TechCode, CloudServer, ServerStack01, Globe02, Link01, Layers01
TimeCalendar01, Ticket01
packages/fastify-admin/src/views/product.view.ts
class ProductView extends EntityView {
icon = 'Package01' // resolved automatically in the bundled UI
}

Any unregistered key falls back to the default entity icon silently.


Using Any Icon Library

The AdminIconComponent type is library-agnostic. Any React component that accepts optional size and className props works:

type AdminIconComponent = React.ComponentType<{
size?: number
className?: string
}>

Lucide React

Lucide icons already match this signature — use them directly:

import { Trash2, Pencil } from 'lucide-react'
iconRegistry.override({ delete: Trash2, edit: Pencil })

Heroicons

Heroicons v2 accept className but not size. Wrap them with a thin adapter:

import { TrashIcon } from '@heroicons/react/24/outline'
const HeroTrash: AdminIconComponent = ({ size = 16, className }) => (
<TrashIcon style={{ width: size, height: size }} className={className} />
)
iconRegistry.override({ delete: HeroTrash })

Phosphor Icons

import { Trash } from '@phosphor-icons/react'
iconRegistry.override({ delete: Trash })

HugeIcons (default)

HugeIcons exports SVG data objects, not React components. Use the asIcon() helper to wrap them:

import { asIcon } from './lib/iconRegistry'
import { Delete02Icon } from '@hugeicons/core-free-icons'
iconRegistry.override({ delete: asIcon(Delete02Icon) })

Entity Icon in EntityView

When writing server-side entity config, the icon property is a string key matched against the registry:

// fastify-admin/src/views/product.view.ts (server)
class ProductView extends EntityView {
icon = 'Package01' // must match a key in registerEntityIcons()
}

If you need a custom icon not in the pre-registered set, add it to registerEntityIcons() in your main.tsx:

// apps/web/src/main.tsx (client)
iconRegistry.registerEntityIcons({
MyCustomIcon: asIcon(SomeHugeIcon), // or any AdminIconComponent
})

Full Example — main.tsx

import { iconRegistry, asIcon } from './lib/iconRegistry'
import { FastifyAdmin } from './lib/FastifyAdmin'
// 1. Override named UI icons (optional)
import { Trash2, Pencil, Eye } from 'lucide-react'
iconRegistry.override({ delete: Trash2, edit: Pencil, view: Eye })
// 2. Register entity icons by server-side name
import { User03Icon, ShieldUserIcon } from '@hugeicons/core-free-icons'
iconRegistry.registerEntityIcons({
User03: asIcon(User03Icon),
ShieldUser: asIcon(ShieldUserIcon),
})
// 3. Init — icons are resolved automatically
await FastifyAdmin.initFromApi()