forci/locale-bundle
forci/locale-bundle is a PHP locale management bundle for multilingual applications. It provides locale configuration and detection utilities to help route users to the right language and integrate localized content, making it easier to build and maintain localized experiences.
Architecture fit — not a fit; this is a reference artifact, not a dependency. The critical fact for a TPM is that forci/locale-bundle is a Symfony bundle, and Laravel does not implement the Symfony bundle contract. There is no registerBundles(), no Extension auto-loading, no compiler-pass pipeline. Laravel consumes Symfony components (HttpFoundation, Routing) — not bundles. So the package cannot be installed and "just work"; at best a fraction of its plain-PHP service classes could be lifted out and rewired by hand. The -bundle suffix is the tell, and it should end the install conversation early.
The deeper architectural point worth socializing: Laravel's first-party localization already covers the intended feature set. App::setLocale(), lang/ catalogs, __(), $request->getPreferredLanguage($available), and route prefixing via ->prefix('{locale}') collectively do what this bundle advertises — request-source locale detection, default/fallback, and translator integration. Adopting a third-party bundle for this is not an architecture improvement; it's a net addition of surface area.
Integration feasibility — effectively zero, and the cost/benefit is upside-down. With 1 star, 0 dependents, and a score of 0.005, there is no evidence of production use anywhere, no signal on test coverage or CI, and no visible release cadence. A Symfony 3/4-era bundle will declare constraints against symfony/framework-bundle in the ^3/^4 range; a modern Laravel app ships Symfony 6/7 components. Composer will either refuse resolution or require a replace/alias hack — destabilizing the dependency graph to obtain a capability that is a 1–2 day native build. That trade is indefensible on any dimension a TPM is accountable for: cost, risk, or time-to-market.
Technical risk — high, with one hard stop-ship item.
NOASSERTION is a legal blocker, not a nitpick. It means no recognized OSI license was detected — possibly a custom or malformed license file, possibly no grant of rights at all. This cannot enter a commercial codebase without counsel review, and there is a real possibility the answer is "no." That is a schedule risk on the critical path, not a footnote.Key questions to answer before spending another hour on it:
LICENSE file, what does it say, and does it grant commercial use and redistribution? (Legal owns this answer.)composer.json? Any dependency on symfony/symfony (monolithic) is disqualifying outright.LuneticsLocaleBundle), and is upstream healthier?Stack fit — no direct path; frame this as a port or a spec, never an install. The only defensible uses in a Laravel context are (a) reading it as a reference implementation for negotiation/fallback structure, and (b) using it to sanity-check an internal effort estimate. The capability mapping is roughly one-to-one against Laravel primitives, which is precisely why the dependency is unnecessary:
| Bundle capability (likely) | Laravel-native equivalent | Effort |
|---|---|---|
| Request-source locale resolution | Custom middleware + App::setLocale() |
~2h |
Accept-Language negotiation |
$request->getPreferredLanguage($available) |
Native |
| Session/cookie locale persistence | session()->put('locale', …) |
Native |
Locale-prefixed routing (/fr/, /de-de/) |
Route ->prefix('{locale}') + Route::pattern |
~2h |
| Locale switcher endpoint | Controller + redirect-back | ~1h |
| Translation catalog loading & fallback | lang/ directories, __(), fallback_locale |
Native |
Migration path — recommend not installing. Three options, ranked:
SetLocale middleware we own and test. ~1–2 engineer-days, zero dependency risk, no legal entanglement.mcamara/laravel-localization covers locale-prefixed routing far more completely, with real adoption, active maintenance, and a clear MIT license. This is the correct escalation path for anything beyond the simple case — and it is a different decision from this one.ServiceProvider, ignore the bundle class, pin transitive Symfony constraints. This trades a few hundred lines of code for a permanent maintenance liability and a latent upgrade hazard.Compatibility — the gating check is composer.json, and it likely fails. Anything requiring symfony/framework-bundle outside ^6.0|^7.0 is disqualifying for Laravel 10/11. A dependency on the monolithic symfony/symfony is an immediate no — it conflicts with Laravel's per-component requirements and will not resolve.
Sequencing (two weeks, most of it not engineering):
LICENSE, escalate to legal only if a stakeholder insists on pursuing the code. Do not let engineering time be spent ahead of a legal answer.pt-BR vs pt), RTL locales, and missing-translation fallback.Maintenance — adoption equals full ownership from day one. With 1 star and 0 dependents there is effectively no upstream. Every future PHP or Laravel upgrade becomes a manual patch against code we didn't write and can't upstream. Total cost of ownership is the initial port plus an open-ended patch tail, measured against a 1–2 day native build. The arithmetic doesn't close, and the tail is the part that gets underestimated in the estimate.
Support — none exists. No community, no issue triage, no security-disclosure process, no Stack Overflow footprint. There is no one to escalate to, and the only behavior spec is the source. "Vendor support" is not a fallback here; there is no vendor.
Scaling — a non-issue either way. Locale negotiation is a per-request CPU operation with no I/O beyond a session or cookie read; it's measured in microseconds. The only meaningful optimization is caching the available-locale list in config rather than scanning the lang/ directory per request — and that applies identically to any implementation. This package introduces no scaling hazard and no scaling advantage, which means scaling is not a reason to adopt it.
Failure modes to design against (all implementation-independent, all easier to verify when we own the code):
Accept-Language dropping to default with no log line produces a user-visible language regression that surfaces only via support tickets. Instrument the fallback path with a counter and alert on drift.Vary: Accept-Language) or exclude the route. This is the single most common production defect in locale middleware; an opaque third-party implementation makes it materially harder to verify.composer update fails resolution on a pinned Symfony constraint, blocking unrelated security patches across the whole application.Ramp-up — low technical, non-trivial organizational. The domain is well understood and Laravel's primitives are documented, so an engineer is productive in a day. The real cost is organizational: legal review time for NOASSERTION, plus the standing cognitive load of an undocumented, unowned dependency sitting in the locale path — a cost that recurs every time someone touches that code and has to reverse-engineer intent from source.
Recommendation for the roadmap. Do not adopt; do not install. Log the decision and the rejected dependency so it stops resurfacing. Budget the locale-routing work as 1–2 engineer-days inside the market-entry epic, and keep the localization conversation — content, RTL, formatting, search — explicitly separate, because that is where the actual budget and schedule risk live. If a stakeholder insists on evaluating the source further, the first and only next step is a license determination from legal; engineering time should not be spent ahead of that answer.
How can I help you explore Laravel packages today?