norman-huth/nova-radio-field
A Laravel Nova radio field that lets you present selectable options as radio buttons inside forms. Provides a simple, native-feeling alternative to dropdowns for single-choice fields, making options visible at a glance and improving clarity for small sets of choices.
Architecture fit. This is a presentation-tier Nova form field: one PHP field class plus a compiled Vue component, ~100–200 lines of code total. It touches no domain logic, persistence, queues, or data egress. Stored values are ordinary scalar columns, so the package sits entirely in the admin UI layer and imposes no architectural constraints on the application. That is the strongest thing about it — it is trivially isolatable. The corresponding weakness is that there is no architecture-level reason to adopt it: the same fit is achievable with a native Nova field or a plain Select at zero dependency cost.
Integration feasibility. Install is mechanically simple (composer require, Nova service-provider autodiscovery, nova:publish, hard refresh), but install success is not integration success. The real risk surface is the prebuilt dist/ bundle: a Vue component compiled against a different Nova minor can load without error and fail silently at runtime. Namespace verification against src/ is required before writing use statements — the package name, repo org, and author namespace do not agree. The genuine integration work is a staging verification matrix, not the require.
Technical risk. Concentrated and asymmetric:
Radio. If that covers the requirement, this package is dead on arrival and the assessment ends there. This must be answered first, not last.rules() is a UX affordance. Server-side validation remains the trust boundary and must be built independently.Key questions.
composer.lock, and does the native field set already provide Radio? (If yes: stop.)Recommendation. Do not add it as a Composer dependency. Either use the native Nova field, or — if the UX is genuinely required and unavailable natively — vendor the MIT source into app/Nova/Fields with attribution and treat it as first-party code. Adoption cost exceeds build cost with a permanent maintenance tail and no compensating upside.
Stack fit. Laravel + Nova only; no database, cache, or queue involvement. The field maps to an existing string column, so there is no schema change, no cast, no migration. This is the cleanest possible integration profile and the reason the decision can be made cheaply.
Sequencing. Strictly gated, one resource first:
Radio exists and works, close the ticket.app/Nova/Fields/ with the MIT notice and a header attribution comment; lint and test it as normal Nova field code.options() feeding the field, Rule::enum() in the FormRequest.Compatibility. Pinned to older Nova majors (3.x/4.x) and only against the exact minor verified in production. An archived package is a guaranteed blocker on a Nova 5 upgrade and must be scoped as such before any upgrade planning. If dependency adoption is forced by policy, pin an exact version and mirror the source alongside the lockfile so builds never reach a remote that can disappear.
Migration path (in and out). In: a few lines per resource, no data change. Out: swap the field class back to Select or native Radio in the resource definition — a one-line change with no data migration, because values are plain columns. This reversibility is the single strongest argument for trying it at all, and it should be stated explicitly so the team does not over-deliberate a low-stakes choice.
Anti-patterns to block up front. Do not retrofit every select across the admin. Do not use it for option sets beyond ~5–7 entries. Do not rely on the field for data integrity. Do not assume consistent label rendering across index/detail/form — test each context.
Maintenance. The clock starts at install. With upstream archived, this becomes a permanent fork whether or not you call it one: no upstream issues, no compatibility patches, no security response. Budget it as first-party code with a named owner in the internal component inventory and a written retirement trigger (e.g., "delete when we move to native Nova radio"). If owned without documentation, it degrades into an orphan nobody dares touch before the next Nova upgrade forces the question.
Support. No vendor, no CVE pipeline, no maintainer responsiveness. Anything a procurement or compliance review asks — patch cadence, security disclosure path, maintainer continuity — has no answer. That likely disqualifies it from operator-facing paths under most governance regimes, and it is the cleanest reason to prefer vendoring, which at least gives you a party to hold accountable: yourself.
Scaling. The field does not scale, and neither does the dependency model.
Failure modes (ranked by likelihood, not severity):
dist/js/field.js before debugging PHP.src/.null or ''; undocumented upstream and never to be documented, so it must be asserted in tests.dependsOn is the standard failure surface for custom Nova fields and will never be patched upstream.None of these are severe; all of them are yours to find. That is the operational tax on a package that saves roughly one engineer-day.
Ramp-up. Low for any Laravel/Nova developer — the field API is conventional (options(), default(), rules()), and the source is auditable in an afternoon. The ramp-up cost is not learning the package; it is learning its undocumented edges (null behavior, index vs. detail rendering, conditional visibility), which is discovery work rather than documentation. Mitigate by writing the verification checklist into the PR — it will be the only documentation this component ever has — and by keeping the pilot to one resource so the exit remains a one-line change.
How can I help you explore Laravel packages today?