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

Ux Icons Js Bundle Laravel Package

silarhi/ux-icons-js-bundle

Symfony bundle that plugs Iconify's JavaScript runtime into Symfony UX Icons, letting you render any of Iconify's 200,000+ icons on demand—no per-icon SVG imports or manual icon sets—via a single lightweight script that loads icons at runtime in your Twig templates.

View on GitHub
Deep Wiki
Context7

Getting Started

symfony/ux-icons is the icon tooling from Symfony UX: it scans icon directories, dumps them into an optimized sprite/per-icon module output under var/icons/, and gives you a thin JS runtime (icon()-style rendering, plus loadIcon/UXLazyIcon as of v0.2.0). There is no Laravel service provider — you're adopting the JS runtime plus a console command, not a package that registers itself.

Minimal path:

  1. composer require symfony/ux-icons --dev — you mainly want the CLI dumper and the IconSet/Iconify on-demand fetcher; the browser side is plain ESM.
  2. If you're not running Symfony alongside it, copy the dump command into app/Console/Commands/DumpIconsCommand.php (or shell out to it in a Composer post-autoload-dump script) and point its output at resources/icons/ or public/build/icons/ instead of var/icons/.
  3. Configure icon sources — a local directory of SVGs, or an on-demand set (heroicons, lucide, iconify prefix). Register prefixes so heroicon:user and lucide:user don't collide.
  4. Run the dump, then render in Blade with a small anonymous component:
{{-- resources/views/components/icon.blade.php --}}
@props(['name', 'size' => 24])
<svg {{ $attributes->merge(['width' => $size, 'height' => $size]) }} aria-hidden="true">
    <use href="{{ asset('build/icons/sprite.svg') }}#{{ $name }}"></use>
</svg>

First real use case: deleting a folder of hand-pasted Heroicons and replacing every <x-icon name="..."/> with one dumped set, so icons are tree-shaken and versioned together with the rest of your frontend.

Where to look first: the generated manifest (var/icons/*.php or .json) to confirm what actually got dumped, and var/icons/loaders.js — that file is the contract for the new runtime-name feature.

Implementation Patterns

Build-time dump, request-time render. Treat the dump as a build artifact, not a runtime concern. Wire it into npm run build or a post-autoload-dump Composer script so php artisan icons:dump runs before Vite compiles. Never resolve icons per-request from disk in production.

Sprite for static names, per-icon modules for dynamic names. For icons you know at compile time, the sprite + <use> (or an inlined <svg>) is cheapest. For names that only exist at runtime — a CMS "icon" field, an API payload, a user-chosen emoji set — v0.2.0 gives you the second lane:

import loaders from '../../var/icons/loaders.js';
import { loadIcon } from 'symfony/ux-icons'; // adjust to the package's JS entrypoint

async function renderDynamicIcon(name, el) {
    try {
        el.innerHTML = await loadIcon(loaders, name);
    } catch {
        el.innerHTML = await loadIcon(loaders, 'fallback-question');
    }
}

Each icon is a separate module, so the network request is one file — you're not shipping the whole set to render one glyph.

Framework components for component-driven frontends. If you're on Inertia + Vue or React, UXLazyIcon is the idiomatic wrapper: it takes name, fetches the module on mount, and renders a fallback prop/slot until it resolves.

<UXLazyIcon name="heroicon:bell" class="size-4">
  <template #fallback><span class="size-4 animate-pulse rounded bg-gray-200" /></template>
</UXLazyIcon>

Resolve var/icons in Vite. Laravel's vite.config.js doesn't know about the generated path. Add an alias so imports stay readable and survive the directory move out of Symfony's convention:

resolve: { alias: { '~icons': path.resolve(__dirname, 'resources/icons/generated') } }

Cache resolved SVG strings when the name comes from user data — Cache::remember("icon:{$name}", now()->addDay(), fn () => ...). The loader map is cheap, but you don't want a per-render module resolution on a listing page with 200 rows.

Custom icon sets as an extension point. If dumping is impractical (huge Iconify catalog), implement the package's icon-set interface against your own fetcher and let the on-demand path hit your CDN/cache instead of a local directory. That's the escape hatch when the dump gets slow.

Gotchas and Tips

  • No Laravel glue ships with it. Expect to write the console command wrapper, the Blade component, and the Vite alias yourself — roughly 30–50 lines. Budget for that, not for composer require and go.
  • var/ is a Symfony convention and is usually gitignored. In Laravel you almost certainly want output under resources/ or public/build/; if you keep var/, make sure CI regenerates it, because a fresh clone has no manifest and every icon silently renders empty.
  • Stale manifest fails silently. Adding an SVG without re-running the dump gives you an empty <use href="...#icon-foo"> with no console error. When an icon "disappears," diff the manifest against the directory first.
  • Name normalization is the #1 bug source. Prefixes (heroicon:user vs user), case, and kebab-casing all have to match between the dump, the sprite ID, and the name you pass at runtime. Unknown names in loadIcon reject — always try/catch and fall back, especially for API-supplied names (treat them as untrusted input; don't interpolate into HTML unescaped).
  • Lazy icons flash and shift layout. Always pass a fallback (skeleton or the previous icon) and set explicit width/height or a Tailwind size-* class so the box doesn't collapse while the module downloads.
  • SSR/Inertia prerendering: lazy loading is client-only. On the server you'll render the fallback on every request — if icons matter for perceived completeness above the fold, use the sprite for those and reserve UXLazyIcon for below-the-fold or truly dynamic slots.
  • Debugging checklist: (1) does the name exist in loaders.js? (2) does the sprite contain #icon-<name>? (3) does the network tab show a request for the per-icon module (404 → path/alias wrong)? (4) is Vite's build.rollupOptions externalizing the generated dir by accident?
  • loaders.js is a reference map, not the SVGs. Importing it is cheap and doesn't inline every icon body, but it does pin every icon name into the bundle graph — regenerating it invalidates chunks, so keep the dump in the same commit as the icon changes to avoid noisy hashes.
  • Pin the version. 0.x with pre-1.0 API churn; ^0.2 is fine only if you're watching release notes — the loadIcon/UXLazyIcon surface is brand new in this release and will likely move before 1.0.
  • On-demand sets bypass the dump entirely — if you configure an Iconify-style set, don't also expect sprite output for it; pick one strategy per prefix or you'll get duplicate/conflicting registrations.
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