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

Intl Extra Laravel Package

twig/intl-extra

Twig Intl Extension adds locale-aware filters to Twig: look up country, currency, language, locale, and timezone names, get country timezones, and format currencies, numbers, dates, times, and lists using PHP's Intl extension.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit twig/intl-extra is an official Twig extra, not a Laravel package. It supplies a single IntlExtension that registers ICU-backed filters (format_date, format_time, format_datetime, format_number, format_currency, plus name lookups such as country_name, currency_name, currency_symbol, language_name, locale_name, timezone_name, and country_timezones). Architectural fit is therefore conditional on one fact: is Twig in the rendering path?

  • Strong fit where Twig already renders output: transaction emails, PDF/invoice generation, report exports, admin or back-office templates, or Symfony-shared components inside a Laravel estate. In those slices the extension removes controller-side plumbing and gives template authors locale-aware formatting and ISO-code-to-display-name lookups without new PHP services.
  • Weak fit for a conventional Laravel app. Blade is the default view layer and does not consume Twig extensions. Laravel 10+ already ships Illuminate\Support\Number (currency, format, percentage, file sizes) and Carbon's localized date formatting, and __() / trans_choice() cover translation and pluralization. The marginal capability this package adds over native Laravel is mostly the ISO name-lookup filters and ICU pattern control inside Twig templates.
  • Inverted fit if adopting it means introducing Twig into a Blade codebase. That is a view-layer migration disguised as a composer dependency: routing, view composers, shared data, auth/session access, and autoescaping semantics all have to be reconciled through a community Twig bridge.

Verdict for a TPM: treat this as a capability for an existing Twig surface, not as an i18n strategy for Laravel. If the organization is Blade-only, the correct decision is usually "no" to the package and "yes" to a thin IntlFormatter service plus Blade directives using NumberFormatter / IntlDateFormatter directly.

Integration feasibility Two viable paths, with materially different costs:

  1. Twig-enabled slice (recommended if Twig exists). composer require twig/twig twig/intl-extra:^3.30, instantiate or obtain the Twig environment, addExtension(new \Twig\Extra\Intl\IntlExtension()), bind the locale from app()->getLocale() via a Twig global or function, and configure a filesystem template cache. Effort is roughly 2–5 developer-days for one surface plus locale tests. Main dependency risk is the Twig-to-Laravel bridge layer, which is community-maintained and tends to lag Laravel majors; that bridge, not intl-extra, is the real integration liability.
  2. Blade-only (not recommended to adopt the package). Reimplementing these filters as Blade directives is feasible but duplicates vendor logic and creates a permanent fork to maintain. Budget 1–2 sprints and accept ongoing drift; cheaper to use native intl helpers.

Non-negotiable prerequisites: PHP 8.1+, the intl extension enabled (not guaranteed in slim php:*-cli images unless explicitly installed), Twig 3.x version alignment, and a compiled-template cache. New in this review: pin ^3.30, which carries both the CVE-2026-46629 fix (from v3.26.0) and the v3.30.0 formatter-prototype correctness fix.

Technical risk

  • Locale drift. Twig filters accept an explicit locale argument, while Laravel holds locale in App::setLocale(). Without a single source of truth, templates will format with inconsistent locales across requests and jobs.
  • Date-pattern derivation correctness (updated). v3.30.0 fixes IntlExtension inheriting values that ICU derived from a date formatter prototype, and now compares the prototype pattern with the derived pattern once per pattern. Practically: where templates pass custom ICU date patterns rather than named styles (short/medium/long), earlier 3.x releases could produce subtly wrong output for locales whose derived pattern diverges from the prototype. This is a correctness bug, not a security one, and it argues for upgrading the floor to ^3.30 rather than staying on ^3.26. It also strengthens the case for per-pattern snapshot tests — the regression class is silent wrong output, not an exception.
  • ICU data drift. intl behavior depends on the ICU library bundled with the PHP build. Dev laptop, CI image, and production container can produce different output (notably for currency spacing, timezone names, and date patterns). Pin the PHP base image and test the locale matrix in CI.
  • Security/patch posture. v3.26.0 fixed CVE-2026-46629 (unbounded memoization of IntlDateFormatter / NumberFormatter). This matters specifically for long-lived workers — Laravel Octane, Horizon, queue workers rendering templates — where unbounded formatter caches become memory growth. Constrain to ^3.30 (includes v3.26.0) and run composer audit in CI.
  • Formatter exceptions. ICU pattern errors and unsupported locales raise exceptions rather than degrading gracefully; an invalid pattern in a template becomes a 500. Need an explicit fallback strategy.
  • Performance in loops. Per-row formatting of dates/currencies in large tables is CPU-visible. Hot paths should be pre-formatted in PHP and passed to the template. Note that v3.30.0 adds a per-pattern comparison in the prototype path — negligible, but it does mean pattern keys should be low-cardinality, consistent with the existing caching guidance.
  • Low visible downstream adoption (0 Packagist dependents) is not a quality signal against the package — it is maintained under the Twig organization — but it does mean fewer battle-tested Laravel integration examples to copy.

Key questions

  1. Which templates today are rendered by Twig, and what percentage of user-facing output does that represent?
  2. If Twig is not present, what is the business case for introducing it versus using Number/Carbon/intl in Blade?
  3. Who owns the Twig bridge and its upgrade cadence when Laravel ships a major?
  4. What is the authoritative locale and fallback chain, and how will it be injected into Twig?
  5. Do any templates pass custom ICU date patterns to format_date/format_datetime, and if so, are their outputs snapshot-tested across the locale matrix? (Directly scopes exposure to the v3.30.0 prototype-derivation fix.)
  6. Which environments use long-lived PHP processes where formatter memoization and memory ceilings matter?
  7. What is the standard PHP base image, and is intl + ICU version pinned across dev/CI/prod?

Integration Approach

Stack fit Target only Twig-rendered surfaces: transactional email, PDF/invoice rendering, exported reports, and any admin templates already on Twig. Do not target Blade views, Livewire components, or Inertia/Vue/React front ends — the extension cannot reach them. If the estate already runs a Twig bridge for Symfony interoperability, this is a near-zero-friction addition.

Migration path

  1. Decision gate. Inventory Twig usage. If zero, stop; document the native-Laravel alternative and close the evaluation.
  2. Pin prerequisites. Confirm php -m | grep intl, PHP 8.1+, Twig 3.x, and a compiled template cache in every environment.
  3. Install and register. composer require twig/intl-extra:^3.30, then register IntlExtension on the Twig environment in a service provider. Do not floor at ^3.26 — that version line predates the v3.30.0 prototype-derivation fix.
  4. Bind locale centrally. Expose app()->getLocale() and app()->getFallbackLocale() to templates; forbid hardcoded locale strings in templates by convention and lint rule.
  5. Pilot one surface. Convert a single email or PDF template, covering format_currency, format_datetime, and one name lookup. Include at least one custom-pattern date if the surface uses one, so the v3.30.0 fix is exercised and locked in by test.
  6. Harden. Add a locale matrix test (e.g., en_US, de_DE, fr_FR, ja_JP, plus one unsupported locale) asserting exact output snapshots. Where custom patterns exist, snapshot the derived output per pattern, not just the input pattern string.

Compatibility PHP 8.1+, Twig 3.x, ext-intl, Laravel 10/11/12, twig/intl-extra ^3.30. Verify the chosen Twig bridge against the current Laravel major before committing; if the bridge is unmaintained, that is a stop condition. Confirm the Twig cache driver is configured (filesystem or Redis), since uncached compilation in production is a latency and disk risk.

Sequencing

  • Phase 0 — Discovery (1 week): Twig inventory, locale source-of-truth decision, bridge maintenance check, custom-ICU-pattern inventory.
  • Phase 1 — Foundation (1 week): dependency (^3.30), extension registration, locale injection, cache config, ICU/PHP image pinning.
  • Phase 2 — Pilot (1–2 weeks): one template surface, snapshot tests including a custom pattern, error/fallback behavior defined.
  • Phase 3 — Expand (2–4 weeks): remaining Twig surfaces converted; convention documented ("Twig for email/PDF, Blade for web views").
  • Phase 4 — Operate: upgrade runbook, CVE patch SLA, locale regression suite in CI.
  • Rollback: the extension is additive; removing it reverts only converted templates. Keep the pilot scoped so rollback is a single-PR revert.

Operational Impact

Maintenance Vendor maintenance is low and credible: MIT-licensed, maintained under the Twig organization, with a steady patch cadence (v3.29.0 → v3.30.0 is a routine minor with one bug fix and one micro-optimization, no breaking changes, no deprecations). The maintenance burden you actually own is the integration layer — the Twig bridge, locale synchronization, and the locale regression suite. Expect to touch this at every Laravel major and every Twig major. Pin ^3.30 or later, run composer audit and Dependabot/Renovate in CI, and define a patch SLA (e.g., 7 days for security releases, next scheduled release for correctness fixes such as the prototype-derivation bug in v3.30.0). Because v3.30.0 changes only internal formatter-prototype handling, it is a low-risk in-place upgrade — schedule it as a normal dependency bump, but re-run locale snapshot tests since output for custom patterns may legitimately change.

Support There is no Laravel-specific documentation and little Laravel-specific community answer surface; support relies on Twig and PHP intl docs. A Blade-only team will need ramp-up on Twig syntax ({% %} vs @), escaping semantics, and error types (Twig\Error\LoaderError, SyntaxError, RuntimeError). Publish an internal one-pager mapping each supported filter to its intended use and the approved locale argument convention so on-call engineers can diagnose template failures without Twig expertise. Add a note that silent date-format differences after an intl-extra upgrade are an expected symptom class, resolved by checking the changelog and re-baselining snapshots.

Scaling The extension is stateless and adds no concurrency concerns; compiled-template caching keeps render overhead low. Two scaling caveats: (1) high-cardinality locale/pattern inputs to IntlDateFormatter/NumberFormatter can grow internal caches — keep patterns static and locale sets small, and validate memory ceilings on Octane/Horizon workers; the v3.30.0 per-pattern comparison reinforces keeping the pattern set constant and finite; (2) formatting inside large loops is CPU-bound, so pre-format in PHP for list/report rendering. ICU data adds tens of MB to container images — account for that in image size budgets.

Failure modes

Failure Impact Mitigation
ext-intl absent in an image All filters fatal; emails/PDFs break Assert extension in CI and container healthcheck
Locale unset or unsupported Silent wrong output or exception Central locale injection; explicit fallback locale; matrix tests
ICU version differs dev vs prod Inconsistent currency/date output Pin PHP base image; snapshot tests in CI
Pre-3.30 release retained with custom date patterns Subtly wrong dates from inherited prototype-derived values, no exception raised Floor at ^3.30; snapshot custom-pattern output per locale
Vulnerable intl-extra retained Memory growth in long-lived workers (CVE-2026-46629) Constrain ^3.30, automated dependency updates
Invalid ICU pattern in template 500 on render Validate patterns in code review; catch and fall back
Twig major / bridge drift after Laravel upgrade Template rendering failure at deploy Pin versions; include Twig render smoke test in release pipeline
Cache misconfiguration Slow renders, disk pressure Configure and monitor Twig cache; clear on deploy

Ramp-up A developer already fluent in Twig reaches productivity in 1–2 days. A Blade-only team introducing Twig spends 1–2 sprints on the bridge, conventions, and locale testing before the first production template — which is precisely why the recommendation is to adopt this package only where Twig already exists, and otherwise to invest the equivalent effort in a small native intl formatting service that the whole team already knows how to operate.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin