tempest/intl
Internationalization toolkit for Laravel: locale-aware formatting for dates, numbers, currencies, and translations. Ships multilingual apps with consistent output across locales, wrapping PHP's intl extension in a tidy, framework-friendly API.
Architecture fit. tempest/intl is not a standalone library — it is a Composer-distributed, read-only sub-split of the Tempest framework's internationalization component. The [READ ONLY] marker is the defining fact for a TPM: the repository is a publication artifact, not a development surface, so issues, PRs, and the roadmap all live upstream in the Tempest monorepo. Any adoption decision is therefore really a decision about the Tempest framework's trajectory, not about this package. For a Laravel codebase the architectural fit is poor: Laravel already ships a coherent, pervasive i18n stack (Lang, __()/@lang, Pluralizer, Number, Carbon for date/time, and the native intl extension underneath), all wired into the container, validation, and Blade. A framework-sibling component means maintaining two parallel i18n idioms with overlapping responsibilities and an unstated rule about which applies where.
Integration feasibility. Mechanically, Composer will install it. Practically, the component almost certainly depends on Tempest support/container primitives, which are not Laravel service providers and will not auto-register. Expect to write a custom service provider, hand-bind value objects, and verify whether configuration is read from Tempest's config layer rather than config/app.php. None of this is hard, but none of it is free, and every bound seam is a future breakage point on a pre-1.0 dependency.
Technical risk.
[READ ONLY] means we cannot carry a clean local fork — any emergency fix becomes a privately maintained fork we own indefinitely.intl extension, which Laravel developers can call directly or reach via symfony/intl — a package with a decade of Symfony-backed maintenance.Key questions.
Number/Carbon/native intl does not? If the answer is "nicer ergonomics," that is a preference, not a requirement.intl PHP extension, and is that present and pinned across CI, container images, and all target environments?Stack fit. Low. Laravel's i18n is opinionated and pervasive — validation messages, mail templates, Blade, pagination — all flow through Lang. A Tempest component sits outside that pipeline and cannot transparently inherit it. The realistic fit is narrow: use it strictly as a typed value-object layer for currency, number, and locale formatting in a bounded domain, never as the translation layer.
Migration path. There is no migration — there is an insertion. Recommend a strict containment strategy: adopt at the leaves (a reporting module, an invoicing formatter) behind our own thin interface (CurrencyFormatter, LocaleResolver), so the vendor type never appears in domain or controller signatures. If we later swap to symfony/intl or a native implementation, only the adapter changes. Do not attempt a wholesale replacement of Laravel's translator; the blast radius across validation, mail, and Blade is disproportionate to any gain.
Compatibility. Verify the PHP version floor and ext-intl presence first. Confirm the package's declared framework-agnosticism — it should have no illuminate/* constraints, which cuts both ways: it installs cleanly but integrates with nothing. Check for tempest/support or container dependencies and pin them explicitly. Run the full suite against our lowest supported PHP version, not just the current one.
Sequencing.
NumberFormatter plus a few helpers, close it out and use native intl. Be honest that the ergonomic gain must clear the governance overhead.composer.lock.Maintenance. Low code volume, high governance overhead. Renovate/Dependabot will surface frequent pre-1.0 minor bumps with potential BC breaks; each requires a human read of the upstream monorepo changelog, because the split repo will not summarize it. Budget roughly half a day per quarter for routine upkeep, plus unplanned time on breaks.
Support. The support channel is the upstream Tempest project's issue tracker — no SLA, no commercial backing, no guaranteed response. Escalation paths are effectively: fix it ourselves upstream and wait for a split, or fork privately. Neither is acceptable for a tier-1 revenue path; both are tolerable for internal tooling.
Scaling. Runtime cost is negligible — formatting is CPU-bound and cheap. The scaling concern is organizational: the number of places depending on this package should stay small and enumerated. Each additional consumer compounds migration cost if we exit.
Failure modes. Ranked by likelihood:
Number produces different grouping, decimal separators, or currency symbols for the same locale. This is the insidious one; it surfaces as customer-visible inconsistency and is hard to test for.ext-intl absent or version-divergent in a container, causing silent locale fallback to en.Ramp-up. A competent Laravel engineer reads the adapter in under an hour. The hidden cost is conceptual: the team must hold two mental models of i18n and know which applies where. That ambiguity is the real onboarding tax and argues for keeping adoption to a single, clearly-labeled module — or declining it outright.
Recommendation. Do not adopt as a platform dependency on current evidence; treat the 40.06 opportunity score as exploratory only. Run the one-sprint spike against native intl and symfony/intl in parallel and default to the incumbent unless the spike demonstrates a material, measurable advantage. Revisit if Tempest reaches 1.0 with a published BC policy and visible production adoption — at which point this package becomes the natural default for Tempest shops, not for Laravel ones.
How can I help you explore Laravel packages today?