theodo-evolution/legacy-wrapper-bundle
Theodo Evolution's Symfony bundle for wrapping legacy PHP applications and migrating them incrementally. It routes legacy requests through Symfony, bridges sessions, services, and authentication, and lets old and new code coexist so teams can modernize without a risky big-bang rewrite.
Architecture fit. Despite the “Laravel/PHP” framing, this is a Symfony bundle, not a Laravel package. Its architecture implements a strangler-fig pattern: run a legacy PHP application behind a Symfony kernel, intercept unmatched routes, and bridge session/request state so old and new code coexist during incremental migration. That pattern is sound and well understood. The implementation, however, is coupled to Symfony's HttpKernel, Request/Response, and bundle configuration conventions. In a Laravel-first estate there is no native seam for it: you would either introduce Symfony alongside Laravel (unusual and operationally expensive) or reimplement the pattern with Laravel middleware and Route::fallback.
Integration feasibility. Low as-is. The last release was 2018-04-11, stars are 40, and there are zero Packagist dependents. Composer constraints almost certainly target PHP 5.6/7.x and Symfony 2/3. On PHP 8.2+ and Symfony 6/7 or Laravel 10/11, dependency resolution will fail without a fork, constraint overrides, and code changes. There is no Laravel service provider, no PSR-15 middleware, and no evidence of a maintained test matrix against modern runtimes.
Technical risk. High. The package is effectively abandoned: no security patching, no upstream issue triage, no known production users to de-risk the edge cases. The pattern itself introduces request-lifecycle complexity — nested kernels, subrequests, session and cookie bridging, header stripping, error-handler conflicts — which is hard to debug and easy to get subtly wrong. Using an unmaintained dependency at the boundary of a migration increases the blast radius precisely where reliability matters most.
Key questions.
try_files/proxy_pass, Laravel Route::fallback, or a custom middleware — achieve the same migration outcome with less coupling?Stack fit. Poor for a Laravel-centric stack. Moderate only if the organization already runs Symfony and the legacy app is PHP-based. The conceptual model — wrap legacy, route by fallback, share session — translates to Laravel, but the bundle does not.
Migration path. If pursued, treat it as an internal fork, not a dependency: vendor the code under an internal namespace, pin PHP and Symfony/Laravel versions, add a Laravel/Symfony bridge, and replace bundle-specific configuration with explicit middleware. In parallel, evaluate a lighter-weight alternative: terminate routing at the edge (Nginx/Traefik) and proxy only unmatched paths to the legacy app, or implement a Laravel fallback route that dispatches to the legacy front controller. These achieve the same strangler behavior with fewer framework assumptions.
Compatibility. Validate against PHP 8.2/8.3, Symfony 6/7 or Laravel 10/11, and PSR-7/PSR-15 where applicable. Expect breakage in HttpKernel signatures, event dispatcher APIs, session handling, and deprecated bundle extension patterns. Budget for a compatibility spike before committing.
Sequencing.
Maintenance. Effectively zero upstream maintenance. Internal ownership is mandatory: expect ongoing work for security patches, PHP/Symfony upgrades, and compatibility fixes. A realistic estimate is 0.25–0.5 FTE during active migration, tapering but never zero.
Support. No vendor, no community of dependents, sparse documentation. Runbooks, architecture decision records, and internal on-call training are required. Debugging spans two applications, so support burden is inherently higher than a single-stack service.
Scaling. The wrapper adds a proxy/subrequest hop: extra latency, memory, and connection overhead. Scaling characteristics will be dominated by the legacy application, but the wrapper can become a bottleneck under concurrency. Load-test with realistic session and payload sizes; set strict timeouts and circuit-breaking around legacy calls.
Failure modes. Session loss or cookie-domain conflicts; CSRF token mismatch across kernels; header and body corruption on subrequests; routing loops or fallback recursion; double error handling and masked stack traces; asset path collisions; memory exhaustion from nested kernels; silent divergence between legacy and new behavior. Each needs a detection and rollback playbook.
Ramp-up. Even strong Laravel developers will need 1–2 weeks to understand Symfony's HttpKernel request lifecycle and the wrapper's routing/session model before making safe changes. Add time for legacy application domain knowledge. The opportunity score (11.28) reflects a real and recurring migration problem; the package score (1.66), zero dependents, and 2018 release date indicate the package is not a viable dependency without a fork. Recommendation: adopt the pattern, not the package — prototype with Laravel middleware or an edge proxy first, and only fork this bundle if a Symfony-based legacy stack makes it a direct fit.
How can I help you explore Laravel packages today?