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

Nova Simple Repeatable Laravel Package

optimistdigital/nova-simple-repeatable

A Laravel Nova field package for adding simple repeatable rows to resource forms. It lets editors create, reorder, and remove structured JSON-backed entries without a related model, making flexible repeated inputs easy to manage in Nova.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Build vs. buy for admin-editable content. This is a Nova form field, not a general Laravel package — it only creates value inside an existing Nova resource. For display-oriented admin content (FAQs, opening hours, feature/spec lists, contact blocks, link lists), it collapses what would otherwise be a data-modeling project — new table, migration, Eloquent model, child resource, relationship wiring, and reorder UI — into a nullable json column, a field definition in the resource, and editor UAT. Use that delta as the real comparison in the estimate, not "package vs. nothing."
  • The decision it actually forces: JSON blob vs. normalized child table. The package ships a UI; the PM-level decision is storage shape. A JSON column makes individual rows opaque to SQL — no reliable joins, sorts, aggregates, referential integrity, per-row identity, permissions, or audit history. Adopt where the data is human-edited and display-bound; refuse where any downstream feature, report, integration, pricing/eligibility rule, or public API contract depends on the inner values.
  • Roadmap sequencing and scope recovered. Its value to a PM is schedule arithmetic: a schema-plus-UI workstream becomes a Composer dependency, one migration, one field definition, and a UAT pass. Value concentrates where the product lives or dies on admin/ops throughput — content sites, catalogs, internal back-office tools — by removing a recurring "please add another row of X" developer queue item.
  • Bet sizing and reversibility. Small surface: one dependency, no child tables, MIT license, no migrations beyond one nullable column. It is a cheap, abandonable tactical bet, not a platform commitment. Worst case is a fork, not a rewrite. Because the JSON stays human-readable, migrating to a normalized model later is a decode-and-backfill migration — price it as a known exit, not a redesign.
  • Backlog triage you can apply at grooming. Appropriate: bounded, low-cardinality, editor-owned row sets (tens of records, tens of rows each). Inappropriate: unbounded or end-user-driven structures, per-row workflow or permissions, anything a downstream feature must query. Publishing a short "do not use this field for X" list early is the cheapest way to stop the shortcut from spreading into places where it becomes expensive to undo.
  • Questions to force before committing scope. Will we ever filter, sort, or report on individual row values? Will the row shape drift, and who owns versioning it? Will this JSON be exposed through an API or export? Does any row contain a file upload or a relationship reference? A "yes" on any of these should be priced into the estimate now rather than discovered at reporting time.
  • Vendor and platform gating. Nova is a paid, closed-source first-party dependency — a commercial cost driver that dwarfs this package. This field also sits on the small-maintainer, vendor-renamed (optimistdigital → outl1ne) end of the ecosystem, with a thin dependent count. That is an acceptable risk only when someone owns the Nova-major upgrade path and the fork option is genuinely available to the team.

When to Consider This Package

Consider it when all of these hold:

  • You already run Laravel Nova (licensed, supported major) and the screen lives in a Nova resource.
  • The content is human-edited, display-oriented, and bounded — a handful of fields per row, tens of rows per record.
  • Nobody will ever need to filter, sort, aggregate, search, or join on the inner values.
  • The JSON stays internal. It does not define a public API contract, an export format, or a data feed.
  • Editing concurrency is low (one editor per record at a time); last-write-wins is tolerable.
  • Rows have no need for durable identity — no deep links, per-row sync, per-row workflow, or per-row permissions.
  • The row set uses only simple inputs (text, textarea, select). No file uploads you can't prune, no relationship fields whose deletion would leave dangling IDs, no reactive/dependent or nested repeatable behavior.
  • You can fork. MIT plus a small maintainer means fork-on-Nova-major is the real continuity plan, so the resource definition should stay thin enough to fork cleanly.

Look elsewhere when any of these hold:

  • You need a child model. Per-row identity, permissions, audit trail, versioning, workflow state, or any query/report requirement all point to a normalized table with its own Nova resource. Retrofitting queries onto JSON via generated columns is an escape hatch, not a plan — the third whereJsonContains is the signal to migrate.
  • File storage is involved. A row-level File/Image field stores a path; deleting the row leaves the file on disk. Only proceed if you are willing to own an orphan-pruning job.
  • Relational integrity matters. BelongsTo inside a row writes a bare integer with no foreign key; deleting the related model breaks the editor preview silently.
  • Two people might edit the same record. The whole array is written per request with no diff, version, or conflict detection.
  • You need search or filtering in the Nova index. Nova search runs against the column as a string; matching opaque JSON produces nonsense and slow scans.
  • You are not on Nova, or you are on a Nova major outside the package's supported matrix. Verify against composer.json on the tag you pin, not the readme.
  • You need a maintained, supported dependency with an SLA. 75 stars, a single-maintainer history, a namespace migration, and "updated packages" as a changelog mean you are the validation layer.

How to Pitch It (Stakeholders)

The one-liner: a small, MIT-licensed Nova field that lets editors add, remove, and reorder groups of fields inside an existing admin screen — stored as JSON on the record, with no new tables, models, or relationships.

For executives: this converts a recurring class of small requests — "add another row of X to the admin" — into editor self-service. Effort is a Composer dependency, one nullable JSON column, one field definition, and a UAT pass; licensing is MIT, so there is no procurement step. It is a tactical, reversible bet: one dependency, no schema sprawl, and a defined exit (decode the JSON, backfill a proper table) if requirements grow. The genuinely irreversible commitments here are Nova itself and the data model we choose, so both should be stated explicitly rather than assumed.

For engineering: the field is thin; the discipline is not. Three non-negotiables: an array cast on the model (without it, saves fail or data silently reads back empty), a single centralized row-schema definition shared by the resource, tests, and factories, and model-level validation treated as the source of truth while Nova's inline rules are UX only. Keep the field set in a static method — no clever inline definitions — so a fork or replacement stays contained. Pin an explicit version constraint and commit the lockfile; never leave a small-maintainer package floating.

The limits to state up front, so they don't surface as surprises: rows have no stable identity, so removing row 2 renumbers everything after it; the whole array is rewritten on every save, so concurrent editing loses data silently; inner values are not queryable, so this cannot feed reporting, pricing, eligibility, or an API contract; file uploads inside rows leak unless pruned; and relationship fields inside rows store bare IDs with no foreign key.

Guardrails to agree before the pilot: pick one bounded use case first (opening hours, FAQ list, feature bullets, contact block) because everything learned about the JSON shape, editor UX, and validation transfers and the edge cases don't. Hide the field from the index or render a row count — never a raw JSON wall. Normalize the empty state in one accessor so nothing branches on null vs []. Publish a short "not for these cases" list alongside the field, so the shortcut doesn't quietly become the default answer to every admin request.

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.
alphabalex/messaging-made-easy
rawphp/warp
shootkiran/merobug
narakode/fineauth
numencode/wn-syncops-plugin
ibnnajjaar/mib-global-pay
ably/pubsub-server
mstfkhazaal/defender
mfonte/base62x
karnoweb/metapilot
tobya/bcsapiwrapper
swalker2/cpanel
vish4395/laravel-translation-manager
morningtrain/economic
teksite/systeminfo-laravel
atomcms/voting
run6/weather
siokas/laravelembeddirectives
adamlien/pkuuids
gilsonsouza/lara-doc-generator