nelmio/esi-debug-bundle
A Symfony bundle that adds debugging support for Edge Side Includes (ESI). Use it during development to inspect ESI fragments, understand how includes are rendered behind a caching reverse proxy such as Varnish, and troubleshoot fragment caching and request behavior more easily.
Architecture fit — Poor for a Laravel codebase. nelmio/esi-debug-bundle is a Symfony bundle built to decorate Symfony's HttpKernel request/response cycle and render a panel inside WebProfilerBundle. It assumes Symfony's bundle registration, DI container tags, kernel.request/kernel.response event subscribers, Twig template paths, and the profiler data-collector contract. Laravel has none of these primitives: no bundles, a different container, its own middleware pipeline, and no profiler to hook into. The package also presumes ESI actually exists in the stack — Laravel core ships no ESI handling at all; ESI in a Laravel project normally lives at the reverse proxy or CDN (Varnish, Fastly, nginx ssi), where PHP never sees the subrequests. The core value proposition — "show caching information around ESI requests" — is only meaningful if ESI subrequests are being resolved inside PHP, which is a Symfony HttpCache/FrameworkBundle idiom, not a Laravel one.
Integration feasibility — Effectively zero as a dependency. The realistic options are (a) a full port of the data collector into a Laravel package or a Telescope/Debugbar watcher, or (b) replacing the need entirely with edge/proxy tooling. Given the repository is archived, ~43 stars, and 0 dependents, there is no ecosystem to lean on, no maintainer to ask, and no upstream fixes. Expect the composer constraints to target PHP 5.x/7.0-era Symfony; installing on PHP 8.2+/Laravel 10–11 would require --ignore-platform-reqs and would likely fatal on removed Symfony APIs and Twig signatures. A port is a small-to-medium engineering task (a middleware that records subrequest timing/cache headers, a collector, and a UI panel), but it is a rewrite, not an integration.
Technical risk — High and asymmetric. Archived + abandoned means no security patching, no PHP/Symfony/Laravel version drift support, and no CVE response path — a hard blocker for anything with compliance or audit obligations. The upside is bounded: this is a local-only debugging convenience that should never ship to production. Zero dependents signals either a very narrow niche or an idea that has been superseded by better tooling (browser devtools, X-Cache/Age/Surrogate-Control headers, Varnish varnishlog, Fastly X-Cache debugging, Laravel Telescope). The failure mode is not "breaks the app" — it's "quietly wrong cache insight," which is worse for a debugging tool because it can mislead performance work.
Key questions — (1) What is the actual problem: debugging ESI subrequest composition, or auditing cache hit/miss behavior? The former needs edge tooling; the latter is served by headers and Telescope. (2) Is there any ESI in our stack at all today, and if so, at which layer — proxy, CDN, or PHP? (3) If we need PHP-side ESI, are we prepared to own a fork (security, PHP 8.x, Laravel 11) indefinitely? (4) Can we meet the same need with a ~200-line internal middleware plus a Telescope watcher, avoiding third-party abandonment risk entirely? (5) Does anything in our stack still run Symfony, in which case a pinned, vendored copy may be tolerable for a legacy tool?
Stack fit — Mismatch at every layer. Composer will resolve, but the runtime contracts (Symfony EventDispatcher subscribers, DataCollectorInterface, @Twig template resolution, services.yml tags) have no Laravel analogue. Laravel's middleware pipeline is a linear onion, not a tagged event system with priority ordering, so the bundle's assumption that it can observe every ESI subrequest as a discrete kernel event does not hold. The only sane framing is: treat this repository as a reference implementation, not a dependency.
Migration path — There is no migration path in the usual sense; there is a reimplementation path. Concretely: (1) decide whether ESI resolution will happen in PHP at all — if the answer is "at the CDN," stop here and invest in proxy observability instead; (2) if PHP-side, build a ResolveEsiSubrequests middleware that parses <!--esi ... --> / <esi:include> blocks, dispatches internal subrequests, and stamps each with timing, cache status, and upstream headers; (3) expose those records through a container-scoped collector; (4) surface them in an existing panel — Laravel Debugbar's custom collector API or a Telescope watcher entry — rather than building new UI; (5) gate everything behind APP_DEBUG and a config flag with a hard production off-switch. That sequence reuses the bundle's design (what to record, how to present it) while discarding its delivery mechanism.
Compatibility — Assume broken on PHP 8.1+ and Laravel 9+. Verify before any spike: composer why-not php 8.2 on the extracted package, and inspect the abandoned symfony/* transitive constraints. If a legacy Symfony 2/3 service exists in the estate, a vendored, version-pinned copy is defensible for that service only; it must never enter a shared Laravel monorepo's composer.json.
Sequencing — Week 0: confirm the ESI requirement and its layer (proxy vs PHP). Week 1: prototype a header-based cache audit (X-Cache, Age, Surrogate-Key, Cache-Control) against staging — this likely answers 80% of the question for near-zero cost. Week 2–3: only if PHP-side ESI is confirmed, build the middleware + Telescope watcher internally and record a short ADR explaining why the archived package was not adopted. Defer any port indefinitely if the proxy path suffices.
Maintenance — Low if not adopted; unbounded if forked. An archived bundle with 0 dependents becomes our code the moment we vendor or port it — we inherit every future PHP/Laravel compatibility break with no upstream. A ~200-line internal middleware plus a Telescope watcher, by contrast, has a small, familiar, testable surface owned by the team, written in idioms the team already knows.
Support — None available. No maintainer response, no issue triage, no release cadence. Any incident traced to the bundle is a self-service debugging exercise against code last touched years ago. That is an unacceptable support posture for anything beyond a throwaway investigation.
Scaling — The tool itself is debug-time only and should be off in production, so runtime scaling is not a concern — provided the production off-switch is enforced, not merely documented. The real scaling risk is organizational: adopting an abandoned Symfony-era dependency invites copy-paste of the same pattern into other Laravel services, each carrying its own unfixable transitive tree.
Failure modes — (1) Silent no-op: the collector registers but records nothing because Laravel emits no matching events, producing false confidence that ESI caching is healthy. (2) Install-time rot: platform-requirement conflicts force --ignore-platform-reqs, which then hides genuine incompatibilities. (3) Misleading cache attribution: ESI semantics differ between Varnish, Fastly, and Symfony HttpCache; a tool modeling Symfony's will report wrong hit/miss ratios for a CDN-fronted Laravel app. (4) Debug leakage: profiling data reaching production, exposing internal cache keys and topology. (5) Dependency sprawl: pulling an unmaintained Symfony subtree into a modern Laravel app for a convenience feature.
Ramp-up — Reading and understanding the bundle is a few hours for an engineer fluent in Symfony; mapping it to Laravel is a day. Building the equivalent internally is roughly 3–5 engineer-days including tests and panel wiring, with the caveat that it should not start until the ESI-layer question is settled. The cheapest first step by a wide margin is a half-day of header inspection on staging, which may render the whole exercise unnecessary. Recommendation: do not adopt; mine for design, validate the ESI requirement at the edge first.
How can I help you explore Laravel packages today?