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

codeat3/blade-mono-icons

Laravel Blade package that provides ready-to-use components for the Mono Icons set, making it easy to render crisp SVG icons directly in Blade templates with customizable size, color, and attributes—no manual SVG copying or extra setup required.

View on GitHub
Deep Wiki
Context7

Getting Started

codeat3/blade-mono-icons publishes the Mono Icons SVG set as Blade components. Each icon compiles to inline <svg> server-side — no spritesheet, no build step, no runtime request.

composer require codeat3/blade-mono-icons

The service provider is auto-discovered. Nothing to register, publish, or compile. Confirm the install and the component prefix your project actually resolves with one render:

<x-mono-icons-home class="size-5 text-gray-500" />

Where to look first, in order:

  1. vendor/codeat3/blade-mono-icons/resources/svg/ — this directory is the authoritative list of valid component names. File names are kebab-cased into the tag: arrow-left.svg → <x-mono-icons-arrow-left />. The upstream Mono Icons site uses display names that don't always match, so ls | grep this folder before guessing a tag. Bookmark it.
  2. config/blade-mono-icons.php — only matters if you want to change the component prefix or point the set at your own SVGs. Publish with php artisan vendor:publish --tag=blade-mono-icons-config. Most projects never touch it.
  3. The package README — one page; enough to be productive.

Your first real use case is almost always the same: replace hand-pasted <svg> blocks or a sprite sheet in an existing layout with a component tag, screen by screen. Do it per template, not in a big sweep — visual diff is the only reliable regression test for an icon swap.

Adopt two conventions on day one, before usage spreads:

  • Pin the version (^1.6) so icon-set drift can't surprise you on a routine composer update.
  • Never reference <x-mono-icons-*> directly in application code. Expose a single wrapper (<x-icon name="..." />) and route everything through it. This is the seam that makes a future icon-family swap, a fork, or abandonment a one-file change.

Implementation Patterns

The wrapper component (the pattern that matters most). Create resources/views/components/icon.blade.php:

@props(['name', 'label' => null])

@php
    // Whitelist resolved names to avoid arbitrary component references.
    $resolved = str_starts_with($name, 'mono-icons-') ? $name : 'mono-icons-' . $name;
@endphp

<x-dynamic-component
    :component="$resolved"
    {{ $attributes->merge(['class' => 'size-5']) }}
    @if($label) role="img" aria-label="{{ $label }}" @else aria-hidden="true" @endif
/>

Application code becomes <x-icon name="home" /> or <x-icon name="trash" class="size-4 text-red-500" label="Delete" />. The name prop is your only dependency-specific surface; a swap to another blade-* icon set or a vendored fork changes one file.

Dynamic names. Blade cannot interpolate a tag — <x-mono-icons-{{ $name }} /> will not render. Either use the wrapper above with <x-dynamic-component> (recommended), or resolve through the underlying BladeIcons facade / Svg class in a dedicated helper when you need to inspect the markup (e.g. to embed icons in a PDF or email render).

Sizing and color. The reliable lever is CSS, not props:

<x-icon name="search" class="size-4 text-gray-400" />        {{-- Tailwind --}}
<x-icon name="bell" class="w-6 h-6 stroke-current" />          {{-- explicit dims --}}

Mono Icons are stroke-based SVGs, so text-* classes drive currentColor and inherit hover states from the parent. <x-icon name="heart" class="text-red-500 group-hover:text-red-600" /> inside a group works without any custom props. If you need literal dimensions, width/height forward to the root <svg>, but prefer classes so size-* utilities stay consistent.

Icon-only interactive elements. The most common integration friction is button/link semantics. Pattern:

<button type="button" class="rounded p-2 hover:bg-gray-100">
    <x-icon name="pencil" label="Edit" class="size-4" />
</button>

An icon with a label becomes meaningful; an unlabeled icon stays decorative (aria-hidden). Never render a bare interactive icon with no accessible name. When the label duplicates adjacent visible text, leave it null and let the text carry the semantics.

Composing with components and slots. Icons slot naturally into existing Blade components. For a <x-button variant="danger" icon="trash"> pattern, pass the icon name through and render <x-icon :name="$icon" class="size-4" /> inside. This keeps the icon-set decision out of every call site.

Replacing hand-pasted SVGs. Work in this order per screen: identify the pasted <svg> blocks, map each to a Mono Icons filename via the vendor resources/svg/ directory, replace, then visually verify size and stroke weight. Old SVGs often relied on hardcoded fill="currentColor" or viewBox-scaling quirks that the package's normalized output changes; expect minor visual delta on the first few and adjust via classes rather than editing the icon.

Testing. One render test per icon actually used is worth the five minutes — it catches component-not-found and namespace changes across upgrades:

$this->get('/dashboard')
    ->assertOk()
    ->assertSee('<svg', false)
    ->assertSee('mono-icons', false);

Assert on presence of SVG output rather than exact markup; the package doesn't guarantee inner markup stability across versions.

Build-time integration. Nothing flows through Vite/Webpack — do not try to import SVG files into your CSS pipeline for these. They're server-rendered. If you have a component that renders client-side (Livewire, Inertia), the SVG still ships inline in the response, which is what you want.

Gotchas and Tips

The size / color props in the README are thinner than they sound. The package advertises size, color, and class attributes, but it is built on blade-ui-kit/blade-icons, which simply forwards attributes to the root <svg>. There is no prop validation or fallback. In practice: class (Tailwind utilities) is the lever that always works; color only works as a CSS property and is easily overridden by currentColor inheritance; use width/height if you must set literal dimensions. Don't build a design-system convention on a prop that isn't enforced.

stroke vs fill assumptions. Mono Icons are stroke-based. If you have a Tailwind reset or a local component setting fill="currentColor" globally on SVGs, a Mono icon rendered inside it can appear as a filled blob or vanish. Scope any global SVG rules with svg:not(.icon) or similar, or explicitly reset fill="none" stroke="currentColor" via classes on the wrapper.

Component prefix collisions. If you already installed another codeat3/blade-* icon package or a blade-icons set, multiple sets register their own prefixes. mono-icons is the default here, but two packages registering the same prefix will shadow each other. Check what prefixes are in play before adding a second set:

composer show | grep blade
php artisan about                # providers, in case registration fails silently

If a tag returns "component not found," confirm the prefix in the published config rather than assuming mono-icons.

Static component name resolution means renames are breaking changes. Because each icon is a compiled Blade component class, a file rename in an upstream bump turns <x-mono-icons-oldname /> into a 500 at render. The changelog only records framework-compat changes, so renames can ship without a callout. Mitigate with per-icon render tests, and the wrapper pattern, which localizes the blast radius. Read the file-count and filename diff between versions, not just the changelog.

icons:cache is available and worth using in production. blade-ui-kit/blade-icons ships php artisan icons:cache and icons:clear. In production with a warm opcache it's a marginal win, but it removes runtime directory scanning. Remember to invalidate it if you point the config at your own SVG path.

Custom icons and mixed sets are a config change, not a fork. In config/blade-mono-icons.php you can add a second path pointing at resources/svg/custom/ and drop your own SVGs there. They pick up the same component namespace. This is the right way to add a handful of branded glyphs without abandoning the package — and it's the same mechanism you'd use if the upstream set is abandoned.

Transitive constraint check before any framework upgrade. The package bump to Laravel 13 support (1.6.0) only widens its constraint. blade-ui-kit/blade-icons must also permit Laravel 13 or Composer still refuses to resolve. On a throwaway branch:

composer update --dry-run
composer why-not codeat3/blade-mono-icons 1.6.0
composer show -t

Surface this on the platform-upgrade checklist rather than discovering it mid-bump — it manifests as "cannot upgrade Laravel," not as an application error.

Autoload/classmap bloat is real but harmless at runtime. One class per icon means hundreds of entries in the Composer classmap. This shows up as IDE indexing noise and slightly larger CI caches — not a request-time cost. Exclude vendor/codeat3/blade-mono-icons from static-analysis include paths if it's slowing PHPStan down.

After publishing the config, re-cache. php artisan vendor:publish + a stale config:cache is a classic "I changed the prefix and it didn't take" bug. Run php artisan config:clear on the dev box and let your deploy pipeline rebuild caches.

Debugging "component not found" — in order: (1) does the file exist in vendor/.../resources/svg/ with exactly that kebab name, (2) is config/blade-mono-icons.php published and does it set a non-default prefix, (3) did you add a second icon package whose prefix shadows it, (4) is a stale icons:cache in play. Four checks, in that order, resolves virtually every case.

Pin and treat as vendorable. Single maintainer, low activity, but the payload is static data — a fork is a realistic contingency, not a last resort. Keep the version pinned, keep the wrapper component, and note in your front-end README that the swap point is resources/views/components/icon.blade.php. That documentation is what survives team turnover.

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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect