Product Decisions This Supports
- Build vs. buy for admin tooling. This is a small MIT-licensed Laravel Nova field that turns a JSON/array column into a repeatable, drag-sortable list editor in the admin UI. When the requirement is "let ops edit a simple ordered list," it replaces a bespoke field build (roughly 3–5 engineer-days including UI, validation wiring, and tests) with a same-day
composer require — provided the stack is Nova 3.x. That is a clean, low-cost buy decision, not a platform investment.
- Roadmap scoping for internal operations surfaces. Appropriate for back-office workflows — feature bullet lists, menu links, FAQ entries, simple settings, integration config, per-record metadata — and explicitly not for customer-facing product surfaces. It lets a PM say yes to "let the ops team manage this themselves" without opening a platform initiative or committing roadmap capacity.
- Use-case validation as the real deliverable. Because a proof of concept costs hours rather than a sprint, a PM can use this to test whether non-technical operators can safely own array data, and measure the resulting drop in routine engineering tickets. Treat the field as an experiment harness with a defined end date; the evidence — not the package — is the durable output.
- Schema and data-model input. Release 0.6 adds nullable-column support (community PR #14). The PM-relevant consequence: teams no longer need to force a non-null default (empty array or sentinel) purely to satisfy the admin UI, and
null can now be represented as semantically distinct from []. That is a genuine reduction in schema compromise — but it means every downstream consumer (API, export, analytics, search) must branch on two "empty" states. The decision isn't "can we store null" but "is null meaningful in this domain, and are we willing to fund the downstream branching?" If the distinction isn't meaningful, standardize on [] and document it in one place.
- Architecture triage: JSON column vs. relational model. This package is correct only when the list is edited as a whole, belongs to one parent model, and is not a first-class queryable entity. The moment contents need server-side search, filtering, sorting, reporting, or relationships to other models, the right answer is
hasMany plus a Nova relationship field — and adoption converts from accelerator into technical debt. This is a fast scoping rule usable in design reviews and roadmap grooming.
- Risk framing and dependency governance. The package is narrow, single-maintainer, pre-1.0, last released 2020-09-16, 111 stars, and has zero reported dependents. The 0.6 merge is a mild positive signal about the maintainer but is not a maintenance commitment and says nothing about Nova 4/5 compatibility. The dominant risk is a Vue 2 / Laravel Mix component that will very likely fail to build against Nova 4 (Vue 3) or Nova 5 (Vite, PHP 8.1+). That failure is loud and build-time — staging, not silent production corruption — which makes it tolerable as a time-boxed tactical utility and unacceptable as a strategic commitment.
- Concurrency and operational risk budgeting. Because the field writes the whole array on save, two admins editing different rows of the same record silently clobber each other. There is no per-item locking. That is a product constraint to accept or mitigate (low-concurrency internal workflows only), not a bug to file.
When to Consider This Package
Consider it when:
- You are on Laravel Nova 3.x in production and a disposable-branch spike confirms install, render, save, reorder, and reload of a representative payload — including a record with a
null column — against your exact Nova version.
- You have array/JSON columns that need an editable admin UI and the data is a simple ordered list or flat key-value shape, internally owned, with a fixed and understood schema.
- The column is nullable or optional, and
null is genuinely distinct from [] in your domain (or you have decided to normalize to [] and don't need the distinction). Pin to 0.6.* — not ^0.6 — to inherit the nullable fix rather than re-applying it by hand, and to avoid drifting onto an unexpected pre-1.0 minor.
- The workflow is internal-only and low risk — a broken admin screen costs an ops ticket, not revenue or compliance exposure.
- MIT licensing and a small dependency surface matter to procurement and security; forking is legally unencumbered and practically small (one PHP field class, one Vue component, a build config).
- You have named an internal fork owner and accept that the expiry date is tied to your Nova upgrade roadmap.
Look elsewhere when:
- You are on Nova 4 or 5, or plan to be within 12–18 months. Without a fork this is effectively infeasible; budget 3–5 engineer-days to port to Vue 3 and current tooling if the pattern is used in more than one or two places.
- Nova's built-in
KeyValue field (flat maps only) or another actively maintained repeater already covers the need — this is a leaf field, so switching cost is low and the data contract is unchanged.
- The array is nested or per-record variable in shape, or needs per-row conditional logic, min/max item counts, or nested repeaters. Feature depth beyond basic repeat plus reordering is unverified and likely absent; 0.6 adds nullability only.
- The data is read outside Nova — API, exports, analytics, search — or must be filtered, sorted server-side, or related to other models. Normalize to
hasMany and treat JSON normalization as its own roadmap item.
- The workflow is customer-facing or business-critical, or you require active maintenance, security posture, dependency automation, or a vendor SLA. A Nova license does not extend support to third-party fields; support is GitHub issues with uncertain response times.
- You need concurrency safety or audit-grade edit history. Whole-array write semantics mean silent lost updates absent additional mitigation.
- Your CI cannot authenticate against the private
laravel/nova repository, or security scanning of that private dependency is a hard compliance requirement.
How to Pitch It (Stakeholders)
To executives. This is a small, MIT-licensed Nova field that lets operations edit array/JSON attributes directly in the admin panel — feature lists, menu links, FAQs, simple settings — instead of us building a custom field or taking an engineering ticket every time the data changes. On our current Nova 3 stack the integration is same-day, and release 0.6 adds nullable-column support, which removes a schema compromise we would otherwise have to make. Cost is effectively zero in licensing, and the decision is reversible: it is one field on one resource, with low switching cost to Nova's built-in KeyValue field or a relational model if requirements grow. The trade-off is that it is a 2020-era, single-maintainer, pre-1.0 package with Vue 2 tooling, so it will not survive a Nova 4/5 upgrade without a fork. We should adopt it as a tactical, time-boxed utility for internal admin workflows — not as a platform bet — and name an internal owner up front.
To engineering. This is one PHP field class and one Vue 2 component; there is no service provider hooking the request lifecycle, so debugging is confined to the form component and its serialization to the model. Practical asks: pin composer require dillingham/nova-items-field:0.6.* exactly; confirm laravel/nova is 3.x before anything else; make the backing column json and decide nullability deliberately, since null and [] are now two distinct empty states that every downstream consumer must branch on. Own validation in the resource (rules() with wildcard per-sub-key rules plus an array-level bound) — the package enforces no shape. Roll out read-only first and prove a full lossless round-trip, including null, before granting edit access. Treat the JSON shape as a small internal public contract, validated in exactly one place, and normalize to a single "empty" representation if null isn't semantically meaningful. Budget a fork (Vue 3 + Vite rebuild, ~3–5 engineer-days including tests) tied to the Nova upgrade, forked from 0.6 so the nullable fix is inherited. Expect build-time, not silent, failures on Nova 4/5 — and note that CI will need Nova repo credentials either way.