Next-generation internationalization and localization for the Elixir language, built on Unicode CLDR.
This organization is the home of the successor to the ex_cldr family of libraries. Where ex_cldr comprised 28 separate packages with compile-time backend generation, the elixir-localize libraries consolidate that functionality into a smaller set of cohesive packages with runtime locale loading, no compile-time configuration, and faster build times.
The core localization library. Provides locale-aware formatting and operations for numbers, currencies, dates and times, units, lists, message formats, locale display names, and more. Consolidates the functionality of ex_cldr, ex_cldr_numbers, ex_cldr_currencies, ex_cldr_dates_times, ex_cldr_units, ex_cldr_lists, ex_cldr_locale_display, and ex_cldr_messages into a single package.
A unified calendar library supporting the Gregorian, Coptic, Ethiopic, Japanese, Persian, and lunisolar calendar systems, together with composite calendars and calendar-aware formatting. Replaces the separate ex_cldr_calendar_* packages.
Phoenix and Plug integration for localize. Provides locale negotiation plugs, HTML helpers, and localized routing. Consolidates ex_cldr_plugs, ex_cldr_html, and ex_cldr_routes, and will host a LiveView-based interactive locale explorer.
A thin shim over localize that mirrors the JavaScript Intl API — Intl.NumberFormat, Intl.DateTimeFormat, Intl.ListFormat, Intl.DisplayNames, Intl.RelativeTimeFormat, Intl.PluralRules, Intl.Collator, Intl.DurationFormat, and Intl.Segmenter. Module names, function purposes, and option names mirror their JS counterparts, adapted to idiomatic Elixir conventions (snake_case options, {:ok, result} / {:error, reason} tuples). Useful for developers moving between Elixir and JavaScript, or for porting existing code that targets Intl.
Locale-aware formatting of personal names following the CLDR person name specification. Handles ordering, given/surname conventions, honorifics, and script-specific display rules across locales.
Parsing, validation, and formatting of international phone numbers using Google's libphonenumber metadata, integrated with localize for locale-aware display.
Locale-aware postal address parsing, validation, and formatting based on the CLDR and Google address metadata, including country-specific field ordering and required components.
Embeds translations directly into Ecto schemas, storing all of a record's translations in a single JSONB column rather than a separate translations table — avoiding the extra tables and JOINs of the traditional approach. Localize.Translate provides the use macro for translatable schemas and runtime translate/2,3 functions with CLDR parent-chain fallback, while the optional Localize.Translate.QueryBuilder adds Ecto.Query macros for filtering and selecting on translated values in SQL. Continues the work of trans and ex_cldr_trans within the localize ecosystem.
A family of Phoenix LiveView components for locale-aware form inputs. The components share a common CSS token set, Gettext catalog, and structured validation errors so they look and behave consistently when used together. Server-side parsers accept whatever the user types in their locale's conventions (digit shaping, group/decimal separators, calendar systems, date patterns) and the JS hooks degrade gracefully when their optional peer dependencies are not loaded.
Shared foundation for the input component family. Hosts the Localize.Inputs.ValidationError exception, the Localize.Inputs.Gettext backend with shared UI strings (button labels, ARIA labels), and the --li-* CSS variable tokens for light and dark mode. You usually don't depend on this directly — it is pulled in transitively by the sibling component packages.
Locale-aware number-like form inputs for Phoenix LiveView. Provides <.number_input> for decimal and integer values with cursor-preserving live formatting via AutoNumeric, and <.unit_input> paired with a searchable <.unit_picker> covering CLDR units of measure (length, mass, volume, …) with locale-specific preferred unit systems (metric, US, UK) and localized unit names.
Locale-aware date form inputs for Phoenix LiveView. Provides <.date_input> with a popup calendar grid that accepts the locale's CLDR short, medium, long, and full date patterns as well as ISO-8601, plus <.date_range_input> and <.date_range_picker> for two-date selection with min/max, span, and weekday restrictions. Multi-calendar support (Gregorian, Buddhist, Japanese imperial, Islamic, Persian, Hebrew, ROC, …) is provided through calendrical, so users can type dates in their locale's calendar and the server parses them correctly.
A standalone deployment wrapper that demonstrates the input components across every CLDR locale, with tabs for input behaviour, server-side parsing, formatting, and locale data. The live instance runs at localize-inputs-playground.fly.dev. The package can also be embedded into a host Phoenix application's dev router as a forward route for local experimentation.
localize is a plain BEAM library, so any language that compiles to the BEAM can call it directly — there is no foreign runtime to bridge and no FFI overhead. These packages exist purely for ergonomics: each shapes arguments and results the way its host language expects, so callers write idiomatic code instead of reaching across into Elixir modules by hand.
Locale-aware formatting for the Lua (Luerl) VM. Installs a small localize table into a Luerl VM so Lua scripts — such as templates rendered by a CMS — can format numbers, currencies, dates, times, units, lists, and MessageFormat 2 messages. The exposed surface is a curated allowlist of pure formatting functions with no filesystem or network access, making it safe to hand to untrusted template authors.
Idiomatic LFE bindings. The localize module speaks LFE's own conventions — charlists, atoms, Erlang date/time tuples, and lisp-case option keys — so lispers write (localize:currency 1234.56 "EUR") and the library handles the charlist/binary/atom coercion Localize expects.
Idiomatic Erlang bindings, exposed as small per-concern modules (localize_number, localize_currency, localize_date, localize_collation, …). Binaries in and out, maps for options, Erlang date/time tuples, and {ok, Binary} | {error, {Tag, Message}} returns that translate Localize's Elixir exceptions into ordinary Erlang error terms.
Type-safe Gleam bindings. Options are a typed Options record built with record-update syntax, and every fallible call returns a Result(String, LocalizeError) whose error is a union you can pattern-match (InvalidLocale, InvalidDate, UnknownCurrency, …). Localize's {ok, _}/{error, _} maps straight onto Gleam's Result.
-
No backend modules. Locale data is loaded at runtime into
:persistent_termfor fast access, removing the compile-time backend generation used byex_cldr. -
No compile-time configuration. Locales can be added, loaded, or downloaded dynamically at runtime. Locale data is distributed in Erlang term format, so no JSON decoder dependency is required.
-
Pluggable locale storage and loading. The default downloads locale data on demand, but custom loaders and stores are supported for resource-constrained devices, air-gapped environments, or organizations with bespoke data requirements.
-
Idiomatic errors. Errors are returned as
{:error, Exception.t()}with structured exception data, replacing the{:error, {module, message}}tuples used inex_cldr. -
Simpler packaging. A small number of focused libraries rather than 28 separately versioned packages.
The ex_cldr libraries remain supported and will continue to receive maintenance updates. elixir-localize is a parallel next-generation codebase rather than a drop-in replacement — most public function signatures are preserved, but the removal of the backend argument and the change in error format mean that migration requires code changes. Migration guides will accompany each library's first stable release.
- Elixir 1.17 or later
- Erlang/OTP 26 or later
The libraries are under active development and have been released to hex.pm.