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

Filament Adjacency List Laravel Package

saade/filament-adjacency-list

A Filament form component for managing adjacency lists (trees) with drag-and-drop nesting, reordering, and customizable labels, depth limits, item actions, and URLs. Works with arrays or Eloquent relationships.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This is a single-purpose Filament form component (plus an optional widget) that renders and mutates adjacency-list data — parent/child trees stored as parent_id + sort columns, or resolved through recursive relationships. It is not a domain layer, a repository abstraction, or a data-structure library; it is a presentation-and-interaction layer over a schema you already own. That makes it a strong architectural fit only if the product surface is a Filament panel. For a Laravel API, a Nova/Inertia/Livewire-non-Filament admin, or a customer-facing frontend, the value is near zero — you would be adopting a Blade/Alpine drag-and-drop tree you cannot reuse. The design is composable in the Filament idiom (closures for labels/URLs, action customization, per-field addable/editable/deletable/reorderable/moveable/indentable switches), which means policy enforcement and read-only modes can be expressed declaratively rather than forked.

Integration feasibility. Low effort for a team already on Filament: one composer require, one @source line in the theme CSS, and a model that either exposes a self-referential children() relation or adopts Staudenmeir's HasRecursiveRelationships. The README provides a complete, copy-pasteable relationship recipe (Department → Subjects) and documents the Staudenmeir interop, including the non-obvious getPathSeparator() / getCustomPaths() workaround for teams already using that trait elsewhere. That last detail matters: it signals the maintainer has anticipated coexistence rather than greenfield-only adoption.

Technical risk.

  • Bus factor of one. Primary author plus a small set of recurring contributors. MIT license means we can fork, but a fork of a drag-and-drop Livewire component is not a trivial maintenance artifact.
  • Adoption signal is thin. ~100 stars and zero dependents is a weak corroboration signal. We would be an early-ish adopter, so we should expect to find the edge-case bugs ourselves rather than reading about them in issues.
  • Tight framework coupling. Value is entirely contingent on the Filament major line. The changelog shows explicit Filament 4 and Filament 5 support work landing in the same release window as Laravel 12/13 support — good responsiveness, but also confirmation that Filament majors are the real compatibility axis and will force package upgrades on their cadence, not ours.
  • Behavioral complexity in the client layer. Drag, indent, outdent, reorder, max-depth enforcement, and modal-vs-inline editing are Alpine/JS state machines. These are the least testable and most regression-prone parts of the package, and the v4.2.0 notes are a catalogue of exactly such fixes (depth limit miscounts on drag, action handlers breaking after drag, parent/order mutation of the root record). Assume residual edge cases.
  • Persistence semantics are the sharp edge. The v4.2.0 fix "save graph relationships without detaching siblings or failing on save" and "keep the tree empty and stop adding items until the owner record is saved" describe failure modes with real data-integrity consequences, not cosmetic bugs. Tree mutation bugs are silent and expensive to reconcile.

Key questions.

  1. Are we committed to Filament for the lifetime of this feature, or is the admin layer plausibly being replaced within 18–24 months?
  2. Does the tree live in our own tables (parent_id, sort) with full control, or does it depend on Staudenmeir's package — i.e., are we taking one dependency or two?
  3. What is the maximum realistic tree size and depth for our data (categories: hundreds; org units: thousands)? Has anyone validated render and save performance at that size?
  4. What is the composer.json PHP constraint, and does it match our runtime floor?
  5. Do we need audit history, soft deletes, or per-node permissions? The package has none of these; policy hooks exist but there is no change journal.
  6. Who owns a fork if the maintainer goes dormant — is there a named engineer and an acceptable frozen-version fallback?
  7. For the many-to-many / graph case, do we actually need HasGraphRelationships, or is a simple parent_id tree sufficient? Graph support materially increases the blast radius of any persistence bug.

Integration Approach

Stack fit. Filament + Livewire + Alpine, Laravel 12/13, PHP per the package's composer constraint. Ideal target: an internal or back-office panel where menus, category taxonomies, org hierarchies, or ticketing subject trees are edited by a small number of trusted operators. Poor fit for high-concurrency, multi-tenant-editing-the-same-tree scenarios — there is no optimistic locking or conflict resolution in the component.

Migration path.

  1. Schema first, UI second. Add parent_id (nullable, indexed, FK with nullOnDelete or restrict) and sort (integer, indexed) to the target table. Backfill roots with parent_id = NULL and deterministic sort values. Ship a data-integrity job that asserts no cycles and no orphans before the field is exposed.
  2. Model prep. Add the self-referential children() relation with ->with('children')->orderBy('sort') per the README, or adopt Staudenmeir if we already need recursive queries elsewhere. Prefer Staudenmeir only if we have a second use case; otherwise the plain relation keeps the dependency surface at one package.
  3. Theme wiring. Add the @source directive to the custom theme CSS. This is a hard prerequisite — skipping it yields an unstyled, apparently broken field and a confusing bug report.
  4. Field rollout behind a flag. Register the AdjacencyList on a single resource, in read-only mode first (->addable(false)->editable(false)->deletable(false)->reorderable(false)), to validate rendering against real data volumes.
  5. Enable mutation progressively. Turn on edit → add → reorder → indent/outdent, gated by maxDepth() and Laravel policies. Set maxDepth to a number the business actually needs; unlimited depth is a footgun.
  6. Widget last. Add AdjacencyListWidget only after the form component is stable, and only for read-mostly overview pages.

Compatibility. Pin the package major to the Filament major and treat Filament upgrades as a coupled change (package bump + theme rebuild + regression pass on drag/indent/reorder). Maintain a compatibility matrix in the repo: Filament version × Laravel version × package version. The v4.x line's support for Filament 4/5 and Laravel 12/13 in the same window is encouraging but should be verified in staging, not assumed.

Sequencing. Data model and integrity checks → theme/CSS → read-only render → mutation with depth and policy limits → widget. Do not parallelize schema work with UI work; the persistence bugs in the changelog all surface at the seam between the two.

Operational Impact

Maintenance. Low steady-state effort: a composer bump per Filament/Laravel cycle, occasional theme rebuilds, and a regression pass on the tree interactions. The real cost is the coupling tax — this package's release cadence is dictated by Filament's, so it lands in our upgrade critical path. Budget one engineer-day per Filament major and a half-day per minor, plus a manual QA script covering add/edit/delete/reorder/indent/outdent/max-depth/policy-denial/save-on-unsaved-owner.

Support. Upstream support is community-only, best-effort, via GitHub issues. There is no SLA, no paid tier, no security disclosure process beyond a policy file. For an internal admin tool that is acceptable; it would not be for a customer-facing editor. We should designate an internal owner, keep a pinned version, and pre-write the fork checklist (branch from tag, vendor the theme views, document the patch points) before we need it.

Scaling.

  • Tree size. Rendering is recursive and eager-loaded via with('children'); a few hundred nodes is comfortable, low thousands needs measurement. Watch for N+1 patterns if custom itemLabel closures hit the database per node — the README's own example does a Page::find() inside the label closure, which is a per-item query. Cache or preload instead.
  • Depth. maxDepth() exists and is enforced on drags and indents (a v4.2.0 fix), but unlimited depth with a recursive relationship invites deep eager-load stacks. Cap depth by policy.
  • Write volume. Every drag/indent persists immediately through Filament's relationship saving. Fine for a handful of editors; not a fit for bulk tree restructuring or programmatic imports — use a queued job for those.
  • Concurrency. No locking. Two editors on the same tree will last-write-wins. Acceptable for an ops team of two; add an advisory lock or "tree is being edited" banner if the editor count grows.

Failure modes to instrument.

  • Orphaned or cyclic nodes from a failed save mid-drag. Mitigation: nightly integrity job asserting single-root reachability, no cycles, contiguous sort.
  • Sibling detachment on relationship save (explicitly fixed in v4.2.0, but the failure class is architectural). Mitigation: after-save assertion comparing expected vs. actual child counts.
  • Silent no-op saves when the owner record is unsaved — the tree renders empty and refuses additions. Correct behavior, confusing UX. Mitigation: document it, and hide the field on Create pages until the record exists.
  • Theme CSS not compiled after a deploy → unstyled tree. Mitigation: include a visual smoke test in the deploy pipeline, not just an HTTP 200 check.
  • Policy bypass on drag when the field is disabled or the policy denies. Historically a bug (fixed in v4.2.0). Mitigation: an authorization test per action, not just a render test.
  • Filament major upgrade breaking the component with no upstream fix yet. Mitigation: upgrade Filament in a branch, confirm the package supports that major before merging.

Ramp-up. A developer familiar with Filament reaches productive use in under an hour — the API is declarative and the README is unusually complete for a package this size (installation caveat, configuration, relationships, Staudenmeir interop, widget, ordering). The learning cost is not the API; it is the operational model: understanding that the field mutates relationships on save, that ordering depends on a column you must supply, and that depth/policy constraints must be configured rather than defaulted. Those are the three items to put in the team's own runbook, because they are the ones the README states once and the changelog shows people getting wrong.

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.
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus