softspring/translatable-bundle
A Symfony bundle for building translatable Doctrine entities, letting you store and manage per-locale field values with locale fallback, so the same content can be served in multiple languages without duplicating your models or templates.
Package identity is the headline finding, not a footnote. softspring/translatable-bundle is a Symfony bundle that adds translatable-field behaviour to Doctrine ORM entities. The brief calls this a "Laravel/PHP package." Those are not the same artefact and the gap is structural, not cosmetic. The bundle's entire value proposition — entity listeners, per-locale translation tables, Doctrine unit-of-work integration, Symfony DI service wiring — has no analogue in Eloquent. A TPM's first job here is to resolve whether the consuming system is Laravel or Symfony before any technical evaluation is worth the time. If the answer is Laravel, the assessment ends at "not applicable" and we should redirect to Laravel-native options (spatie/laravel-translatable, astrotomic/laravel-translatable, or laravel-doctrine/orm if the team has genuinely committed to Doctrine).
Architecture fit (assuming a Symfony consumer). Translatable content is a cross-cutting persistence concern. Adopting a third-party bundle means accepting its translation-table schema conventions, its locale-resolution and fallback semantics, and its listener lifecycle into the domain layer. That is a reasonable trade for a CRUD-shaped content model; it is a poor trade if we already have a localisation strategy, or if any read path bypasses Doctrine (document store, read-model projections, search index as source of truth) — the bundle's guarantees stop at the ORM boundary.
Integration feasibility. Non-trivial but bounded: requires Doctrine ORM, Symfony DI, and a schema carrying one translation table per translatable entity. The real feasibility risk is version floors — minor bumps in this family have historically moved the minimum PHP/Symfony/Doctrine constraints, and a floor change can cascade through the rest of the dependency graph.
Licence is a gating item, not a formality. AGPL-3.0 is a strong copyleft with a network-use clause (Section 13). If the consuming product is distributed, or if modified source is exposed to users over a network, the source-offer obligation attaches to the combined work. For an internal-only deployment with no external network interaction the exposure is lower, but that is a legal determination, not an engineering one. Counsel must clear this before engineering spend. It is the single most likely reason to reject the package regardless of technical merit.
Adoption signal is weak. Zero stars, a composite score of ~20.5, and a release note (v5.6.0) containing nothing but an auto-generated compare link. That combination means: no third-party bug corpus, no Stack Overflow surface, no community triage of edge cases, and no way to size an upgrade's blast radius in advance. Support load lands entirely on our team. The listed release date (2026-10-08) should also be verified before this enters a dependency register — metadata hygiene matters when the package is this thin.
Technical risk. Moderate-to-high, weighted toward process and legal rather than code: (a) framework mismatch, (b) AGPL obligations, (c) undisclosed minor release touching entity persistence — the class of dependency where silent behaviour changes (fallback order, proxy handling, hydration strategy, join shape) surface as data bugs, not exceptions, and therefore after users have seen wrong content, (d) near-zero ecosystem validation, (e) single-vendor continuity.
Key questions
Stack fit. Decisive. Symfony + Doctrine: fits, adopt at a pinned minor. Laravel + Eloquent: does not fit — there is no supported path, and attempting one means reimplementing the bundle's listener and schema layer inside Eloquent, at which point we are not using the package, we are cloning it. Laravel + laravel-doctrine/orm: technically possible, but the bundle still assumes Symfony DI and Symfony configuration loading. We would be maintaining a compatibility shim, inheriting two mental models (Eloquent and Doctrine) and two migration toolchains, and owning the integration surface ourselves. That is a "no" dressed up as a "maybe."
Migration path. Four states, only two of which are cheap:
^5.6, declare translatable entities, generate and review Doctrine migrations, backfill default-locale rows, wire fallback configuration explicitly.composer update softspring/translatable-bundle constrained to ^5.5.10|^5.6; the acceptance test is an empty doctrine:schema:update --dump-sql and a green localisation suite.Compatibility. Two surfaces. The visible one is composer constraints (PHP, Symfony, Doctrine ORM). The quiet one is the generated schema — a minor release can alter column types, index coverage, or association mappings, producing a schema diff that reads as benign and is not. Treat a non-empty diff on a minor bump as a stop-and-review event.
Sequencing
composer.json constraint delta, before touching a branch.~5.5.10 to stop incidental pickup.Maintenance. High release cadence paired with absent changelog discipline. Cadence plus low disclosure is the combination that turns dependency management into archaeology: every bump requires diff-reading rather than release-note-reading. Budget recurring time per release, or accept silent drift. Zero stars means no upstream community is absorbing that work for us.
Support. Single-vendor, small-team open source. No SLA, no confirmed security-advisory channel, no commercial backstop, no third-party bug corpus to search. For a persistence-layer dependency that is a risk-register entry, not an assumption to wave through. AGPL obligations also become an ongoing operational control — not a one-time legal checkbox — if we modify the package.
Scaling. Translation-table designs scale in rows, not entities: one row per entity per locale. Watch for (a) join explosion on listing and search queries, (b) N+1 loading of translations in collections, (c) index coverage on (translatable_id, locale), and (d) read-replica lag on locale-switching reads. None of these are v5.6.0-specific, but a minor release can shift hydration strategy and change query counts — which is precisely why the diff is load-bearing.
Failure modes
Ramp-up. For a Doctrine-fluent team: roughly a day to productive, a week to confident. For a Laravel/Eloquent team the ramp-up is not the bundle — it is Doctrine's unit of work, entity listeners, proxy behaviour, and migration tooling. That is weeks, and it is the true cost driver if this package is being weighed for a Laravel codebase.
Recommendation. For a Laravel system: do not adopt — this is the wrong artefact category, and the correct action is to close the evaluation and assess a Laravel-native translatable package instead. For a Symfony/Doctrine system: pin, read the diff, obtain licence clearance, and re-assess with real changelog content. Confidence in this assessment is low — it is derived from package identity, a version string, a licence identifier, and adoption metadata rather than from release content, which does not exist.
How can I help you explore Laravel packages today?