kevintweber/ktw-database-menu-bundle
A Symfony bundle for creating database-backed menus. Store menu items as Doctrine entities, manage navigation without code changes, and render dynamic menus in Twig templates. Useful for CMS-style applications with frequently updated navigation.
Positioning. The intake record labels this a "Laravel/PHP package," but it is a Symfony bundle that extends KnpMenuBundle with a Doctrine-backed menu provider. From a TPM standpoint, the deliverable of evaluating it is not an integration plan — it is a corrected classification, a scoped requirement definition, and an informed build-vs-buy recommendation. That is a legitimate outcome: a package can produce value by proving the feature category exists and by giving you a reference schema, even when it is never installed.
Architecture fit. The architectural concept — persist navigation structure as rows so non-developers can edit it — is framework-agnostic and maps directly to real product needs (content-ops self-serve nav, per-tenant and per-role menu variants, locale-specific labels, CMS-driven sites). The implementation is bound to Symfony's DI container, bundle registration, Doctrine entities/repositories, and KnpMenu's MenuProviderInterface. None of that transfers to Laravel's service provider / Eloquent / Blade idiom, and its era (Symfony 2.x/3.x generation, coupled to a specific KnpMenuBundle major) puts it well behind a modern Symfony 5/6/7 stack as well. In both plausible target environments, the integration surface is a rewrite, not an install.
Integration feasibility. Not viable as a dependency. As a port, it is a greenfield build of a small, well-understood domain: menus and menu_items tables with parent-child ordering, a provider that hydrates the tree in one or two queries, a recursive renderer with active-state resolution and depth limiting, an admin CRUD with drag-and-drop reordering, and cache invalidation on write. Realistic sizing is 1–2 developer-weeks including tests and admin surface — which is the number that should drive the decision, because it is small enough that ownership risk dominates any build saving.
Technical risk. High, and concentrated in provenance rather than complexity:
Key questions.
Recommendation. Do not adopt as a dependency. Use it as a design reference, build a small first-party implementation, or select a maintained package in the target ecosystem. Additionally, correct the intake misclassification so Symfony bundles stop consuming Laravel evaluation cycles.
Stack fit. Poor as-is, clean conceptually. The mapping is total replacement rather than adaptation: bundle registration → service provider; Doctrine entity → Eloquent model; MenuProviderInterface → repository or facade; KnpMenu rendering → Blade component or recursive partial. This is worth stating explicitly to stakeholders, because it means there is no partial-adoption path — you either port the pattern or you don't do it.
Migration path. There is nothing to migrate from, so frame the work as porting the pattern:
menus (key, name, locale) and menu_items (menu_id, parent_id, label, url/route, target, weight, visibility, timestamps). Adjacency list by default; add materialized path or nested set only if read depth justifies it.Compatibility. If a Symfony sibling service is in scope, validate its Symfony and KnpMenuBundle major versions before assuming anything — the bundle's constraints should be presumed obsolete until proven otherwise. For the Laravel build, pin the supported PHP and framework versions, confirm Doctrine-vs-Eloquent assumptions are fully discarded, and re-verify license and commit history if any code is copied.
Sequencing. (1) Requirement and editorial workflow confirmed with the content owner. (2) One-day spike on schema and cache strategy. (3) Build model, provider, and renderer behind a feature flag, keeping the current hardcoded menu as fallback. (4) Ship the admin UI. (5) Cut over per-menu rather than globally, so a bad tree is reverted without a deploy.
Roadmap placement. Dynamic navigation is a content-ops enabler, not a user-visible feature. It lands naturally with CMS-lite admin, tenant onboarding, or a marketing-site handover. Put "editable navigation" on the roadmap as a capability; never as "integrate this bundle."
Maintenance. Effectively 100% yours. Upstream will not patch, but the inherited surface is small enough that owning it is cheaper than tracking a fork. Allocate a modest ongoing budget for schema evolution (localization, permissions) and admin UX iteration — the latter tends to grow once content editors start using it.
Support. No vendor, no community, no security response. Internal documentation and a named owner are mandatory. On a small team this is a single-point-of-failure risk that should be written down explicitly rather than absorbed silently, and it belongs in the risk register next to the feature, not next to the dependency.
Scaling. Menu trees are small and read-heavy — near-ideal caching candidates. The realistic bottlenecks are query count per render (classic N+1 on recursive tree walks) and cache invalidation on edit. One or two indexed queries or a cached payload handles high traffic comfortably. The operational rule to enforce: per-request tree queries never reach production.
Failure modes.
Ramp-up. Low for a developer fluent in Eloquent and Blade: the domain is intuitive and the reference bundle's model is a reasonable opening sketch. The real learning cost is not code — it is establishing editorial conventions and cache discipline across the team. Estimate one to two days of onboarding for a mid-level developer, on top of the build effort above.
Stakeholder framing. For executives: the underlying need — letting non-developers edit navigation without a deploy — is legitimate and shows up in content-ops and multi-tenant roadmaps; this specific package is not the answer, it is a Symfony component in a Laravel-classified intake with zero adoption and no maintenance signal, and adopting it makes the team its permanent maintainer. Recommend not adopting, and if editable navigation enters the roadmap, budget a small internal build (roughly one to two sprints) or select a maintained alternative with active release history.
How can I help you explore Laravel packages today?