marshmallow/nova-fontawesome
marshmallow/nova-fontawesome adds a searchable Font Awesome icon picker field to Laravel Nova. Let editors choose icons visually, store the selected class on your model, and render icons consistently across your admin resources. Lightweight and easy to install.
Architecture fit. This is a single-purpose Nova form field: it swaps a text input for a searchable Font Awesome picker and persists the chosen class string (e.g. fa-solid fa-house) onto a nullable model column. Architecturally that is the best kind of dependency — presentation-layer glue with no service, no queue, no runtime footprint on the customer-facing request path, and a blast radius of exactly one form control. It belongs in the admin/resource layer, not in the domain model. The only durable design decision it forces is a data one: raw FA class strings vs. your own semantic keys.
Integration feasibility. Low. One composer require, one nullable string column, one field registration. The credible build-vs-buy framing is 1–3 days of custom-field work (icon search, live preview, empty states, validation, Vue asset packaging, ongoing maintenance) collapsed into an afternoon. Feasibility is gated almost entirely on two preconditions: you already run Nova 5, and Font Awesome is already the sanctioned icon vocabulary. If design hasn't picked FA, this package is not the venue for that decision.
Technical risk. The risk is not technical complexity, it's supply chain and asset plumbing:
Key questions to close before approving.
| Question | Why it gates the decision | Owner |
|---|---|---|
| How many admin surfaces need an icon choice? | Below ~3, saved effort doesn't clear evaluation + pinning cost | TPM / eng lead |
| Raw class strings or semantic keys? | Cheap now vs. expensive later; changes the data model | TPM + eng |
| Do we need FA Pro glyphs? | If yes, picker value collapses and editors hand-type | Design |
| How does the Nova admin panel get FA CSS (self-hosted vs. CDN)? | CSP/SRI and "invisible glyphs" support noise | Eng |
| Who forks and patches if the maintainer walks? | Named owner, not an assumption | Eng manager |
| Is there a text-input fallback behind a flag? | Abandonment contingency for editors | Eng |
Stack fit. Nova 5 only; v3.1.0 added Laravel 13 support via an outside contributor — a genuinely positive sustainability signal for a package this size. Important for planning: the binding constraint is Nova's own Laravel support, not this field. Do not treat this package as the thing that unblocks a framework upgrade; check Nova's release notes first and confirm the resolved constraint matrix with composer show.
Migration path. Additive and reversible, which is why this is a safe first move:
->nullable() string column per icon attribute.whereNull('icon')->update([...])) so list views aren't blank during rollout.Compatibility. Pin to ^3.1 and record the resolved version in the lockfile notes. Read the service provider for the exact asset-publish tag rather than guessing; run php artisan nova:publish and clear cached config/views after every Nova or package upgrade. Self-hosting FA CSS in the Nova build beats a CDN on maintenance (no SRI hash churn, no CSP exceptions).
Sequencing.
Repeater and a Panel in staging. Single-purpose fields most often break on mount assumptions; this is cheap to verify once.Maintenance. Small but real: a line item in every future Nova major evaluation, and to a lesser degree every Laravel major. Mitigated by the maintainer's active framework tracking and a merged outside-contributor compatibility PR. Budget the fork capability, not the fork.
Support. This is the actual business case, and it should be framed as such. The field moves icon selection out of the engineering backlog and into marketing/ops/support hands — it converts a recurring "can you swap this icon" ticket stream into self-serve configuration. Before approving, ask support for a rough count of that ticket volume; that number is the ROI. Do not approve it as a UI nicety.
Scaling. Runtime cost is negligible; reuse cost across additional resources approaches zero, which is the argument for adopting at 3+ surfaces rather than 1. The thing that actually scales is governance, not infrastructure: without a centralized field definition and an enforced class-format rule, you get fa-solid fa-house in one resource and fas fa-house in another, and a slow-burn cleanup. Semantic keys are the only variant that scales to multi-tenant or white-label theming.
Failure modes and mitigations.
nova:publish step.Text::make('Icon') fallback behind a feature flag, plus defensive rendering at every output site (whitelist the class string; never {!! !!} a user-editable column).Ramp-up. Hours, not weeks. One staging smoke test, one short editor note ("pick from the search list; a blank icon means the CSS isn't loaded — file a ticket"), and a rendered-glyph column in the index view so the field is self-evidently working. Pin the version, upgrade deliberately, and treat the first release as a proof on one contained resource.
How can I help you explore Laravel packages today?