shchedrakov/translation-bundle
A PHP translation bundle for managing localized strings in your application. It helps organize translation resources, simplify multilingual support, and integrate message catalogs into your existing framework setup with minimal configuration.
Architecture fit — poor, and mismatched at the framework level. Despite the framing of this review, shchedrakov/translation-bundle is not a Laravel package. It is a Symfony2 bundle (a fork of the long-abandoned JMSTranslationBundle), and its entire architecture assumes the Symfony full-stack runtime: a Bundle class registered in AppKernel, a DependencyInjection/*Extension that loads XML/YAML service definitions at container compile time, annotation-driven routing for a browser-based translator UI, and console commands wired through symfony/console and the Symfony Application. Laravel has no equivalent bundle/compiler-pass/kernel-bundle lifecycle. There is no service provider, no facade, no config stub — nothing that would let composer require resolve into a working Laravel application.
Integration feasibility — effectively blocked at dependency resolution. The bundle's composer.json targets Symfony 2.x components (symfony/framework-bundle, symfony/http-kernel, doctrine/annotations, twig/twig of that era). Laravel 10/11 pin Symfony 6/7 components transitively. Composer will refuse to install due to hard constraint conflicts; forcing it requires --ignore-platform-reqs plus an aliasing hack, which lands us in an unsupported, unresolvable dependency graph. Even if installed, the extractors are written to recognise Symfony/Twig translation idioms — {{ 'key'|trans }}, $translator->trans('key'), transChoice() — and would silently miss Laravel's __(), @lang, trans() with :placeholder interpolation, and |-delimited pluralisation. The extracted catalogs would be wrong in a way that is expensive to detect.
Technical risk — high and unmitigated.
| Risk | Severity | Notes |
|---|---|---|
| Abandonment | Critical | Last release 2018-03-15; 0 stars, 0 dependents — no community, no upstream fixes, no security policy |
| Runtime EOL | Critical | Symfony 2.x and the PHP 5.6/7.0-era idioms are years past end-of-life |
| Dependency conflicts | High | Irreconcilable with current Laravel's Symfony pins |
| Semantic mismatch | High | Extraction targets Symfony idioms; Laravel idioms missed silently |
| Attack surface | Medium | Ships an annotation-routed web UI that writes translation catalogs to disk |
| Licensing | Low/Medium | Fork's license must be verified against the upstream JMS terms before any vendoring |
Key questions for the requester:
Stack fit: do not integrate the bundle. Decompose its value. The bundle bundles three concerns; each has a better-fit answer in a Laravel stack:
lang/ files (__(), @lang, pluralisation, :placeholder replacement) or spatie/laravel-translation-loader if DB-backed catalogs are required. Native, zero risk.nikic/php-parser for PHP string-literal discovery plus a Blade-aware regex/parser pass for @lang/__() in templates. Roughly 1–2 engineer-weeks, and it will be more accurate on Laravel code than the Symfony extractor ever could be.Migration path (if the org already runs this bundle on a legacy Symfony 2 app): treat it as an extraction-only utility during migration. Run one final jms:translation:extract against the legacy codebase, export the catalogs as XLIFF/PO, and import them into the Laravel lang/ tree or the TMS. Then retire the bundle with the Symfony app. Do not carry it forward.
Compatibility: any attempt to keep the bundle alive requires vendoring classes into app/Support/ or a private internal/translation-extractor repo, stripping the DI/console/routing integration, and pinning symfony/translation to a modern version. That is a rewrite, not an integration — budget it as such.
Sequencing:
composer require in a throwaway Laravel skeleton to produce a concrete, citable conflict report. Cheap, removes ambiguity, and gives the requester evidence rather than opinion.lang/ only."php artisan translations:pull|push, with tests asserting extraction parity against a fixture corpus.Maintenance. Upstream maintenance is zero — 0 stars and 0 dependents is the quantitative signal that nobody is watching this repository. Adopting it means we inherit the entire maintenance burden: PHP version bumps, Symfony component churn, security patches, and any bug in the extraction or UI layers. Realistically that is 0.1–0.2 FTE of standing ownership for a capability we can otherwise buy or build once.
Support. No vendor, no maintainer responsiveness, no issue triage. Internal escalation path is "the one engineer who read the Symfony 2 source." Documentation is limited to legacy JMS docs from the early 2010s, which describe behaviour this fork may or may not match. Onboarding cost is high relative to the small surface area of the problem.
Scaling. Translation volume is rarely a bottleneck, so throughput is not the concern. The concerns are: (a) the extraction command is a full-codebase parse — on a large app it must be chunked or it becomes a memory and CI-time problem; (b) the translator UI writes catalog files to the filesystem, which does not survive horizontal scaling or containerised deploys without shared storage; (c) it will interact badly with Laravel's config/route/event caches, since it assumes Symfony's container-compile model. None of these are fatal in isolation; together they mean a bespoke operational runbook for a non-core capability.
Failure modes to watch. Silent under-extraction is the dangerous one — strings simply never appear in the catalog, ship untranslated, and are discovered by users rather than by CI. Second is catalog overwrite: the UI writes files that may also be edited in-repo, producing merge conflicts and lost translator work. Third is encoding corruption on non-UTF-8 source files. Mitigation for all three is the same: never adopt this; if a legacy app depends on it, wrap the final export in a diff-and-review step before import.
Ramp-up. For a team without Symfony 2 exposure, expect 2–4 weeks before an engineer is productive in the bundle's internals — disproportionate for a translation tooling need, and sunk cost if we later move to a TMS anyway.
Recommendation: reject. The package fails the dependency-conflict test, the framework-fit test, and the maintainability test independently. Capture the requirement it was sourced against, confirm whether the need is extraction, workflow, or storage, and address that need with Laravel-native translation plus a purchased TMS and a purpose-built extractor. If a legacy Symfony 2 application still runs it, schedule a one-time catalog export and decommission.
How can I help you explore Laravel packages today?