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 Evil Icons Laravel Package

codeat3/blade-evil-icons

Blade Evil Icons provides easy, expressive Blade components for the Evil Icons SVG icon set in Laravel. Drop icons into your views with a simple x-evil-icon tag, control size and color via attributes, and keep your markup clean without extra JavaScript or asset pipelines.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and confirm discovery.

composer require codeat3/blade-evil-icons:^1.7
composer show codeat3/blade-evil-icons   # confirm resolved version + constraints

There is no publish step, no config file, no service provider to register — Laravel package auto-discovery picks it up. The only thing worth checking before you write a single template is the constraint set in the installed composer.json: whether ^1.7 widens the Laravel range (e.g. 10–13) or pins to 13 only. That single fact decides whether your other environments can even composer update.

Look here first — the actual icon list. Don't trust blog posts or the upstream Evil Icons website; the package ships the set as files and the name attribute maps to the filename:

ls vendor/codeat3/blade-evil-icons/resources/svg | sed 's/\.svg$//' | column -c 100

That is your authoritative vocabulary (search, close, close-o, chevron-down, sc-github, spinner-2, …). Bookmark the command; it's faster than any docs page.

First use case — one icon in a layout. Drop it into resources/views/layouts/app.blade.php where you currently have an <img src="/icons/search.svg"> or a Font Awesome <i>:

<button type="submit" class="inline-flex items-center gap-2 text-slate-600 hover:text-slate-900">
    <x-evil-o name="search" class="w-5 h-5" aria-hidden="true" />
    <span class="sr-only">Search</span>
</button>

class and any other attribute you pass land on the root <svg>, so w-5 h-5, text-*, opacity-*, and aria-hidden all work without configuration. Render the page, inspect the DOM, and confirm you see a real <svg> element rather than an empty box — that's the whole install verified.

Implementation Patterns

Wrap the set once, use your own tag everywhere. The highest-leverage day-to-day move is to never sprinkle <x-evil-o> through templates. Create resources/views/components/icon.blade.php:

@props(['name', 'size' => 'w-5 h-5'])

<x-evil-o
    :name="$name"
    {{ $attributes->class([$size, 'shrink-0']) }}
    aria-hidden="true"
    focusable="false"
/>

Then application code writes <x-icon name="gear" class="text-slate-400" />. When you outgrow Evil Icons (small, legacy, effectively frozen set), swapping to a multi-set blade-icons package is a one-file change instead of a repo-wide grep.

Drive icons from data, not from markup. Nav and action menus belong in config/arrays, with the icon name as a string:

// config/navigation.php
return [
    ['label' => 'Dashboard', 'route' => 'dashboard', 'icon' => 'chart'],
    ['label' => 'Settings',  'route' => 'settings',  'icon' => 'gear'],
];
@foreach (config('navigation') as $item)
    <a href="{{ route($item['route']) }}" class="flex items-center gap-3 px-3 py-2 rounded hover:bg-slate-100">
        <x-icon :name="$item['icon']" />
        {{ $item['label'] }}
    </a>
@endforeach

This makes icon usage greppable and testable — which matters more than it sounds (see the render test below).

Test icon names in CI, not in staging. A bad name fails at render time, and it fails deep inside a loop you may not have loaded. One cheap test covers every string you use:

it('renders every configured icon', function () {
    foreach (collect(config('navigation'))->pluck('icon')->unique() as $name) {
        $this->blade("<x-icon name=\"{$name}\" />")->assertSee('<svg', false);
    }
});

Sizing and colour conventions. Because output is inline SVG inheriting currentColor, treat icons as text: set colour with text-* on the parent and size with w-* h-* (or Tailwind v4 size-5). Don't set fill/stroke classes per-icon unless you've inspected the emitted markup — Evil Icons paths carry their own presentation attributes, and a blanket fill-current on a stroke-based glyph can make it disappear. If you need to fine-tune weight, target descendants once you've confirmed the structure:

<x-icon name="close" class="size-4 [&_path]:stroke-[2]" />

Rollout pattern: additive sweep, layout by layout. Replace ad-hoc <img src="/icons/...">, hand-copied inline <svg>, and <i class="fa ..."> tags one template at a time, keeping the legacy asset directory in place. Decommission /public/icons and the FA dependency only after grep -rn 'icons/\|fa-' resources/views comes back clean. Keep this sweep out of the same deploy as a Laravel major upgrade so a rollback is attributable to one change.

Escalation path for icon-dense pages. If a single route renders 50+ icons, inline SVG starts to hurt: emit a local <symbol> sprite partial once per request and use <use href="#evil-search"> afterwards. It's a page-local optimisation, not something to do on day one.

Gotchas and Tips

The prefix is fixed at evil-o. You can't rename it via config, which is exactly why the wrapper component above earns its keep. The set choice also has a long tail: Evil Icons is small and static, so commit to it deliberately, not per-feature.

Names are filenames, verbatim. close-o, spinner-2, sc-linkedin — hyphenated variants are real and typos produce a Blade component/argument exception at render, not a blank space. When an icon "is missing", run the ls command from Getting Started before debugging anything else.

Invisible icons are almost always colour inheritance. Inline SVG uses currentColor; if a parent sets text-transparent, text-white on white, or if a global reset applies fill: none / svg { display: block } across the app, icons vanish. Check by wrapping one icon in a <div style="color:red"> — if it appears, it's CSS, not the package.

Accessibility is your job, not the package's. The component emits bare inline SVG. Default to aria-hidden="true" focusable="false" for decorative icons and pair meaningful ones with visible or sr-only text; adding a <title> child isn't part of the tag-based API. Verify attributes actually land on the root <svg> in your version before relying on role/aria-label passthrough, and validate against your a11y requirements before customer-facing use.

CSP is a point in its favour, not a risk. Inline SVG needs no img-src or font-src, which is why this beats icon fonts and <img> for strict policies. Just don't pipe icon markup through user-content sanitizers or {!! !!} blocks.

Caching and upgrades. After a composer update or when adding your own SVGs, run php artisan view:clear (and the blade-icons cache clear if enabled) before concluding the package broke. Pin ^1.7 and commit composer.lock so CI and prod resolve identically; the realistic failure mode here is a constraint mismatch on a framework upgrade, not a runtime bug.

Livewire and payload size. Inline SVG is re-serialised with every Livewire component render. Keep decorative icons in the surrounding Blade layout rather than inside components that update on every keystroke, and check the network payload if a form-heavy screen feels sluggish.

Email is a hard stop. Blade mailables and notifications render this fine, but Gmail and Outlook strip inline SVG. Use PNG fallbacks in resources/views/vendor/mail — don't let an icon refactor quietly break transactional email.

Exit strategy, cheap to buy now. Keep a vendored copy of the SVG set (e.g. resources/svg/evil-icons/) and a NOTICE file with the Evil Icons attribution alongside the package's MIT licence. Single-maintainer, zero-dependent commodity dependencies should always be swappable — and with the wrapper component in place, swapping means editing one file and re-pointing it at your vendored copies.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource