toxic-lemurs/menu-builder
A Laravel package for building and managing dynamic, nested navigation menus. Define menu structures, control items, links, and ordering, then render them in Blade views. A lightweight helper for site navigation, sidebars, and admin panels.
Architecture fit MenuBuilder is a conventional Laravel 5-era package: a Composer library with a service provider, a publishable config, and (typically for this class of package) database-backed menu and menu-item storage exposed through Eloquent models, plus Blade helpers for rendering. That pattern fits an application that already treats Laravel as the delivery framework and wants menu structure to be data rather than hard-coded templates. It does not fit a headless or API-first architecture well, and it does not fit a multi-tenant SaaS without verification of how menus are scoped. As a TPM I would frame this as a UI-composition dependency, not a platform dependency — its blast radius is navigation, breadcrumbs, and admin chrome.
The critical caveat is that this is a low-signal package: 6 stars, 0 dependents, score 0.15, and a single last release dated 2020-11-10. That combination means we are, in practice, adopting an unmaintained codebase rather than a supported product. Architecture fit is therefore conditional on our willingness to own the code.
Integration feasibility
Feasible, with a bounded spike. Expect a 1–3 day timeboxed evaluation covering: (a) does composer require resolve against our Laravel/PHP version, (b) do the migrations run cleanly on our DB engine, (c) does the render path survive our view layer and CSS framework, (d) does authorization integrate with our policies/Gates rather than the package's own. The package almost certainly targets Laravel 5.x and PHP 7.x; on Laravel 9/10/11 the constraint will fail to resolve, and even a forced install will hit removed helpers (str_*, array_*), the $dates property, and facade alias changes.
Technical risk
composer audit before anything reaches production.Key questions
composer.json actually permit, and which branch is our target?spatie/laravel-menu, kalnoy/nestedset plus our own CRUD, or a Filament/Nova-native menu resource) that removes the ownership burden?Stack fit
Only a fit if the target is Laravel 5.x/6.x on PHP 7.x. For Laravel 8+ I would go in assuming we fork it: vendor the source under our namespace, modernize the constraint, replace removed helpers, and convert config to the current config/ publish pattern. If the app is on Laravel 10/11 with PHP 8.2+, treat the package as reference source, not as a dependency, and re-implement the parts we need — the data model is small and the rendering helper is a thin recursive Blade partial.
Migration path
menu_*) and never let foreign keys from core tables point into them.MenuRepository / MenuRenderer interface that the package satisfies. Every call site depends on our interface, not the package facade. This is the single highest-leverage decision — it converts a rip-and-replace into a swap.Compatibility Verify against our actual DB (MySQL 8 and Postgres behave differently for ordering/recursive queries), our cache driver (menu trees are natural cache candidates; confirm invalidation hooks exist or add them), and our auth layer (menus keyed to roles must read our Gate definitions). Confirm the package does not register global middleware or route groups that conflict with ours — if it does, disable them in the provider.
Sequencing Spike (3 days) → go/no-go with a written recommendation → fork and modernize or select an alternative (1 sprint) → interface wrapper and data migration (1 sprint) → cutover behind a feature flag with both renderers live for one release → remove the flag and the package's unused surface. Do not start this work in the same sprint as a framework upgrade; the dependency-resolution failures will be indistinguishable from upgrade noise.
Maintenance The honest number is that we inherit maintenance. Budget roughly 1–2 engineer-days per quarter for dependency drift and a one-time 3–5 days to fork and modernize. That is acceptable for a navigation component only because the surface is small; it would not be acceptable for anything on the transaction path. Record the fork point in an ADR so a future team knows why a 6-star package sits in our dependency graph.
Support None available. No issue triage, no security advisories, no maintainer to escalate to. Support model is internal: one named owner, a README in the fork explaining our divergence from upstream, and a rule that upstream is not merged from — we patch forward only. Set expectations with stakeholders explicitly: this is not a vendor relationship.
Scaling Menu trees are small (tens to low hundreds of rows) and read-mostly. The scaling concern is not row count but query count — naive implementations re-query per item during render, which turns a layout partial into N+1 queries on every page. Require eager-loaded trees plus a cache key invalidated on menu write. Under that pattern it scales to any realistic traffic; without it, it is a per-request tax on every page in the app.
Failure modes
<ul>; needs an assertion in the smoke suite.Ramp-up Low for a Laravel-fluent engineer: the domain is intuitive and the package is small enough to read end to end in an afternoon. The real ramp-up cost is the fork's tribal knowledge — why we diverged, what we patched, what we deliberately left broken. That cost is paid by whoever joins next, so it must be written down at fork time, not reconstructed later. If the team has no Laravel 5 experience, add a week; if the team is already on Laravel 10+, skip the package entirely and build the 200-line equivalent.
How can I help you explore Laravel packages today?