poldixd/laravel-feather
A Laravel package that integrates Feather Icons into Blade views, offering a simple component to render lightweight, customizable inline SVG icons with attributes for size, color, and CSS classes.
poldixd/laravel-feather is a thin Blade wrapper around the Feather icon set. Icons are shipped as Blade views and rendered as inline SVG — no network request, no build step, no JS.
Install.
composer require poldixd/laravel-feather
Laravel's package discovery registers the service provider automatically. There is no migration and, in the common case, nothing to publish before first use.
Look here first. In order:
vendor/poldixd/laravel-feather/resources/views/ — the icon views themselves plus whatever wrapper component/include ships with them. This is the authoritative answer to "what is the component called and which attributes does it accept."vendor/poldixd/laravel-feather/README.md — the documented quickstart syntax.vendor/poldixd/laravel-feather/src/ — the provider tells you the view namespace and whether a config file exists.Confirm the namespace rather than guessing: php artisan view:list | grep -i feather.
First use case: one icon in an existing button partial. Pick something you already render on a page you look at constantly.
{{-- component form --}}
<x-feather-icon name="check" class="w-4 h-4" />
{{-- include form --}}
@include('feather::icon', ['name' => 'check', 'class' => 'w-4 h-4'])
Use whichever form the README documents as canonical; the other exists for cases the component can't cover (see below).
Verify in the source, not the browser. View-source the page and confirm you got <svg ... fill="none" stroke="currentColor" viewBox="0 0 24 24"> and not an empty element. A blank icon is almost always a wrong name or a view that failed to resolve — not a CSS problem.
Wrap it once, use your wrapper everywhere. Create resources/views/components/icon.blade.php that forwards to the package and pins your house defaults (stroke width, default size, aria-hidden). Every call site then says <x-icon name="user" />, and swapping to blade-ui-kit/blade-icons or Heroicons later is a one-file change. This is the single highest-leverage thing you can do with a package this small.
Size and colour through CSS, stroke through props. Feather icons are stroke-based and inherit currentColor, so the idiomatic Tailwind usage is <x-feather-icon name="trash" class="w-5 h-5 text-red-600" /> inside a text-* context. Reserve the component's own size/stroke-width/color attributes for cases where you can't reach the icon with a utility class (email templates, PDF rendering, third-party markup).
Dynamic names. For icon names driven by data (nav config, menu models), keep an allowlist and use the component form:
@php $icon = in_array($item->icon, config('ui.icons')) ? $item->icon : 'circle'; @endphp
<x-feather-icon :name="$icon" class="w-5 h-5" />
When the name itself is computed and you'd otherwise need <x-dynamic-component>, the @include form is often simpler and more readable:
@include("feather::{$icon}", ['class' => 'w-5 h-5'])
Pair it with your button/link components. The natural integration point is resources/views/components/button.blade.php, nav-link.blade.php, alert.blade.php — accept an icon prop and render the icon before the slot. This keeps icon markup out of twenty call sites.
Decorative vs. meaningful. Default to aria-hidden="true" and focusable="false" in your wrapper. For icon-only buttons, put the accessible name on the button (aria-label or an sr-only span), not on the SVG.
Keep a small partial for icon+label (<x-icon-label icon="download" label="Export" />) so spacing (gap-2) is consistent and doesn't drift per page.
Livewire/Alpine are fine. The SVG is server-rendered once into the DOM; toggling classes on a parent is the cheapest way to animate or recolour. Avoid re-rendering long icon-heavy lists on every poll if you can paginate instead.
Deploy with php artisan view:cache. Each icon is a compiled Blade view. First-request compilation of a dozen partials is avoidable latency; caching them costs nothing.
Pin to your framework major. This package's major tracks Laravel's (13.x targets Laravel 13). On a Laravel 11/12 app, stay on the matching older major; do not force 13.x early.
Test behaviour, not markup. assertSee('feather', false) or assertSee('<svg', false) on a page that uses your wrapper is enough. Don't snapshot full SVG paths — a Feather version bump will churn every snapshot for zero signal.
fill on a Feather icon. They're designed for fill="none" stroke="currentColor". A global svg { fill: currentColor } in your CSS base layer will turn outline icons into weird blobs. Scope any global SVG reset.currentColor surprises. If an icon is the wrong colour, the icon isn't broken — an ancestor's color is. Check the button/link's text-* class before touching the icon.size attribute (which emits width/height presentation attributes) with w-5 h-5 utilities works most of the time because CSS beats presentation attributes, but it's the classic source of "why is this icon 24px in one place and 20px in another". Put sizing in the wrapper's defaults and use classes at call sites; don't do both.class handling to your own icon.blade.php, remember $attributes->merge(['class' => '...']) — otherwise passing class="text-red-600" from a call site silently drops your defaults.blade-ui-kit/blade-icons, x-icon / x-feather prefixes can collide or shadow each other. Decide on one icon system, or register the package under a distinct prefix via Blade::componentNamespace().name. Even if the package throws rather than resolving arbitrary paths, an allowlist is the correct posture and gives you a clean fallback.resources/views/vendor/feather to tweak them, they shadow the package's copies forever. After each upgrade, diff that directory against the vendor one. Prefer wrapping over forking; if you must fork, do it for one or two icons only.php artisan view:clear (and config:clear, composer dump-autoload). Compiled icon views are the most likely stale artifact, and the symptom — an old or missing SVG — looks like a bug in the package. php artisan about confirms the provider is discovered; view:list confirms the namespace.<use> instead, or trim the icon set at build time.src/ — with a package this thin, a private API dependency is easy to introduce accidentally and will not appear in a changelog.How can I help you explore Laravel packages today?