ozankurt/laravel-intl
A Laravel package for internationalization built on PHP's intl extension, providing locale-aware helpers for formatting dates, numbers, and currencies, along with middleware and Blade directives to manage per-request locales in your application.
Position: a tactical convenience dependency, not a strategic platform bet. Adopt only behind an interface we own, and vendor it.
Architecture fit
intl extension (ICU NumberFormatter / IntlDateFormatter). No persistence, no schema, no background workers, no external services, no request-lifecycle hooks beyond a service provider and facade. Blast radius is small and confined to the rendering edge — which is exactly where locale formatting belongs.Integration feasibility
composer require, one Blade line to prove health, no migrations, no data backfill. The only hard dependency is ext-intl, which is an image/CI concern rather than an application concern.Technical risk
Intl is a heavily used facade alias; in a mature app this risks ambiguous or wrong class resolution.Key questions
intl capabilities are genuinely wrapped versus the ones we actually need? The gap sizes the residual work.app()->getLocale() or its own intl.locale config key? Determines whether middleware must set both — otherwise silent-fallback trap.ext-intl/ICU version runs in every environment, and do we control that image?Stack fit
ext-intl enabled. The composer PHP constraint is not stated here — verify against our minimum supported version before assuming.Intl.NumberFormat) or pre-formatted strings shipped from the API — decide which before rollout, not after.Migration path
Formatter interface (money, number, percent, date, list, plural) and bind the package behind it. This single decision caps exit cost at one file and makes swapping to raw ICU, an alternative package, or an in-house implementation a container-binding change plus a config toggle — no data migration, no downtime.ext-intl in every image (HTTP, CLI, queue, scheduler), publish config, prove output parity against current screens on 3–4 real surfaces.Accept-Language → app default; set both app()->setLocale() and the package config key, since resolution order is unconfirmed.Compatibility
en-US, never en_US). Audit and normalize any persisted locale/language columns first — in practice this is the largest hidden work item and it is independent of the package.ext-intl must exist in the base image, CI runner, and every job/worker image. Formatting that passes in HTTP can fail in a queued report.php artisan octane:reload after install and after every upgrade; long-running workers cache container state.config:cache freezes published defaults — runtime locale overrides must come from middleware or env-driven redeploy, not hand-edits to the config file.Intl alias if any other package claims it.Sequencing
intl helper. All three are viable; the differentiator is who owns the upgrade path.ext-intl, locale middleware, test locale pinning.Maintenance
Support
Scaling
NumberFormatter and IntlDateFormatter instantiation is expensive; reports and exports formatting thousands of rows will show it in profiles. Mitigate with memoization per (locale, style), a reused underlying formatter for bulk paths, or precomputation at write time — routing high-volume paths around the facade to the raw classes is the intended escape hatch.Failure modes (ranked by business impact)
ext-intl in a new image or job — loud, hard failure, easy to diagnose if a boot-time capability check fails fast.Ramp-up
How can I help you explore Laravel packages today?