Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Intl Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Position: a tactical convenience dependency, not a strategic platform bet. Adopt only behind an interface we own, and vendor it.

Architecture fit

  • Thin, stateless adapter over PHP's 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.
  • Idiomatic Laravel packaging (auto-discovered provider, facade, publishable config). It holds no opinion about our domain model, so it cannot leak a bad architecture into business logic.
  • Scope is narrow and should be stated plainly to stakeholders: formatting only. It does not provide translations (Laravel's own lang system), currency conversion, timezone persistence strategy, or ICU version management.
  • Documentation mismatch: the PM-facing assessment in this dossier describes a country/currency reference-data and validation package, not a formatting wrapper. Either the pack is mismatched or the maintainer's materials are unreliable. Either way it is a diligence red flag to resolve before commitment — it undermines the artifact set, not just this package.

Integration feasibility

  • High. 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.
  • Whole surface is reviewable by one engineer in an afternoon. Spike-and-prove: ~1 engineer-day. Full standardization across a mid-size app (interface, locale middleware, CI image updates, stabilized test fixtures, surface-by-surface migration): 1–2 sprints, dominated by the migration of call sites, not by the package.

Technical risk

  • Concentration risk: single maintainer, 3 stars, 0 dependents. Effectively zero third-party production validation and no observable security response process. Treat as unvetted.
  • Supply chain: with this adoption level the community has not vetted it. Mitigation is cheap — vendor/fork the code — but must be an explicit decision, not an accident.
  • Release hygiene: 2.1.0 ships with only a compare link and no prose changelog. A minor semver bump can still shift formatter defaults or add required config keys; the diff must be read, not assumed benign.
  • Determinism: output depends on host ICU version. Same code, same input, different strings across dev/CI/prod (Windows PHP builds lag notably). This is a test-infrastructure tax that lands on whoever owns the dependency.
  • Silent fallback: unknown locale or currency codes produce plausible-looking wrong output instead of throwing. On pricing and checkout surfaces that is a revenue-adjacent correctness bug that QA will not catch.
  • Naming collision: Intl is a heavily used facade alias; in a mature app this risks ambiguous or wrong class resolution.
  • Feature gap risk: the wrapper is thin, so any formatter style we need and it does not expose (units, relative time, ordinals, skeleton patterns) still gets written against raw ICU — meaning we may end up maintaining two idioms.

Key questions

  1. Actual LOC and test coverage? If it is a few hundred lines with thin tests, the build-vs-buy math flips toward an in-house helper of comparable size.
  2. Which intl capabilities are genuinely wrapped versus the ones we actually need? The gap sizes the residual work.
  3. Does it read app()->getLocale() or its own intl.locale config key? Determines whether middleware must set both — otherwise silent-fallback trap.
  4. What ext-intl/ICU version runs in every environment, and do we control that image?
  5. Who owns this when the maintainer stops, and what is our exit cost?
  6. Is the dossier documentation for this package or a different one? Resolve before the decision meeting.

Integration Approach

Stack fit

  • Suitable for Laravel 10/11/12-era apps on PHP 8.x with ext-intl enabled. The composer PHP constraint is not stated here — verify against our minimum supported version before assuming.
  • Non-invasive: it touches neither queues, caching, auth, nor Eloquent. It can be adopted incrementally, one surface at a time, with no coordination across teams.
  • Server-render only. Blade, API Resources, and Inertia/Livewire payloads all work; client-side formatting does not. If we localize in the browser we need an ICU-capable JS formatter (Intl.NumberFormat) or pre-formatted strings shipped from the API — decide which before rollout, not after.

Migration path

  • Day-one rule: never call the facade at call sites. Define an application-owned 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.
  • Phase 1 — install, verify ext-intl in every image (HTTP, CLI, queue, scheduler), publish config, prove output parity against current screens on 3–4 real surfaces.
  • Phase 2 — locale negotiation middleware: user preference → Accept-Language → app default; set both app()->setLocale() and the package config key, since resolution order is unconfirmed.
  • Phase 3 — migrate surfaces in business-value order: money first, then dates, then percentages, then lists/plurals.

Compatibility

  • BCP-47 tags only (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.
  • Octane: 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.
  • Import the facade class explicitly rather than relying on the Intl alias if any other package claims it.

Sequencing

  1. Feasibility spike plus a read of source LOC and test coverage (~1 day).
  2. Decision gate: adopt-behind-interface vs. write ~200 LOC internally vs. thin raw-intl helper. All three are viable; the differentiator is who owns the upgrade path.
  3. If approved: interface and binding, CI/base-image ext-intl, locale middleware, test locale pinning.
  4. Feature-flagged surface-by-surface migration.
  5. Vendor or patch the dependency and publish an upgrade runbook.

Operational Impact

Maintenance

  • Low run-rate, but not zero. Churn lives in PHP/Laravel major upgrades and ICU defaults, not in the wrapper. Budget roughly half a day per minor release to read the diff (compare links only, no prose changelog) and re-run the formatting suite.
  • Config surface is tiny — default locale, default currency, fallbacks — so it is cheap to document and cheap to reason about. That smallness is also the argument for in-lining it.

Support

  • No vendor, no SLA, no advisory feed. The support model is "we own it the moment we require it." Acceptable only because the code is small and vendorable; unacceptable if it sits unvendored on the critical path to a PHP upgrade.
  • Internal load concentrates in one or two engineers. Without a written runbook this becomes tribal knowledge and a single point of failure on the team, mirroring the package's own risk profile.

Scaling

  • Horizontal scaling is unaffected: no shared state, no cache dependency, no network calls.
  • Formatter construction is the real cost. 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.
  • Cardinality is bounded by locale count, so caching benefit is stable and predictable.

Failure modes (ranked by business impact)

  1. Wrong-looking money from silent locale/currency fallback — highest severity, hits checkout and pricing. Mitigate with whitelist validation on user-supplied currency and locale codes, plus assertions that the rendered currency matches expectation.
  2. Environment drift producing different strings in prod vs. CI — breaks snapshot tests, can ship inconsistent customer-facing output. Mitigate with a pinned base image and structural assertions (symbol present, digits grouped) rather than exact strings.
  3. Missing ext-intl in a new image or job — loud, hard failure, easy to diagnose if a boot-time capability check fails fast.
  4. Facade alias collision — intermittent and confusing; fixed by explicit class imports.
  5. Laravel/PHP upgrade breakage — moderate; fully contained by the interface.
  6. Bulk-formatting performance regression — degraded reports, not an outage.
  7. Octane serving stale container state post-upgrade — transient, but a reliable time sink as a false alarm.

Ramp-up

  • Roughly half a day for a competent Laravel engineer to be productive: install, verify the extension, publish config, one Blade example, one API Resource example, and the gotchas list. The gotchas — BCP-47 vs POSIX tags, formats-not-converts, silent fallback, config caching — matter more than the API, which is a handful of methods.
  • The genuine onboarding cost is not this package but the surrounding discipline: locale negotiation, test locale pinning, image/ICU parity, persisted-locale normalization. Budget that explicitly. It exists with or without this dependency, and it is where the schedule risk actually lives.
  • Net TPM position: low cost to try, low cost to exit, low strategic value. Adopt behind an owned interface and a vendored copy; do not let it become the reason we cannot upgrade PHP. Resolve the documentation mismatch in the dossier before the decision meeting.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox