Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Blade Lucide Icons Laravel Package

technikermathe/blade-lucide-icons

technikermathe/blade-lucide-icons brings Lucide’s clean SVG icon set to Laravel Blade as a simple reusable component. Install it, render icons in your views, and customize size, color, stroke, and CSS classes with intuitive attributes for consistent lightweight UI icons.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require pascalebeier/blade-lucide-icons

No service provider registration, no publish step, no config file required — the package registers an anonymous Blade component namespace (lucide) that maps every bundled SVG to a component name.

<x-lucide-search class="size-5" />

Where to look first:

  1. vendor/pascalebeier/blade-lucide-icons/resources/views/ — one file per icon; the filename is the component name, so this directory is your authoritative icon list for the version you actually have installed.
  2. https://lucide.dev for browsing/visual search — but treat it as documentation of latest Lucide, not of your installed copy (see Gotchas).
  3. Your app's highest-traffic layout (layouts/app.blade.php, nav partial) — that's where icon sizing/colour conventions get established and copied everywhere.

First use case: replace hand-pasted inline SVGs in your nav and buttons with <x-lucide-{name} class="size-5" />, then grep for <svg in resources/views to find the remaining stragglers.

As of v3.195.0 the bundled set tracks Lucide 1.61.0.

Implementation Patterns

Attribute passthrough is the whole API. Everything lands on the root <svg>, so Tailwind utilities and ARIA attributes work directly:

<x-lucide-trash-2 class="size-4 text-red-600" stroke-width="1.5" aria-hidden="true" />

Wrap it once so sizing isn't repeated 400 times:

{{-- resources/views/components/icon.blade.php --}}
@props(['name', 'size' => 'size-5'])
<x-dynamic-component :component="'lucide-'.$name" {{ $attributes->class($size) }} aria-hidden="true" />

Dynamic names (from config, DB, enum, permission checks) go through x-dynamic-component, not string interpolation inside a tag name.

Config-driven nav / menus:

['label' => 'Dashboard', 'icon' => 'layout-dashboard', 'route' => 'dashboard']
<x-icon :name="$item['icon']" />

Colour inherits — Lucide is stroke-based and uses currentColor, so text-gray-400 hover:text-gray-900 on the parent link themes the icon for free. There is no separate "fill" or "solid" variant.

Accessibility is on you. Decorative icons need aria-hidden="true"; standalone meaningful icons need role="img" + aria-label. Bake this into the wrapper above and you never think about it again.

Production caching. Rendering ~1,700 anonymous components means a filesystem lookup per icon per request. Run the package's cache command (php artisan blade-lucide-icons:cache — confirm the exact name in the README for your version) plus php artisan view:cache in your deploy pipeline, and rebuild both on every release. Given the release cadence (see Gotchas), "every release" can mean every few days — automate it rather than remembering it.

CI guard against renames — the single highest-value habit with this package:

grep -rhoP 'x-lucide-[a-z0-9-]+' resources/views | sort -u | \
  sed 's/x-lucide-//' | while read i; do
    test -f "vendor/pascalebeier/blade-lucide-icons/resources/views/$i.blade.php" || echo "MISSING: $i"
  done

Custom/brand icons: don't jam them into the vendor directory. Register your own path with the same lucide prefix via Blade::anonymousComponentPath(resource_path('views/icons'), 'lucide') in a service provider so <x-lucide-*> resolves across both (verify precedence in your Laravel version), or keep a separate x-brand-* namespace.

Gotchas and Tips

  • Icon-sync releases are breaking releases wearing a minor-bump costume. v3.195.0 is another bare "sync Lucide to 1.61.0" shipped as a feat — the third minor in the five days between v3.192.0 (Lucide 1.58.0) and v3.195.0 (Lucide 1.61.0). Composer will pull these happily under ^3.0, and three Lucide minor versions in a week is a lot of upstream rename/deprecation churn landing in your templates. A renamed icon means Unable to locate a class or view for component [lucide-foo], or, if you use x-dynamic-component with a stale string, a hard 500 on a page you didn't touch. Pin the exact version ("pascalebeier/blade-lucide-icons": "3.195.0") and upgrade deliberately with the CI check above, or accept that composer update can break templates.
  • Treat the version bump as an icon-availability change, not a bugfix. Nothing in the 3.192 → 3.195 range adds features or fixes behaviour — the only delta is which SVGs exist. So the upgrade test you care about is "do all referenced icon names still resolve," not "do the pages still render." Diff resources/views/ between tags if you want the exact rename list.
  • Docs/version skew cuts both ways. An icon on lucide.dev may not exist in your installed version (not synced yet), and a name that worked last month may be gone after an upgrade. When a component "doesn't exist," check the vendor directory before you check the website.
  • Stale caches mask upgrades. After composer update, run php artisan view:clear and re-run the icon cache command. New icons appearing blank/404 right after an upgrade is almost always a stale cache file in bootstrap/cache — which must be generated at deploy time and never committed.
  • Don't vendor:publish on a whim. Publishing copies the whole icon set into your repo, shadows future upstream fixes, and makes upgrades a merge conflict — especially painful when upstream syncs land weekly. Publish only to override a specific icon.
  • No default size class. Unstyled icons render at the SVG's intrinsic 24px and will blow out your line-height in buttons and tables. Always pass size-*/h-* w-*.
  • Multi-class is merged, not replaced by Laravel's ComponentAttributeBag, so wrapper defaults plus call-site classes combine — useful, but it means a call-site size-8 won't override a wrapper's size-5; it'll just be contradictory CSS. Prefer a single size prop.
  • SVG + email/PDF: inline SVG is stripped by several mail clients and renders inconsistently in dompdf. Flatten to a PNG or an inline path for those outputs.
  • Namespace is taken. Don't register your own x-lucide-* components expecting precedence — collisions resolve unpredictably and are miserable to debug.
  • Extension points worth knowing: published config (cache toggle/path), published views (per-icon overrides), and Blade::anonymousComponentPath() for layering your own icons under an existing prefix.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator