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

Menu Bundle Laravel Package

zetta/menu-bundle

Zetta Menu Bundle is a PHP package for building and managing hierarchical navigation menus. It offers menu and menu-item models, tree operations, and integration points for Symfony applications, helping developers define, organize, and render multi-level menus with less boilerplate.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Verdict: Do not adopt. zetta/menu-bundle is not a Laravel package — it is a Symfony bundle (namespace Zetta\MenuBundle), released once in October 2015 and never touched since. At 9 stars, 0 dependents, and a composite score of 0.075, this is effectively abandoned software that fails the minimum bar for a production dependency.

Architecture fit — poor. The package is built around Symfony's runtime contracts: the DI container, the EventDispatcher, the Security component's authorization checker, and almost certainly KnpMenu/KnpMenuBundle for tree construction plus Twig for rendering. Laravel has none of these; it has the service container, the event dispatcher, Gate/Policy authorization, and Blade. Every integration point would need a shim. The only transferable asset is the idea — decorating menu items with a required role/permission and filtering the tree at render time via a voter — not the code.

Integration feasibility — not feasible as-is. A 2015 Symfony bundle will declare constraints against Symfony 2.x and PHP 5.x. Modern Composer resolution on PHP 8.2+ with Laravel 10/11 will fail on platform requirements at best; if forced through with --ignore-platform-reqs, it will fatal on removed Symfony APIs (ContainerAware, Controller, getRequest() semantics, security.context, Twig 1.x helpers). There is also no Laravel package discovery, no facade, no config publishing.

Technical risk — high and asymmetric. The upside is a small menu-filtering utility we could write ourselves in a day or two; the downside is an unpatched, unmaintained dependency in the authorization path of our UI. Security-critical code from 2015 has had zero CVE review since. A particularly dangerous failure mode: teams often treat a "secure menu" as the access control. Hiding a menu item is presentation, not authorization — if the underlying routes are not independently guarded, we ship an access-control illusion. That risk is inherent to the package's framing, not just its age.

Key questions for the spike:

  • What exactly does "secure" mean here — role-based visibility, or does it also enforce route-level authorization? (If the former, it is a UI helper, not a security control.)
  • Does it hard-depend on KnpMenuBundle, and which versions?
  • What is the license, and is the vendor (Zetta) still reachable for a fork/takedown decision?
  • Is there any internal consumer already vendoring this bundle that we would need to keep in lockstep with?
  • Are the menu definitions configured in YAML/DI XML (Symfony idiom) or in PHP — i.e., how much of our configuration would have to be re-expressed?

Integration Approach

Stack fit — none, by construction. We are standardizing on Laravel. This artifact targets a different framework, a different template engine, and a PHP runtime that reached end of life years ago. Recommendation is to re-implement the concept natively, treating the repository as a design reference only.

Migration path (concept port, not code port):

  1. Read the bundle's menu-building and voter logic; extract the behavioral contract: a menu node carries a required permission; a filter walks the tree and prunes nodes the current user cannot satisfy; pruning is recursive and respects parent visibility.
  2. Implement a thin MenuBuilder/MenuRenderer service in Laravel: nodes as value objects (label, route, ability, children), filtering delegated to Gate::allows() / $user->can().
  3. Render with a Blade component (or recursive partial), with a @can-style guard at the node level.
  4. Pair every menu ability with a matching route middleware or authorize() call in the controller — the menu is cosmetic; the policy is the control. Add a test that asserts every ability declared on a menu node is also enforced on the corresponding route.

Compatibility. If any legacy Symfony 2/3 service still needs this bundle, keep it pinned in that application only; do not attempt to bridge it into Laravel. Cross-framework menu sharing via a shared bundle is not worth the coupling.

Sequencing:

  • Day 1: 2-hour spike to confirm the Composer platform failure and document why (closes the question permanently).
  • Days 1–2: Write the native menu + gate filter, with unit tests covering nested pruning and empty-parent collapse.
  • Day 3: Backfill route-level authorization tests; audit any existing menu-hiding logic for the "hidden ≠ forbidden" gap.
  • Week 2: Publish as an internal package if more than one app needs it.

Operational Impact

Maintenance. Zero upstream maintenance; the maintainer's last commit is roughly a decade old. Any fix is ours to carry on a permanent fork, which means we own the entire surface for a component we could have written in two days.

Support. No issue tracker activity, no documentation beyond a README, no community. On-call engineers will be reverse-engineering PHP 5-era Symfony code during an incident. That is the worst possible shape for a dependency in a user-facing authorization path.

Scaling. Technically trivial — menu trees are built in memory per request, O(nodes), negligible. The real scaling concern is organizational: every new app that "just reuses the bundle" inherits the fork, the platform hacks, and the hidden-vs-forbidden ambiguity.

Failure modes to watch:

  • Composer install breaks silently on a PHP upgrade or a Symfony security patch.
  • Menu items render for users who should not see them (or vanish for users who should) after a gate/role refactor — with no upstream tests to catch it.
  • Erosion of the security boundary: developers stop adding route middleware because "the menu already handles it."
  • Abandoned-dependency scanner flags it quarterly, generating recurring triage noise.

Ramp-up. Conceptually near-zero — the domain is a filtered tree. But ramping a developer onto this codebase (Symfony 2 DI XML, Twig 1, security voters) is a multi-day cost for negative long-term value. Native Laravel implementation is familiar to the whole team on day one.

Bottom line for the portfolio: decline adoption, record the decision, and fund a ~3-developer-day native replacement. The only scenario that changes this recommendation is discovering an existing production Symfony 2 application that already depends on the bundle — in which case the work becomes a scoped removal plan, not an integration.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings