Skip to main content
WireKit
Copy for LLM

Icon

The <x-wirekit::icon /> component renders SVG icons via semantic aliases. Instead of referencing a specific icon set directly, you use abstract names like close, search, or trash. WireKit maps these to the actual icon from your configured preset — switch icon sets with a single config change.

Requirements

The icon system requires blade-icons (the rendering engine) and one icon set package (the actual SVGs):

# Required: blade-icons rendering engine
composer require blade-ui-kit/blade-icons

# Plus ONE icon set — choose your favorite:
composer require blade-ui-kit/blade-heroicons          # Heroicons (default)
composer require mallardduck/blade-lucide-icons        # Lucide
composer require codeat3/blade-phosphor-icons          # Phosphor
composer require secondnetwork/blade-tabler-icons     # Tabler

You only need one icon set installed. WireKit's default preset is heroicons, so blade-ui-kit/blade-heroicons is the quickest way to get started. One stackable extension preset (heroicons-marketing) reuses the same package and layers a handful of marketing-copy aliases on top; a second (heroicons-app) is registered but empty — see Available Presets for the full menu.

When a package is missing

Both halves have to be there, and the failure looks different depending on which one is absent. Neither takes the page down.

Installed What renders What you are told
Neither an inert, correctly-sized placeholder one warning in the log naming both packages
blade-icons only an inert, correctly-sized placeholder one error in the log naming the set package to install
Both the icon nothing

The middle row is the one worth knowing about, because it is the state an application lands in by accident. If you already had blade-icons for your own icon set, the set package above reads as optional — and every WireKit alias resolves against it. inbox becomes heroicon-m-inbox whether or not Heroicons is installed, because the alias tables are static.

The placeholder keeps its box, so the layout does not move, and it carries data-wk-icon-missing="<alias>" if you want to find them in a rendered page. The log line names the resolved identifier rather than the alias you wrote, because the alias is not the problem:

WireKit: the icon alias 'inbox' resolved to 'heroicon-m-inbox', but no icon set with the
prefix 'heroicon' is registered. Install blade-ui-kit/blade-heroicons to provide it.
Rendering an empty placeholder.

It is said once per prefix per process, not once per icon — a single page draws icons through buttons, dropdowns and modals, and fifty identical lines is a log nobody reads.

Two deliberate exceptions to the degradation:

  • A console command or a test fails loudly instead. There, a missing package is a build problem somebody can fix now, and a silent placeholder would let it ship. Set wirekit.validation.throw_on_invalid to force either behavior in either context.
  • A fallback you configured still wins. If blade-icons has a fallback icon configured — per set or globally — that icon renders and WireKit never sees a failure.

Usage

Navigation and Action Icons
Status and Feedback Icons
Object and Visibility Icons
<!-- Default size (h-5 w-5) -->
<x-wirekit::icon name="close" />

<!-- Custom size -->
<x-wirekit::icon name="search" class="h-4 w-4" />

<!-- Decorative icon (hidden from screen readers — the default) -->
<x-wirekit::icon name="trash" class="h-4 w-4" />

Icon Preview

Every semantic alias rendered with the default Heroicons preset:

All Semantic Icons

close

menu

search

click

paint-brush

chevron-down

chevron-up

chevron-left

chevron-right

check

plus

minus

info

success

warning

danger

user

calendar

trash

edit

eye

eye-off

upload

download

sort-asc

sort-desc

filter

external-link

home

moon

sun

system

code

key

rocket-launch

broadcast

chart-bar

coins

gift

list-bullets

list-checks

lock-key

map-pin

percent

sliders

trend-up

chart-line

folders

phone

book-open

sign-out

megaphone

map

file-text

copy

globe

book

lightbulb

settings

gear

dashboard

billing

credit-card

server

database

cloud

shield-check

inbox

refresh

undo

play

pause

stop

speaker

mute

microphone

users

history

legal

badge

layers

stack

cash-register

bell-slash

tag

send

envelope

store

cart

receipt

truck

package

barcode

user-add

user-remove

building

webhook

arrow-left

clock

lock

archive

image

message

reply

forward

bell

bolt

shield

more

chevron-up-down

more-vertical

arrows-left-right

hash

shield-warning

prohibit

scan

arrow-down

arrow-right

arrow-up

arrow-up-right

chart-pie

code-bracket

cog-6-tooth

command-line

finger-print

fire

heart

attach

cube

sparkles

link

live

lock-closed

open-source

puzzle-piece

security

speed

squares-2x2

star

swatch

unlock

user-group

x-circle

Configuration

Configure your icon preset in config/wirekit.php. Use the singular preset key for a single base preset, or the plural presets array to stack a base preset with one or more stackable extension presets:

// Single base preset (the simplest case)
'icons' => [
    'preset' => 'heroicons',  // or 'lucide', 'phosphor', 'tabler'
    'aliases' => [],
],

// Stacked: base + the marketing extension (adds its marketing-copy aliases)
'icons' => [
    'presets' => ['heroicons', 'heroicons-marketing'],
    'aliases' => [],
],

See Available Presets for the full preset list including the stackable extension.

Available Presets

WireKit ships with four base presets, each mapping the full semantic-alias set. Two extension presets are also registered; only heroicons-marketing still carries aliases, and both resolve to heroicons glyphs, so they belong on a heroicons install rather than on lucide, phosphor or tabler.

Preset Key Type Icon Set Aliases Blade Package Browse Icons
heroicons Base Heroicons (Mini 20px) Full set blade-ui-kit/blade-heroicons heroicons.com
heroicons-app Stackable Heroicons (Mini 20px) none — empty since v2.37.0 blade-ui-kit/blade-heroicons heroicons.com
heroicons-marketing Stackable Heroicons (Mini 20px) Marketing extras blade-ui-kit/blade-heroicons heroicons.com
lucide Base Lucide (Outline) Full set mallardduck/blade-lucide-icons lucide.dev
phosphor Base Phosphor (Regular) Full set codeat3/blade-phosphor-icons phosphoricons.com
tabler Base Tabler Icons Full set secondnetwork/blade-tabler-icons tabler.io/icons

Stackable Presets (App + Marketing Aliases)

WireKit ships two stackable extension presets that compose with the base heroicons preset (or any base preset) without breaking the base alias contract:

  • heroicons-appempty since 2026-08-26. Every alias it carried now lives in all four base presets, so those words work on Lucide, Phosphor and Tabler too. It stays registered so a published config naming it still boots; stacking it is a no-op.
  • heroicons-marketingcursor-arrow-rays, cube-transparent, a11y, sparkle, ai, pulse. These are the ones that could NOT move: either no set outside Heroicons has a genuine glyph for them, or the glyph it does have is already another alias's picture there — and a word that quietly means something else on a different set is worse than a word that is simply absent.

An alias can move from a stackable preset into the base set — several have — so the lists above name the shape rather than the whole. php artisan wirekit:icons --preset=heroicons-marketing prints the current set for the presets you actually have configured.

Activate by switching from the singular preset key to the plural presets array — stack as many extensions as you need:

'icons' => [
    // 'preset' => 'heroicons',
    'presets' => ['heroicons', 'heroicons-marketing'],
    'aliases' => [],
],

Resolution order — highest priority first:

  1. Developer aliases overrides
  2. Right-most preset in the presets array (later wins)
  3. Left-most preset in the presets array

Aliases in heroicons-marketing have zero overlap with the base heroicons preset (heroicons-app is empty, so it trivially overlaps nothing). The order is only meaningful when you stack presets that DO share alias names (e.g. ['heroicons', 'lucide']lucide would win on close, search, etc.). Anti-drift tests in IconSystemTest enforce both no-overlap guarantees.

{{-- 1. `arrow-up` needs no extension since v2.37.0 — it is in every base preset: --}}
<x-wirekit::icon name="arrow-up" />      {{-- table sort --}}

{{-- 2. After activating heroicons-marketing: --}}
<x-wirekit::icon name="sparkles" />

Names move down, not away. lock, bell, lightbulb, bolt, rocket-launch and shield were on this list and are now in the base preset — they resolve without activating anything. Nothing broke for anyone who had stacked a preset to get them; the extension simply no longer needs to carry the name. If a name you rely on is missing from a preset after an upgrade, look for it in the base tables above before assuming it is gone.

Switching Presets

To switch from one base preset to another (e.g. Heroicons → Lucide):

  1. Install the new icon package:
composer require mallardduck/blade-lucide-icons
  1. Update your config:
'icons' => [
    'preset' => 'lucide',
],

All WireKit components now use Lucide icons — no template changes needed.

To add the stackable extension preset heroicons-marketing on top of an existing base preset, switch from the singular preset key to the plural presets array — see the Stackable Presets section below for the full pattern. No additional Composer install is needed; it reuses the blade-ui-kit/blade-heroicons package the base heroicons preset already requires. (heroicons-app is still a valid preset name so an older published config keeps booting, but it is empty — stacking it changes nothing.)

Semantic Aliases

WireKit defines a set of abstract icon names. Every base preset (heroicons, lucide, phosphor, tabler) maps the complete set. The stackable extension preset heroicons-marketing instead adds its own aliases on top of a base — see the Available Presets section for the per-preset alias counts.

The tables below list every alias against every base preset — one abstract name, four identifiers, so you can look a word up on whichever preset your project is actually configured for. Completeness here is checked rather than promised, in both directions: a test compares every cell against the presets and fails the build when an alias exists in the package and not on this page, and a second one fails when a base preset has no column at all.

For the authoritative list, ask the package rather than this page:

# 1. Every alias in every configured preset, grouped by preset.
php artisan wirekit:icons

# 2. Just the names, one per line — pipe it into a grep when you are
#    looking for whether a particular alias exists.
php artisan wirekit:icons --as=aliases

# 3. One preset only, as JSON, for tooling.
php artisan wirekit:icons --preset=heroicons --as=json

That command reads the presets your application has configured, so it is right for your install and cannot go stale the way a hand-maintained table does — this one had drifted well short of the real set before anyone noticed.

Alias Usage Heroicons Lucide Phosphor Tabler
close Modal close, dismiss heroicon-m-x-mark lucide-x phosphor-x tabler-x
menu Mobile nav toggle heroicon-m-bars-3 lucide-menu phosphor-list tabler-menu-2
search Search input heroicon-m-magnifying-glass lucide-search phosphor-magnifying-glass tabler-search
click A pointer acting on something — call to action, interactive hint heroicon-m-cursor-arrow-rays lucide-mouse-pointer-click phosphor-cursor-click tabler-click
chevron-down Select, dropdown heroicon-m-chevron-down lucide-chevron-down phosphor-caret-down tabler-chevron-down
chevron-up Accordion toggle heroicon-m-chevron-up lucide-chevron-up phosphor-caret-up tabler-chevron-up
chevron-left Pagination, back heroicon-m-chevron-left lucide-chevron-left phosphor-caret-left tabler-chevron-left
chevron-right Pagination, forward heroicon-m-chevron-right lucide-chevron-right phosphor-caret-right tabler-chevron-right
check Checkbox, success heroicon-m-check lucide-check phosphor-check tabler-check
plus Add button heroicon-m-plus lucide-plus phosphor-plus tabler-plus
minus Remove, collapse heroicon-m-minus lucide-minus phosphor-minus tabler-minus
more Overflow menu — the actions a row keeps out of sight heroicon-m-ellipsis-horizontal lucide-ellipsis phosphor-dots-three tabler-dots
chevron-up-down A pop-up button: shows the current choice, opens the others heroicon-m-chevron-up-down lucide-chevrons-up-down phosphor-caret-up-down tabler-caret-up-down
more-vertical Overflow menu on its vertical axis, the usual row-action trigger heroicon-m-ellipsis-vertical lucide-ellipsis-vertical phosphor-dots-three-vertical tabler-dots-vertical
arrows-left-right Swap, transfer, move between two sides heroicon-m-arrows-right-left lucide-arrow-left-right phosphor-arrows-left-right tabler-arrows-left-right
hash An identifier, a channel, a tag heroicon-m-hashtag lucide-hash phosphor-hash tabler-hash
shield-warning A protection that needs attention heroicon-m-shield-exclamation lucide-shield-alert phosphor-shield-warning tabler-shield-exclamation
prohibit Blocked, not permitted heroicon-m-no-symbol lucide-ban phosphor-prohibit tabler-ban
scan Scan a code, frame a subject heroicon-m-viewfinder-circle lucide-scan phosphor-scan tabler-scan

Status and Feedback

Alias Usage Heroicons Lucide Phosphor Tabler
info Info alert heroicon-m-information-circle lucide-info phosphor-info tabler-info-circle
success Success alert heroicon-m-check-circle lucide-check-circle-2 phosphor-check-circle tabler-circle-check
warning Warning alert heroicon-m-exclamation-triangle lucide-alert-triangle phosphor-warning tabler-alert-triangle
danger Error/danger alert heroicon-m-x-circle lucide-x-circle phosphor-x-circle tabler-circle-x

The four status names (info, success, warning, danger) are intentionally shared between this icon namespace and the canonical intent values on components like <x-wirekit::badge> and <x-wirekit::alert>. Use <x-wirekit::icon name="info"> next to <x-wirekit::badge intent="info"> and both read identically across every theme preset. The shared keyword is a feature, not a namespace collision.

Objects and Visibility

Alias Usage Heroicons Lucide Phosphor Tabler
user Avatar fallback heroicon-m-user lucide-user phosphor-user tabler-user
calendar Datepicker heroicon-m-calendar lucide-calendar phosphor-calendar-blank tabler-calendar
trash Delete action heroicon-m-trash lucide-trash-2 phosphor-trash tabler-trash
edit Edit action heroicon-m-pencil-square lucide-pencil phosphor-pencil-simple tabler-edit
eye Show/reveal heroicon-m-eye lucide-eye phosphor-eye tabler-eye
eye-off Hide/password toggle heroicon-m-eye-slash lucide-eye-off phosphor-eye-slash tabler-eye-off
upload File upload heroicon-m-arrow-up-tray lucide-upload phosphor-upload-simple tabler-upload
download File download heroicon-m-arrow-down-tray lucide-download phosphor-download-simple tabler-download
sort-asc Table sort ascending heroicon-m-bars-arrow-up lucide-arrow-up-a-z phosphor-sort-ascending tabler-sort-ascending
sort-desc Table sort descending heroicon-m-bars-arrow-down lucide-arrow-down-z-a phosphor-sort-descending tabler-sort-descending
filter Table filter heroicon-m-funnel lucide-filter phosphor-funnel tabler-filter
external-link External link heroicon-m-arrow-top-right-on-square lucide-external-link phosphor-arrow-square-out tabler-external-link

App and SaaS

Alias Usage Heroicons Lucide Phosphor Tabler
settings / gear Settings, preferences heroicon-m-cog-6-tooth lucide-settings phosphor-gear tabler-settings
dashboard Dashboard, overview heroicon-m-squares-2x2 lucide-layout-dashboard phosphor-squares-four tabler-layout-dashboard
billing / credit-card Billing, payment method heroicon-m-credit-card lucide-credit-card phosphor-credit-card tabler-credit-card

Infrastructure and system

Alias Usage Heroicons Lucide Phosphor Tabler
server Hosting, infrastructure heroicon-m-server lucide-server phosphor-hard-drives tabler-server
database Data store, records heroicon-m-circle-stack lucide-database phosphor-database tabler-database
cloud Cloud service, sync heroicon-m-cloud lucide-cloud phosphor-cloud tabler-cloud
shield / shield-check Security, protection heroicon-m-shield-check lucide-shield-check phosphor-shield-check tabler-shield-check
inbox Inbox, incoming heroicon-m-inbox lucide-inbox phosphor-tray tabler-inbox
bolt Speed, power, action heroicon-m-bolt lucide-zap phosphor-lightning tabler-bolt
refresh Refresh, retry, sync heroicon-m-arrow-path lucide-refresh-cw phosphor-arrows-clockwise tabler-refresh
undo Undo, revert a change heroicon-m-arrow-uturn-left lucide-undo phosphor-arrow-counter-clockwise tabler-arrow-back-up

Content and chrome

Alias Usage Heroicons Lucide Phosphor Tabler
home Home link, breadcrumb root heroicon-m-home lucide-home phosphor-house tabler-home
sign-out Log out heroicon-m-arrow-right-on-rectangle lucide-log-out phosphor-sign-out tabler-logout
moon Dark theme toggle heroicon-m-moon lucide-moon phosphor-moon tabler-moon
sun Light theme toggle heroicon-m-sun lucide-sun phosphor-sun tabler-sun
system Theme follows the operating system — the third state beside sun and moon heroicon-m-computer-desktop lucide-monitor phosphor-monitor tabler-device-desktop
code Code block, snippet, developer surface heroicon-m-code-bracket lucide-code phosphor-code tabler-code
paint-brush Theming, appearance, anything a developer paints heroicon-m-paint-brush lucide-paintbrush phosphor-paint-brush tabler-brush
key API key, credential, access heroicon-m-key lucide-key phosphor-key tabler-key
rocket-launch Launch, ship, get started heroicon-m-rocket-launch lucide-rocket phosphor-rocket-launch tabler-rocket
broadcast Channels, publishing, going live heroicon-m-radio lucide-radio phosphor-broadcast tabler-broadcast
chart-bar Reporting, analytics, comparison heroicon-m-chart-bar lucide-chart-bar phosphor-chart-bar tabler-chart-bar
coins Payments, balances, cash on hand heroicon-m-banknotes lucide-coins phosphor-coins tabler-coins
gift Vouchers, rewards, something included heroicon-m-gift lucide-gift phosphor-gift tabler-gift
list-bullets A plain list of items heroicon-m-list-bullet lucide-list phosphor-list-bullets tabler-list
list-checks Tasks, checklists, things to tick off heroicon-m-clipboard-document-check lucide-list-checks phosphor-list-checks tabler-list-check
lock-key Access, roles, permissions heroicon-m-lock-closed lucide-lock-keyhole phosphor-lock-key tabler-lock
map-pin Locations, branches, an address heroicon-m-map-pin lucide-map-pin phosphor-map-pin tabler-map-pin
percent Discounts, tax rates, margins heroicon-m-percent-badge lucide-percent phosphor-percent tabler-percentage
sliders Settings, filters, fine-tuning heroicon-m-adjustments-horizontal lucide-sliders phosphor-sliders tabler-adjustments
trend-up A metric moving up over time heroicon-m-arrow-trending-up lucide-trending-up phosphor-trend-up tabler-trending-up
chart-line Trend over time, analytics heroicon-m-presentation-chart-line lucide-chart-line phosphor-chart-line tabler-chart-line
folders A collection of folders, a workspace heroicon-m-folder lucide-folders phosphor-folders tabler-folders
phone Telephone, voice call heroicon-m-phone lucide-phone phosphor-phone tabler-phone
book / book-open Documentation, guide heroicon-m-book-open lucide-book-open phosphor-book-open tabler-book
file-text Document, article heroicon-m-document-text lucide-file-text phosphor-file-text tabler-file-text
copy Copy to clipboard heroicon-m-clipboard-document lucide-copy phosphor-copy tabler-copy
globe Language, region, public heroicon-m-globe-alt lucide-globe phosphor-globe tabler-world
map Location, directions heroicon-m-map lucide-map phosphor-map-trifold tabler-map
lightbulb Tip, idea, suggestion heroicon-m-light-bulb lucide-lightbulb phosphor-lightbulb tabler-bulb
megaphone Announcement, changelog heroicon-m-megaphone lucide-megaphone phosphor-megaphone tabler-speakerphone

People, time and records

Alias Usage Heroicons Lucide Phosphor Tabler
users Team, members, accounts heroicon-m-users lucide-users phosphor-users tabler-users
history Activity log, recent heroicon-m-clock lucide-history phosphor-clock-counter-clockwise tabler-history
legal Terms, compliance heroicon-m-scale lucide-scale phosphor-scales tabler-scale
badge Identity, credential heroicon-m-identification lucide-badge-check phosphor-identification-badge tabler-badge
layers Grouping, versions, variants heroicon-m-square-3-stack-3d lucide-layers phosphor-stack tabler-stack-2
stack Stacked items — the same glyph as layers, under the other name for it heroicon-m-square-3-stack-3d lucide-layers phosphor-stack tabler-stack-2

Notifications, mail and media

Alias Usage Heroicons Lucide Phosphor Tabler
bell Notifications heroicon-m-bell lucide-bell phosphor-bell tabler-bell
bell-slash Notifications muted heroicon-m-bell-slash lucide-bell-off phosphor-bell-slash tabler-bell-off
message Conversation, comments heroicon-m-chat-bubble-left-right lucide-message-circle phosphor-chat-circle tabler-message-circle
send Send message, submit heroicon-m-paper-airplane lucide-send phosphor-paper-plane-tilt tabler-send
envelope Email address, mailbox heroicon-m-envelope lucide-mail phosphor-envelope tabler-mail
store Shop, storefront, point of sale heroicon-m-building-storefront lucide-store phosphor-storefront tabler-building-store
cart Shopping cart, basket heroicon-m-shopping-cart lucide-shopping-cart phosphor-shopping-cart tabler-shopping-cart
receipt Receipt, proof of purchase heroicon-m-receipt-percent lucide-receipt phosphor-receipt tabler-receipt
truck Delivery, shipment heroicon-m-truck lucide-truck phosphor-truck tabler-truck
package Parcel, stock item heroicon-m-archive-box lucide-package phosphor-package tabler-package
barcode Scan an article heroicon-m-qr-code lucide-barcode phosphor-barcode tabler-barcode
cash-register The till itself, where the receipts come from heroicon-m-calculator lucide-calculator phosphor-cash-register tabler-cash-register
user-add Invite or add a person heroicon-m-user-plus lucide-user-plus phosphor-user-plus tabler-user-plus
user-remove Remove a person heroicon-m-user-minus lucide-user-minus phosphor-user-minus tabler-user-minus
building Organization, tenant, site heroicon-m-building-office lucide-building phosphor-building tabler-building
webhook Outbound callback URL heroicon-m-link lucide-webhook phosphor-webhooks-logo tabler-webhook
arrow-left Back, previous heroicon-m-arrow-left lucide-arrow-left phosphor-arrow-left tabler-arrow-left
clock Time, duration, history heroicon-m-clock lucide-clock phosphor-clock tabler-clock
lock Locked, restricted heroicon-m-lock-closed lucide-lock phosphor-lock tabler-lock
reply Reply to message heroicon-m-arrow-uturn-left lucide-reply phosphor-arrow-bend-up-left tabler-arrow-back-up
forward Forward message heroicon-m-arrow-uturn-right lucide-forward phosphor-arrow-bend-up-right tabler-arrow-forward-up
archive Archive, move out of inbox heroicon-m-archive-box lucide-archive phosphor-archive tabler-archive
tag Label, category heroicon-m-tag lucide-tag phosphor-tag tabler-tag
image Picture, media attachment heroicon-m-photo lucide-image phosphor-image tabler-photo

Media controls

Alias Usage Heroicons Lucide Phosphor Tabler
play Start playback heroicon-m-play lucide-play phosphor-play tabler-player-play
pause Pause playback heroicon-m-pause lucide-pause phosphor-pause tabler-player-pause
stop Stop playback heroicon-m-stop lucide-square phosphor-stop tabler-player-stop
speaker Audio on, volume heroicon-m-speaker-wave lucide-volume-2 phosphor-speaker-high tabler-volume
mute Audio off heroicon-m-speaker-x-mark lucide-volume-x phosphor-speaker-slash tabler-volume-off
microphone Record, voice input heroicon-m-microphone lucide-mic phosphor-microphone tabler-microphone

