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

Filament 4 Phosphor Icons Laravel Package

schmeits/filament-4-phosphor-icons

Bring the Phosphor icon library to Filament 4 panels. Use thousands of crisp, consistent icons across forms, tables, actions, and navigation, with straightforward setup for Laravel admin interfaces.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require schmeits/filament-4-phosphor-icons

It ships no assets, no migrations, no publish step — just an enum plus a service provider that maps each case to a Phosphor SVG. Since 1.1.0 the floor is Filament 4.13.2 or 5.8.2 (the first versions without known security advisories) and Laravel 12 or 13; Laravel 11 is EOL and no longer tested. If you're on Filament 3 there is still no backport path.

Look at vendor/schmeits/filament-4-phosphor-icons/src/ first. Two greps tell you everything:

grep -n "enum \|case " vendor/schmeits/filament-4-phosphor-icons/src/*.php | head -40
grep -n "public function " vendor/schmeits/filament-4-phosphor-icons/src/*.php | head -20

The first shows the case names (and their backing values), the second shows the six weight variants — expect fluent methods like ->thin(), ->light(), ->regular(), ->bold(), ->fill(), ->duotone(). The enum is generated, so its header comment records which codeat3/blade-phosphor-icons version it came from — read that before assuming an icon is missing rather than just not generated yet. Confirm the FQCN before you write it into 40 files.

First use case — swap one heroicon for a Phosphor one:

use Schmeits\FilamentPhosphorIcons\PhosphorIcon;

class CustomerResource extends Resource
{
    protected static string | BackedEnum | null $navigationIcon = PhosphorIcon::UsersThree;
}

Filament 4/5 icon slots are typed string | Htmlable | BackedEnum | null, which is exactly why the enum API exists: it drops in wherever you previously wrote 'heroicon-o-users'. Reload, and it renders at the panel's icon size because the SVG inherits currentColor and the fi-icon sizing classes. If nothing renders, you have a version constraint problem, not a code problem — check composer why-not schmeits/filament-4-phosphor-icons. On a Filament 4.0–4.13.1 install the correct fix is to upgrade Filament, not to pin an older icon package.

Implementation Patterns

Panel and resource chrome. Replace $navigationIcon, $activeNavigationIcon, $modelIcon (used in global search and relation managers), and getNavigationBadge(). Because nav icons are static properties, this is a mechanical find-and-replace across resources — do it once, on a branch, and eyeball every screen.

Actions and bulk actions.

Action::make('export')
    ->icon(PhosphorIcon::Export)
    ->label('Export'),

BulkAction::make('archive')->icon(PhosphorIcon::ArchiveBox),

Icon-only buttons still need a ->tooltip() or ->label() — the SVG carries no accessible title.

Tables and infolists. Use closures for state-driven icons:

IconColumn::make('status')
    ->icon(fn (Order $record) => $record->isPaid()
        ? PhosphorIcon::CheckCircle
        : PhosphorIcon::Clock),

TextColumn::make('email')->icon(PhosphorIcon::EnvelopeSimple),

Forms. TextInput::make('email')->prefixIcon(PhosphorIcon::Envelope), Section::make('Billing')->icon(PhosphorIcon::CreditCard). If a particular affix slot in your Filament minor version is typed string only, pass PhosphorIcon::Envelope->value — same rendered output.

Standardise on a weight, once. The real payoff of six weights is a consistent visual language: regular for nav, fill for the active/selected state, bold for 16px-and-under contexts (badges, table cells), thin only in dense data tables. Encode it in one helper so the decision lives in one file:

final class Icon
{
    public static function nav(PhosphorIcon $icon, bool $active = false): PhosphorIcon|string
    {
        return $active ? $icon->fill() : $icon->regular();
    }
}

Override Filament's own icons globally. Instead of chasing every panels:: alias, register the mappings once in AppServiceProvider::boot():

FilamentIcon::register([
    'panels::widgets.account' => PhosphorIcon::UserCircle,
    'actions::delete-action'  => PhosphorIcon::Trash,
    'tables::columns.icon-column.true' => PhosphorIcon::CheckCircle,
]);

That gives you a whole-panel consistent icon set in one place. Guard with class_exists(PhosphorIcon::class) if the package is optional in some deployments.

User-selectable icons. Store the backed value string and let Laravel's native enum cast handle the round trip:

// Model
protected $casts = ['icon' => PhosphorIcon::class];

// Form
Select::make('icon')
    ->options(collect(PhosphorIcon::cases())
        ->mapWithKeys(fn (PhosphorIcon $i) => [$i->value => $i->name])
        ->all())
    ->searchable();

Blade. <x-filament::icon :icon="$icon" class="h-5 w-5" />. Sizing only comes for free inside Filament components that accept ->size(IconSize::Small); in raw Blade you supply the h-* w-* classes yourself.

Regenerate instead of forking. When codeat3/blade-phosphor-icons adds a batch of icons, bump that dependency and run composer generate-enum to rebuild the enum from upstream rather than hand-editing cases. The generator lives at bin/generate-enum.php and stamps the upstream version into the output, so the diff tells you exactly what moved.

Isolate the dependency. If you're putting this into a client project, define App\Enums\AppIcon that wraps the vendor enum (or even just string values). Swapping icon sets later becomes a one-file change instead of a grep across app/Filament.

Gotchas and Tips

  • Tight version floors. Filament 4.13.2+/5.8.2+, PHP 8.2–8.5, Laravel 12/13. Laravel 11 is explicitly out. Verify constraints before proposing it; there's no v3 branch and no old-Laravel branch.
  • BackedEnum vs string slots. Most slots accept the enum, a minority of affix/extraAttributes-style APIs want a string. ->value is always a safe fallback.
  • Backing values are the contract. ->value is what lands in HTML and in the database. Never rename or reorder cases if you've persisted them; and persist ->value, not ->name, unless your hydration path maps names back with constant().
  • from() throws. Stale DB rows or renamed cases produce a ValueError mid-render. Use PhosphorIcon::tryFrom($v) ?? PhosphorIcon::Question on any user-editable or legacy column.
  • A missing icon may just be an old generation. The case list is a snapshot of codeat3/blade-phosphor-icons ≥2.4. Check the version header in the generated enum, bump the blade package, and re-run composer generate-enum before you start hand-rolling SVGs.
  • Weight legibility. Thin/stroke weights get muddy below ~16px; the fill and duotone weights rely on fill/opacity and can look heavy or washed out against Filament's dark-mode gray-950 surfaces. Check both themes before committing a convention.
  • Don't mix sets on one screen. Phosphor's stroke geometry next to heroicons' reads as a rendering bug. If you can't convert everything, at least keep both on outline-style weights.
  • Clear the caches after changing FilamentIcon::register(). php artisan filament:clear-cached-components && php artisan optimize:clear — cached components and compiled views can hold the old alias and you'll swear the mapping didn't take.
  • Never require-dev it. SVGs are served from vendor/; a composer install --no-dev in production (or a Docker build context that prunes vendor/schmeits) is the usual cause of missing icons.
  • Blade won't always cast it. {{ $icon }} on a backed enum is context-dependent and will bite you in plain Blade templates — write {{ $icon->value }} explicitly.
  • Every file is now declare(strict_types=1). Irrelevant if you only consume the enum; relevant if you've copy-pasted or subclassed the service provider. The 1.1.0 cleanup removed a $viewNamespace property, a facade alias that was never real, and unused frontend tooling — no live public API changed, so nothing to chase in your app.
  • Bus factor, but with a better story. Small package, one author, a young release — however 1.1.0 adds a CI matrix across PHP 8.2–8.5, Laravel 12/13 and Filament 4/5, includes a render test through Filament's icon component, verifies the enum against the generator, and runs PHPStan at max. The failure mode is still trivial to absorb: the package is a generated enum plus a directory of SVGs, so pin "^1.1", commit the lock file, and if it ever stalls, fork it or move the cases into your own enum and register the paths with FilamentAsset/FilamentIcon. Don't let it leak into domain code.
  • Extension point. Adding icons doesn't require a fork — regenerate from upstream with composer generate-enum, or point FilamentIcon::register() at your own SVG paths for anything the package doesn't cover, keeping everything else on the enum so the weights stay consistent.
  • Icon-only UI needs labelling. Tooltips, aria-label, or a ->label(); Filament renders the SVG as decorative and screen readers get nothing.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console