novius/laravel-nova-order-nestedset-field
A Laravel Nova field for ordering nested set models. Drag and drop tree nodes, move items between parents, and reorder siblings, backed by nested set logic. Configurable depth, sibling or free ordering, and smooth integration with Nova resource forms and index views.
What you are actually buying. This is not a package in the platform-dependency sense — it is a UI wrapper. The dependency chain is four layers deep and only one of them is free: Laravel Nova (commercial, per-project licence, moving field API) → this field → kalnoy/nestedset → a model using NodeTrait with _lft, _rgt, parent_id, depth → a Nova resource. Remove any layer and the package does nothing. The first TPM question is therefore not "is this good?" but "do we already have all four layers in production, or are we about to acquire two of them to get drag-and-drop?"
Architecture fit. Where the fit is real, it is genuinely good: the field is a thin, small, tractable surface that collapses one-to-three weeks of Nova field plus tree-move logic into a composer require. It inherits Nova's authorization and adds none, it binds to the nested-set columns rather than inventing a schema, and it keeps writes inside the model layer. That is the correct architecture. Where the fit is bad, it is disproportionate: nested set is write-amplified machinery for a flat ordering requirement, and the package makes that mistake easy to make. Scope discipline is the PM's call here, not the developer's.
Technical risk, ranked by what actually hurts.
_lft/_rgt range. Irrelevant at thousands of rows; a measured problem at hundreds of thousands.parent_id values and inconsistent ranges. The package cannot prevent this; only a team rule and a repair command can.Key questions to resolve before any commit. Most of these are an hour of reading src/ and the compiled Vue component, and that hour is the cheapest diligence available:
composer.json actually constrain to it?dist/js shipped and built against our Nova version, or do we inherit a build step?Stack fit is binary. If Nova and kalnoy/nestedset are already in the stack, the fit is near-perfect and the integration is a field registration. If either is missing, the honest scope is "adopt a commercial admin panel and a tree data structure to get drag-and-drop" — a different and much larger decision that this package should not be allowed to smuggle in.
Migration path. There is nothing to migrate from, which makes the sequencing trap easy to fall into. The order is strict: add the nested-set columns, populate parent_id values, run fixTree() in a deliberate maintenance window with the admin closed, verify, and only then register the field. A half-backfilled tree is the canonical first-day failure: it renders, drags appear to save, and the ordering is quietly wrong afterwards. On tables of tens of thousands of rows, fixTree() is a maintenance-window operation, not a deploy step.
Compatibility discipline. Pin the package and Nova independently and never upgrade both in the same window. If a Nova bump and a package update land together and drags stop persisting, you have no bisect point. Upgrade one, re-run the invariant suite, then the other. Add "drag a node, hard refresh, assert the position survived" to the Nova upgrade checklist permanently.
Sequencing, with exit gates.
app/Nova/Fields/OrderedTree.php) so every resource references your class, not the vendor's. Add a VCS or path repository entry. This is minutes of work and converts "fork or rewrite later" from a find-and-replace across every resource into a one-file change.countErrors()-based monitoring and a scheduled trees:repair command before editors get the drag handle. Detection before exposure.composer require is.Scope discipline is the highest-leverage PM decision the package forces. "Let admins reorder twelve flat rows" is spatie/laravel-sortable plus an integer column, and reaching for nested set there buys write amplification and corruption risk for zero product value. Because this package makes the mistake easy, a named PM owner should hold that line rather than leaving it to whoever writes the migration.
Maintenance is the real cost, and it is yours. Licence cost is zero — there is no licence file — but ownership cost is not. Budget explicitly: an assigned owner, a fork or vendor plan in place before the second resource (the codebase is small enough that forking is cheaper than waiting for it to break), invariant tests in CI, and a standing re-evaluation at every Nova major. That policy is the adoption cost, not the dependency itself.
Support has no floor. An agency maintainer with a recent release date is a mild positive over a solo developer, but 23 stars and zero dependents means no SLA, no upstream bug-finding, and no compatibility guarantee beyond one team's own usage. Escalation is internal by default. Plan the fork on the assumption that upstream fixes arrive late or never — because you will not know which until you need one.
Scaling has two distinct curves and teams usually watch the wrong one.
Failure modes, with detection and response.
countErrors() with loud logging on any nonzero count after a quiet day. Response: fixTree() in a maintenance window. Prevention: one team rule — all tree writes go through appendToNode, saveAsRoot, moveTo, or this field; never Model::query()->update(), bulk deletes, seeders, or import scripts._rgt - _lft is odd for every node and no parent_id is dangling. Response: repair command, then root-cause the write that bypassed the model.canSee — a policy decision, not a technical one.Ramp-up is genuinely small, which is the package's strongest argument. Roughly an hour for an engineer to read the PHP field class and the Vue component end to end; half a day for the invariant suite; a day for the repair command and monitoring. Editors need a short runbook: don't reorder simultaneously, and if the tree looks wrong, stop — the tree is broken, not the UI. The one habit to install across the team is the non-drag fallback: pair the field with a plain parent_id input on the detail view, which gives power users an escape hatch and gives you a diagnostic lever — if the text field writes correctly and the drag does not, the bug is in the field, not the model.
PM summary. Adopt-and-own is defensible for a team already running Nova and nested set, targeting one or two genuinely hierarchical, low-stakes resources, with an internal owner and a fork plan. Fork-and-own is the realistic endpoint if the UI proves valuable — plan for it rather than resisting it. Rebuild is warranted the moment requirements include tenancy, per-user ordering, draft/published states, or audit history, because at that point you own the tree logic regardless and the field wrapper is the only thing you would be preserving. For flat ordering, the answer is no.
How can I help you explore Laravel packages today?