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_invalidto force either behavior in either context. - A fallback you configured still wins. If
blade-iconshas a fallback icon configured — per set or globally — that icon renders and WireKit never sees a failure.
Usage
<!-- 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:
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-app— empty 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-marketing—cursor-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:
- Developer
aliasesoverrides - Right-most preset in the
presetsarray (later wins) - …
- Left-most preset in the
presetsarray
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):
- Install the new icon package:
composer require mallardduck/blade-lucide-icons
- 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.
Navigation and Actions
| 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 --}}
searchis in the defaultheroiconspreset; if you wantcursor-arrow-rays/pulseand other marketing-flavored aliases, opt into the extension preset viawirekit.icons.presets => ['heroicons', 'heroicons-marketing']. Runphp artisan wirekit:icons --preset=heroicons-marketingto 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 anaria-labelif it carries meaning. Icons arearia-hidden="true"by default — perfect for decorative flourishes, wrong for icon-only buttons. Setaria-labelon the surrounding button instead. - Don't use
class="h-N w-N"to size icons. Use thesize="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) |