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 Nestedset Laravel Package

wsmallnews/filament-nestedset

Filament nestedset tree plugin built on kalnoy/nestedset, with multi-language and multi-tenancy support, unlimited nesting levels, tabbed switching, and a parent select field for elegant tree management.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

Build vs. buy for tree-shaped content. Most admin panels eventually need a hierarchy: nav menus, CMS categories, product taxonomies, org/department structures, knowledge-base sections, file or asset folders, location regions. The realistic in-house version of this (drag-and-drop reorder + reparent, nested CRUD forms, level limits, safe deletion rules, tenant scoping) is roughly one to three engineer-weeks plus ongoing polish. This package is a page class plus a composer require, so the buy case is strong if you are already on Filament v4/v5 and a nested-set model.

Feature scoping. The README effectively doubles as a scope checklist for the tree epic. Decisions you can make and defend:

  • Unlimited depth by default, optional cap via $level / getLevel() — lets you ship a taxonomy without committing to a hard IA limit, then tighten later once content editors reveal actual depth.
  • Safety defaults from config: allow_delete_parent = false, allow_delete_root = false. This makes "you can't delete a category with children" the default UX rather than a bug; you consciously choose cascade or reparent instead.
  • Create-in-context via create_action_modal_show_parent_select and per-row "create child" action — decides whether users add nodes top-down from a modal or in-place from the row they're looking at.
  • Extra row metadata via infolistSchema() (status, count, owner) with breakpoint and alignment controls — turns the tree into a scannable operational view rather than a bare list.
  • getRecordLabel() returning HtmlString — supports badges, status dots, translated labels in the node title without forking the view.

Multi-tenant roadmap enablement. Tenant-scoped trees are supported through kalnoy/nestedset's scoping, driven by getScopeAttributes() on the model plus $isScopedToTenant = false for global pages. This is the single biggest planning input: if your panel is multi-tenant, every tree table needs the tenant (and any scope) column in its schema from day one. Retrofitting scoping columns onto existing tree data is a migration, not a config flip — so decide tenancy before the first tree ships.

Tabs as a segmentation pattern, not a localization feature. $tabFieldName + getTabs() gives you multiple trees on one page (e.g. Website Navigation / Shop Navigation) by appending the tab value to the nested-set scope. Product implication: tabs are a data partition, so the tab field must be in getScopeAttributes(). Good for multi-channel or multi-type taxonomies; a poor fit if you want tabs that are filtered views over one unpartitioned tree.

Integration surface for adjacent roadmap items. The Livewire tree component emits sn-filament-nestedset-leaf-click / node-click events and exposes getRecordUrl for custom navigation, plus getEloquentQuery() for status/visibility filtering. That means "click a category to open its articles/products" and "only show published nodes" are cheap follow-on stories rather than new builds.

Discovery item to resolve early: the "multi-language" claim is UI string localization (publishable translations). It does not appear to mean per-locale node content. If your roadmap needs translated category names per locale, that is a schema and form-schema decision on your side — scope it explicitly, don't inherit it from the package description.

When to Consider This Package

Adopt when all of these are true:

  • You are on Filament v4 or v5 and the tree lives in a Filament panel. (Filament v3 users must use the v1 branch — treat that as a maintenance risk, not a free option.)
  • Your model already uses, or can adopt, kalnoy/nestedset (NodeTrait plus $table->nestedSet()); this package is a UI layer, not a data-structure choice.
  • Read-heavy, shallow-to-medium trees (menus, categories, org units) where moves are occasional. Nested sets make writes expensive and reads cheap — the sweet spot is tens to low thousands of nodes per scope.
  • You need multi-tenancy and/or tabbed partitioning, since those are the differentiators versus a hand-rolled sortable list.
  • You are comfortable depending on a young, single-maintainer, MIT package and pinning a version.

Look elsewhere, or build, when:

  • You are not on Filament. The value is the Filament-native page, form, and styling. On plain Livewire/Blade/Inertia, use kalnoy/nestedset directly with your own UI, or 15web/filament-tree.
  • You need a different hierarchy model. Adjacency lists, closure tables, or materialized paths handle high write volume, very deep trees, or partial-subtree permission queries better. Choosing this package implicitly chooses nested sets.
  • You need governance, not editing. Per-node permissions, approval workflows, scheduled publishing, version history, and audit trails are not in scope here. You will build those on top.
  • You need vendor assurance. 22 stars, 0 dependents, and a single maintainer mean no support SLA and no ecosystem proof. If a broken release would block a launch, budget for an internal fork or a maintained fork budget line.
  • You want one ordering primitive everywhere. If the real need is "sortable lists" across many entities, not hierarchies, a generic reorderable-table solution is cheaper than adopting nested sets.

Adoption checklist before you commit: pin the constraint (^2.0), publish config/views/translations so behavior is reviewable in-repo, wrap NestedsetPage in a thin internal base class so you can swap implementations, and add an integration test on your model covering reorder, reparent, tenant scope, and blocked parent deletion. Verify the v1/v3 branch status if any panel is still on v3. Note the Laravel Boost integration (php artisan boost:update --discover) as a genuine onboarding nicety for AI-assisted work.

How to Pitch It (Stakeholders)

To executives — one paragraph: We need tree-shaped admin screens for [menus / categories / org units], and the honest in-house cost is one to three engineer-weeks per screen family plus indefinite upkeep of drag-and-drop edge cases. wsmallnews/filament-nestedset is an MIT-licensed Filament plugin that delivers that UI — drag-and-drop reordering, parent selection, depth limits, safe-delete rules, tenant-scoped trees, and tabbed datasets — as a page class we configure in an afternoon. It sits on kalnoy/nestedset, a widely used Laravel library, so our data model and data are portable and the lock-in is low. The trade-off is maturity: small community, one maintainer, no support contract. Mitigation is cheap — pin the version, wrap it in one internal base class, and keep our own tests on reorder and tenancy. Recommendation: adopt for the tree screens this quarter, with a deliberate exit path.

To engineering — the framing: It is a thin, well-behaved UI layer over kalnoy/nestedset, not a new persistence model. You keep NodeTrait, the nestedSet() migration columns, and your scoping semantics; you gain the Filament page, tree component, create/edit modal schemas, and parent-select field (codewithdennis/filament-select-tree). Extension points are conventional and override-friendly: schema() / createSchema() / editSchema(), getRecordLabel() (accepts HtmlString), infolistSchema() plus $infolistHiddenEndpoint / $infolistAlignment, getEloquentQuery(), getLevel(), nestedScoped(), $isScopedToTenant, $tabFieldName with getTabs(), and $emptyLabel / $emptyTipLabel. The Livewire tree component emits sn-filament-nestedset-leaf-click and node-click events and exposes getRecordUrl for navigation, so click-through behaviors are additive. Non-negotiables on our side: tenant and tab fields must be added to getScopeAttributes() before any data exists; config defaults block deleting parents and roots, so cascade/reparent behavior is an explicit decision; and we pin ^2.0, publish config and views into the repo, and add regression tests on reorder, reparent, scoped queries, and delete guards before this reaches a customer-facing screen.

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.
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk