codeat3/blade-jam-icons
A Laravel Blade package that brings Jam Icons to your views as simple, reusable components. Render any icon with a clean Blade tag, customize size and class, and keep your markup readable without copying raw SVG by hand.
Architecture fit. This is a thin distribution wrapper, not a rendering engine: it ships static SVGs plus a service-provider registration on top of blade-ui-kit/blade-icons, which does all the component resolution and attribute passthrough. That is architecturally the right shape for a Laravel app — icons are resolved at render time into inline SVG, meaning no icon fonts, no runtime JS, no asset pipeline changes, and no CDN dependency. It fits cleanly anywhere Blade renders, including Livewire views and components, and it inherits currentColor from parent text utilities, so Tailwind sizing/coloring works without new conventions. Scope check before anything else: if the surface is Inertia/React/Vue or API-only, this package has no role — icons belong in the JS bundle.
Integration feasibility. Low. One Composer line, auto-discovered provider, no registration or config edits required to get value. The documented usage patterns are already the ones we would choose: static <x-jam-* /> calls, <x-dynamic-component :component="'jam-'.$name" /> for data-driven icons, and a house <x-icon> wrapper to keep the package name in exactly one file. The only real install-time work is dependency resolution: this brings blade-ui-kit/blade-icons and illuminate/support into the graph, so any app already carrying icon packs needs a composer update --dry-run per lockfile before committing.
Technical risk. Manageable but not zero, and the risks are concentrated in three places:
'jam-'.$row->icon) fail at render with "Unable to locate a class or view," or degrade to the configured fallback if one is set. In production that is a 500, not a build error. No static analysis catches typos. This is the highest-probability defect class introduced by adoption.jam-* is global in Blade; collisions with internal components or other codeat3/blade-* packs are possible and confusing to debug.Key questions.
<x-icon> wrapper and the published config — front-end or whoever owns the design system?Stack fit. Laravel 12/13 Blade apps, Livewire included. Version 1.8.0 exists solely to add Laravel 13 compatibility, with no API change, no deprecations, and no new icons — so it is a patch-level bump inside the same major line, not a migration. Pin ^1.8 and verify the constraint widens rather than replaces older majors; if it replaces, we are explicitly choosing a mixed-version estate and should say so in the upgrade ticket.
Migration path. Replace one hardcoded <svg> partial or one icon-font <i class="jam jam-*"> in a single layout, run php artisan view:clear, confirm the icon inherits currentColor. That first swap is the whole value proposition; everything after is scaling a proven pattern. No data migration, no schema, no runtime services, no rollback ceremony — reverting is a single revert PR.
Compatibility. The dependency graph is the compatibility surface: blade-ui-kit/blade-icons version, illuminate/support constraint, and the Laravel major. Test in the app's actual lockfile, not in the abstract — resolution deadlock is the highest-probability failure and the cheapest to find early. Also note that vendor:publish output is not tracked by Composer: once we publish the config, upstream changes to that stub stop reaching us, so re-diff it on version bumps.
Sequencing.
<x-icon name="..." size="..." /> wrapper before any rollout, with aria-hidden="true" and a default size baked in. One file becomes the only place the package is named.aria-hidden, focusable="false", sensible fallback).Maintenance. Near-zero in steady state, but with two recurring chores worth naming: config-cache and view-clear after config/wrapper edits (a stale compiled view is the most common "my class isn't applying" cause), and a re-diff of the published config stub on each bump. Upstream maintenance is one volunteer; our exposure is bounded by the fact that we hold the assets and can vendor them internally.
Support. No vendor contract, no SLA, MIT-licensed. Support is us. Escalation path is internal: the wrapper means a swap or a fork is a single-file change plus asset vendoring. Document that path — an exit plan that exists only in someone's head is not an exit plan.
Scaling. Scaling concerns are page weight, not throughput. Each icon inlines its full SVG into HTML; fine at normal densities, worth measuring on icon-per-row admin tables and icon-heavy dashboards. gzip/brotli largely neutralizes the repetition, so measure before optimizing; if a specific view is heavy, that view gets an SVG sprite or cached partial — not a package-wide change. Class-merging subtlety: class passes straight through without merging on the vendor component, so if config sets a size class and the view passes another, both apply and CSS order decides. Enforce sizing in exactly one place — the wrapper.
Failure modes.
aria-hidden plus a rule requiring text/aria-label on icon-only controls is the cheapest durable fix.Ramp-up. Effectively zero for an engineer who has used Blade components. The one onboarding step that matters: point people at vendor/codeat3/blade-jam-icons/resources/svg/ as the authoritative name list — faster and more accurate than any docs page — and tell them to use the wrapper, not the vendor component directly. One team-day to instrument the first screens; the discipline cost is "use <x-icon>," not training.
Verdict. Approve for internal tooling, admin panels, and non-brand-critical UI. Hold brand-defining iconography inside the design system. Gate approval on three things, all cheap: wrapper-first sequencing, per-lockfile dry-run, and a logged single-maintainer review trigger.
How can I help you explore Laravel packages today?