knplabs/twig-explorer-bundle
Symfony bundle that integrates Twig Explorer, providing a browser-based interface to browse and inspect Twig templates. Quickly view template source, inheritance, and structure to debug and better understand your views during development.
Architecture fit — poor for a Laravel target, marginal at best for Symfony. This is a Symfony bundle, not a Laravel package: it ships a Bundle subclass, a DI Extension, tag-based compiler passes, and routes loaded through Symfony's routing component. Laravel has no bundle contract, so consuming it would require a service-provider shim that re-registers routes and translates Symfony's tagged-service introspection into the Laravel container. Twig itself is not native to Laravel — it only arrives via a third-party bridge (rcrowe/twigbridge) — so any integration stacks a second unmaintained dependency on top of this one. For a TPM the first decision this supports is a fast, documented "no" for any Laravel roadmap item, unless a legacy Symfony/Twig estate is in scope.
Functional value — largely duplicated. The bundle enumerates Twig filters, functions, tests, tags, and globals in a browser UI. Symfony/Twig already ship debug:twig, debug:twig --filter=..., and lint:twig, which return the same metadata; on Laravel, artisan view:*, Telescope, and Blade component docs cover analogous ground. The differentiator is a browsable interface, i.e. a developer-convenience delta, not a platform capability. That matters to a TPM because convenience deltas rarely justify inheriting dead code.
Integration feasibility — low. The project is archived, has 23 stars and zero dependents, and belongs to the PHP 7.x / Symfony 2.8–4.x / Twig 1–2 era. On a modern stack (PHP 8.1+, Symfony 6/7 components, Twig 3) Composer resolution will almost certainly fail on version constraints, and a forced install would still hit Twig 3 API changes (getFunctions()/getFilters() signatures, NodeVisitor deprecations, Bundle::getPath() requirements). There is no upstream to fix any of this.
Technical risk — high and asymmetric. Archived status means no security patches and no compatibility work, ever; most dependency policies will flag it automatically. The bundle exposes an in-process HTTP surface enumerating template paths, extension names, and globals — a non-trivial information-disclosure vector if the dev-only gate is ever misconfigured. Zero dependents means no field validation; the organization would become the sole consumer of dead code.
Key questions for the requester:
debug:twig, lint:twig, Xdebug/SPX, or a small internal command).Twig\Environment::getExtensions()) satisfy the requirement without the supply-chain exposure?Stack fit — none for Laravel, marginal for Symfony. For a Laravel codebase the defensible answer is "do not integrate"; the value is as a reference design, not a dependency. For a Symfony codebase the only acceptable placement is require-dev, dev/local environment only, behind an authenticated firewall and an IP allowlist — never in a shared or production environment.
Migration path — replace, don't adopt. The extraction logic is thin: iterate Twig\Environment::getExtensions(), read getFilters(), getFunctions(), getTests(), getTokenParsers(), and reflect on GlobalsInterface. That is a day's work in a small internal Artisan command (php artisan twig:inspect) or a dev-only route, delivered with full ownership of the surface area, zero supply-chain risk, and no fork to maintain. For Symfony teams, prefer the maintained first-party CLI over a port.
Compatibility constraints to verify before any spike:
^7.1 — incompatible with Laravel 10/11 and PHP 8.2+.symfony/framework-bundle, symfony/routing: expect ^2.8|^3.0|^4.0.twig/twig: expect ^1.0|^2.0; Twig 3 breaks the reflection paths.Sequencing if a spike is approved (timebox: two days, hard stop):
APP_ENV=local, behind auth middleware and IP restriction.debug:twig; if parity, discard the fork and ship the internal command.Maintenance — inherited on day one. Archived repositories transfer 100% of maintenance burden at adoption: Twig major upgrades, Symfony component churn, and any CVE-adjacent patching with no upstream. Budget it as a small internal tool with a named owner, not as a dependency with a vendor.
Support — effectively nonexistent. 23 stars and zero dependents means no issue triage, no Stack Overflow corpus, no downstream fixes to cherry-pick, and a bus factor of one (whoever wrote the shim). Internal knowledge will be concentrated in that person.
Scaling — a non-issue, for the wrong reason. This is a single-node developer tool doing in-memory reflection over the extension set; cost is negligible even with dozens of extensions. It has no place in a request path, a CI gate, or a multi-tenant deployment, so horizontal-scaling questions simply do not apply. Do not let "it scales fine" be read as a green light.
Failure modes to design against:
local/dev — discloses template paths, filter names, and globals.getPath(), inheritance) causing hard boot failures on upgrade.Ramp-up — low cost, low return. A Symfony-fluent engineer reads the bundle in under an hour and gets real value from the explorer. A Laravel-only team learns nothing transferable; their effort goes into the shim, not the domain, and the underlying need is better served by Blade equivalent tooling.
Recommendation: Reject as a dependency. A score of 0.0725, archived status, zero dependents, and duplicated first-party functionality is a clear decline. Route the underlying capability to debug:twig/lint:twig on Symfony, or to a small internal inspection command on Laravel, and capture this package in the ADR log as an evaluated-and-rejected reference design.
How can I help you explore Laravel packages today?