Each preset column shows the Blade icon identifier — the exact string that gets passed to the @svg() directive. You can use these identifiers directly if you need an icon outside of WireKit's alias system; take them from the column for the preset you have configured, since the same alias resolves to a different identifier on each one.

Raw-name fallthrough

If you pass a name that isn't a curated alias but does match an icon in your active preset's library, WireKit resolves it directly to that icon and logs an informational dev hint — for example <x-wirekit::icon name="briefcase" /> resolves to heroicon-m-briefcase on the default preset. This lets you reach any icon in the underlying set without registering an alias first. A name that matches neither an alias nor a real icon throws an InvalidArgumentException with a "did you mean" suggestion. To silence the dev hint for an icon you reach for often, register it as a project alias.

Using a raw icon name instead of an alias

An icon name the vocabulary does not define still resolves, if the icon package provides it:

{{-- `gear-six` is not an alias — it is Phosphor's own glyph name --}}
<x-wirekit::icon name="gear-six" />

This is supported, and it couples your application to the icon package rather than to WireKit. That trade is worth stating plainly, because the failure is delayed and lands somewhere unrelated:

  • The name resolves because the full package is installed and answers it directly. The alias vocabulary is bypassed.
  • Restrict that package to the icons you actually render — a reasonable thing to do, since a set can carry thousands and the manifest is built per boot — and the raw names stop resolving. One application hit exactly that: the restriction had to be reverted because four test files depended on raw names.
  • Rename or reorganize glyphs upstream and the same thing happens on a package update.

A fallthrough is logged at info level in development, naming the icon and suggesting you add it to your preset. That log is the only signal you get, so it is worth reading.

When to reach for it anyway: a glyph the vocabulary genuinely has no concept for, or a specific variant where the alias picks a different one (gear resolves to Phosphor's gear, not gear-six). Both are legitimate — just know you have taken on the coupling.

When not to: anything the vocabulary already names. home rather than house, legal rather than scales, history rather than clock-counter-clockwise. Those hold whichever preset is configured; the raw names hold only while one particular package is fully installed.

If a concept is missing from the vocabulary — or is there under a name you would not have guessed — that is worth reporting. Several of the names above exist because somebody said so: the admin-navigation group came from an application that had reached past it for raw glyph names, and stack was added afterwards because that was the word it had reached for.

Everywhere, not only on Heroicons

These words used to live in the stackable heroicons extensions, which emit heroicon identifiers exclusively — so a Lucide, Phosphor or Tabler install could not reach them, and stacking an extension resolved the name onto a glyph that set does not ship. Each one below was checked against the real SVG files of all four sets before it moved here.

Alias Usage Heroicons Lucide Phosphor Tabler
arrow-down Sort descending, move down, download direction heroicon-m-arrow-down lucide-arrow-down phosphor-arrow-down tabler-arrow-down
arrow-right Forward, next step, "continue" affordance heroicon-m-arrow-right lucide-arrow-right phosphor-arrow-right tabler-arrow-right
arrow-up Sort ascending, move up, back to top heroicon-m-arrow-up lucide-arrow-up phosphor-arrow-up tabler-arrow-up
arrow-up-right Diagonal direction, trending up, go to heroicon-m-arrow-up-right lucide-arrow-up-right phosphor-arrow-up-right tabler-arrow-up-right
chart-pie Share of total, composition breakdown heroicon-m-chart-pie lucide-chart-pie phosphor-chart-pie tabler-chart-pie
code-bracket Developer surface, API reference heroicon-m-code-bracket lucide-code phosphor-code tabler-code
cog-6-tooth Settings, configuration heroicon-m-cog-6-tooth lucide-settings phosphor-gear tabler-settings
cube Product, module, package heroicon-m-cube lucide-box phosphor-cube tabler-cube
sparkles Generated, enhanced, AI heroicon-m-sparkles lucide-sparkles phosphor-sparkle tabler-sparkles
command-line CLI, terminal, shell command heroicon-m-command-line lucide-terminal phosphor-terminal tabler-terminal
finger-print Identity, authentication, biometrics heroicon-m-finger-print lucide-fingerprint phosphor-fingerprint tabler-fingerprint
fire Trending, hot, high activity heroicon-m-fire lucide-flame phosphor-fire tabler-flame
heart Favorite, like, saved heroicon-m-heart lucide-heart phosphor-heart tabler-heart
attach Attach a file, attachment heroicon-m-paper-clip lucide-paperclip phosphor-paperclip tabler-paperclip
link Copy link, linked resource heroicon-m-link lucide-link phosphor-link tabler-link
live Live status, streaming, real time heroicon-m-signal lucide-radio phosphor-radio tabler-radio
lock-closed Locked, private, restricted heroicon-m-lock-closed lucide-lock phosphor-lock tabler-lock
open-source Open source, public repository heroicon-m-code-bracket lucide-git-branch phosphor-git-branch tabler-git-branch
puzzle-piece Plugin, integration, extension heroicon-m-puzzle-piece lucide-puzzle phosphor-puzzle-piece tabler-puzzle
security Security posture, protection heroicon-m-lock-closed lucide-shield phosphor-shield tabler-shield
speed Performance, fast path heroicon-m-bolt lucide-gauge phosphor-gauge tabler-gauge
squares-2x2 Grid view, dashboard layout heroicon-m-squares-2x2 lucide-grid-2x2 phosphor-squares-four tabler-layout-grid
star Rating, starred, highlight heroicon-m-star lucide-star phosphor-star tabler-star
swatch Theme, palette, colors heroicon-m-swatch lucide-palette phosphor-swatches tabler-palette
unlock Unlocked, granted, opened heroicon-m-lock-open lucide-unlock phosphor-lock-open tabler-lock-open
user-group Team, members, audience heroicon-m-user-group lucide-users phosphor-users tabler-users
x-circle Error state, removed, rejected heroicon-m-x-circle lucide-x-circle phosphor-x-circle tabler-circle-x

Overriding Individual Aliases

Override specific aliases without changing the entire preset. This is useful when you prefer one icon from a different set:

'icons' => [
    'preset' => 'heroicons',
    'aliases' => [
        'close' => 'lucide-x',  // Use Lucide's X for close only
    ],
],

Per-alias overrides require the corresponding Blade icon package to be installed. In the example above, both blade-heroicons (for the preset) and blade-lucide-icons (for the override) must be in your composer.json.

Need just one alias from a stackable extension preset? Map it directly here instead of stacking the whole preset. For example, the live marketing alias lives only in heroicons-marketing — if it's the single alias you need, mapping it by hand is lighter than activating the full extension (and heroicon-m-signal ships in the blade-heroicons package the base preset already requires, so there's no extra install):

'icons' => [
    'preset' => 'heroicons',
    'aliases' => [
        'live' => 'heroicon-m-signal',  // one marketing alias, no preset stacking
    ],
],

Reach for presets stacking (see Available Presets) only when you use many aliases from an extension.

live deliberately stays a marketing alias rather than joining the base presets: unlike copy / globe / book / lightbulb (which map to an equivalent glyph in every base library), it has no clean universal-core equivalent — signal / radio / broadcast differ per icon set — so the choice of glyph is left to you via the override above.

Custom Presets

Create a class implementing Pushery\WireKit\Contracts\IconPreset to use any icon set:

use Pushery\WireKit\Contracts\IconPreset;

class MyIconPreset implements IconPreset
{
    public function icons(): array
    {
        return [
            'close' => 'my-icon-x',
            'menu' => 'my-icon-menu',
            'search' => 'my-icon-search',
            // ... every semantic alias must be mapped
        ];
    }

    public function requires(): string
    {
        return 'vendor/my-blade-icons';  // Composer package name
    }
}

Then set it in config:

'icons' => [
    'preset' => \App\Icons\MyIconPreset::class,
],

Programmatic Usage

Resolve aliases in PHP code (useful in Livewire components or service classes):

use Pushery\WireKit\WireKit;

$iconName = WireKit::icon('close'); // Returns 'heroicon-m-x-mark' (with heroicons preset)

Behavior

Scenario Result
Preset configured + package installed Icon renders as inline SVG
blade-icons not installed RuntimeException with install instructions
Unaliased name that matches a real icon Resolves to the underlying icon + logs an INFO dev hint (see Raw-name fallthrough)
Unknown name with no matching icon InvalidArgumentException with a "did you mean" suggestion
Unknown preset (local) InvalidArgumentException listing available presets
Unknown preset (production) Exception — validate presets before deploy

Production

Cache icons for better performance in production:

php artisan icons:cache

To clear the cache (e.g. after adding new icons):

php artisan icons:clear

Asking what the vocabulary knows

WireKit::icon() tells you what will render. It cannot tell you whether WireKit recognized the name, because it always answers: a name that is not an alias falls through to the icon set's own naming, and a real glyph name resolves that way too.

Two helpers answer the other question — useful when a tool offers completion, or when you want to check a design system's names against the ones that exist here:

// 1. Is this a name WireKit DECLARES? Not "will it render" — that is icon().
WireKit::isIconAlias('webhook');   // true  — a declared alias
WireKit::isIconAlias('x-mark');    // false — renders, but only via the fallthrough
WireKit::isIconAlias('not-a-name'); // false

// 2. The whole declared vocabulary, alias => blade-icons identifier.
WireKit::iconVocabulary();          // ['close' => 'heroicon-m-x-mark', 'webhook' => …]

The vocabulary follows your configuration: the presets you stacked, in their precedence order, with your own icons.aliases last. It deliberately excludes the fallthrough — a list that contained every renderable glyph name would answer yes to everything, which is the same as answering nothing.

Props

Prop Type Default Description
name string null Semantic icon alias (e.g. 'close', 'search', 'trash')
size string|null null Icon size: xs (12px), sm (16px), md (20px), lg (24px), xl (32px). When null, defaults to h-5 w-5 (20px).

All other attributes are passed through to the underlying SVG element (e.g. class, aria-hidden).

Sizing

The size prop sets the icon's width and height to a token-aligned size class. When size is null (default), the historical h-5 w-5 (20px) class is applied — back-compat is preserved for every existing call site.

<x-wirekit::icon name="search" size="xs" />  {{-- h-3 w-3 → 12px --}}
<x-wirekit::icon name="search" size="sm" />  {{-- h-4 w-4 → 16px --}}
<x-wirekit::icon name="search" size="md" />  {{-- h-5 w-5 → 20px (same as default) --}}
<x-wirekit::icon name="search" size="lg" />  {{-- h-6 w-6 → 24px --}}
<x-wirekit::icon name="search" size="xl" />  {{-- h-8 w-8 → 32px --}}

search is in the default heroicons preset; if you want cursor-arrow-rays / pulse and other marketing-flavored aliases, opt into the extension preset via wirekit.icons.presets => ['heroicons', 'heroicons-marketing']. Run php artisan wirekit:icons --preset=heroicons-marketing to see the full alias list.

Passing an invalid size triggers WireKit::validateProp() — throws InvalidArgumentException in debug, falls back to xs and logs a warning in production. To override the size with a custom Tailwind class, omit the size prop and pass class="h-10 w-10" directly.

Accessibility

Icons are either decorative (purely visual, meaning conveyed by adjacent text) or informative (they carry meaning on their own). WireKit defaults to decorative because the vast majority of icons in a UI accompany a text label.

Decorative Icons (Default)

An icon next to a text label is decorative. Screen readers should skip it to avoid duplicate announcements. WireKit automatically adds aria-hidden="true" in this case — you don't have to do anything.

<!-- "Delete" is already announced — icon is skipped by screen readers -->
<x-wirekit::button>
    <x-wirekit::icon name="trash" />
    Delete
</x-wirekit::button>

Rendered output:

<svg aria-hidden="true" class="h-5 w-5" ...></svg>

Informative Icons (Icon-Only Buttons)

When an icon stands alone (no visible text), it becomes the accessible name. Pass aria-label — WireKit detects this and will not add aria-hidden, so the icon is exposed to assistive tech.

<!-- Icon-only close button: icon itself carries the label -->
<button type="button" aria-label="Close dialog">
    <x-wirekit::icon name="close" />
</button>

A second, widely-used pattern is the sr-only text node inside the button — this leaves the <svg> decorative while giving the button an accessible name:

<button type="button">
    <x-wirekit::icon name="close" />
    <span class="sr-only">Close dialog</span>
</button>

Both approaches are valid. The sr-only pattern keeps the icon purely decorative (cleaner SVG output) and is slightly more robust against future label changes.

Informative Icons Inside Text

If an icon communicates something independently of nearby text (e.g. a status indicator), set role="img" + aria-label:

<span>
    Order status:
    <x-wirekit::icon name="success" role="img" aria-label="completed" />
</span>

WireKit detects role="img" and omits the automatic aria-hidden.

Detection Rules

WireKit decides automatically based on the attributes you pass:

Attribute you pass WireKit adds aria-hidden="true"?
None (default) Yes — decorative
aria-label="..." No — informative
aria-labelledby="..." No — informative
role="img" No — informative
aria-hidden="true" (explicit) Respected — your value wins
aria-hidden="false" (explicit) Respected — forces exposure

Further Reading

Keyboard Interaction

This component is purely presentational and does not respond to keyboard input.

Pitfalls

  • Don't ship <x-wirekit::icon> without an aria-label if it carries meaning. Icons are aria-hidden="true" by default — perfect for decorative flourishes, wrong for icon-only buttons. Set aria-label on the surrounding button instead.
  • Don't use class="h-N w-N" to size icons. Use the size="xs|sm|md|lg|xl" prop instead — it ensures the size is token-driven and consistent across the project.

Design Tokens

The icon component renders raw <svg> markup with currentColor so color follows the surrounding text token. Sizing uses Tailwind utility classes (h-4 w-4, etc.) rather than design tokens, mirroring the rest of WireKit's icon usage. The icon doesn't reach for tokens directly — its color and size come from whichever component or context renders it.

Source Used for
currentColor (CSS keyword) SVG fill / stroke — inherits from parent color (any --color-wk-text / --color-wk-accent / --color-wk-danger etc. set on the parent)
Tailwind h-* w-* Width + height (structural, not themed)

Was this page helpful?

Thanks — that helps.

Voting requires cookies or local storage. What we store