kip

kip

ex_cldr Core Team

Localize reaches 1.0

I’m a bit excited to announce that Localize and friends are now at release 1.0. Even though it’s a 1.0 release, it stands on 8 years of work on the ex_cldr family so it’s solid. I think it’s a better library family in every way: faster, more functional, easier to adopt, simpler packaging, better tested, more conformant to the applicable standards, better documented.

A small set of the supporting libraries (Liveview Inputs, MCP Server) are not yet at 1.0 - they’ll get there when there’s enough feedback to say they are ready.

The main differences from ex_cldr:

  • Compiles much much faster. Localize compiles in less than 3 seconds on my MacBook Pro M1 Max. Thats an order of magnitude faster at least than ex_cldr - and its batteries included rather than a collection of libraries for the core functions.
  • No backend modules. Locale data is loaded on demand at runtime into :persistent_term rather than generated into compile-time backend modules.
  • Much simpler dependency set. The only transitive dependencies are Decimal and Gettext.
  • No compile-time configuration. Locales can be added, loaded, or downloaded at runtime. Data is distributed as Erlang terms, so no JSON decoder is required.
  • Pluggable locale storage. The default loader downloads locale data on demand; custom loaders and stores are supported for air-gapped or resource-constrained environments.
  • Structured errors. Errors return {:error, Exception.t()} with structured exception data, replacing {:error, {module, message}}.

ex_cldr remains supported and will receive maintenance updates until the end of 2027 but no new CLDR functionality is planned.

Localize is a parallel codebase, not a drop-in replacement: most public function signatures are preserved, but removing the backend argument and changing the error format mean migration requires some code changes. I expect your friendly coding agent can make short work of that.

Core libraries

  • localize 1.0.0 — numbers, currencies, dates and times, units, lists, collation, MessageFormat 2, locale display names, and locale resolution.
  • localize_web 1.0.0 — Phoenix and Plug integration: locale negotiation plugs, localized routing, and HTML form helpers.
  • calendrical 1.0.0 — Gregorian, Coptic, Ethiopic, Japanese, Persian, Islamic, Hebrew, and lunisolar calendars, with composite calendars and calendar-aware formatting.
  • intl 1.0.0 — a shim mirroring the JavaScript Intl API, adapted to idiomatic Elixir conventions.
  • ex_money 6.2.0 — a money type with currency-aware math, and locale-aware formatting and parsing. Updated to be based upon Localize and with several key improvements to the exchange rate system contributed by @Wigny.

Features libraries

  • localize_person_names 1.0.0 — locale-aware personal name formatting per the CLDR person name specification: ordering, given/surname conventions, honorifics, and script-specific display.
  • localize_phone_number 1.0.0 — parsing, validation, and formatting of international phone numbers via Google’s libphonenumber.
  • localize_address 1.0.0 — postal address parsing and formatting for 267 countries and territories, with country-specific field ordering. Based on libpostal.
  • unity 1.0.0 — a unit conversion calculator inspired by the Unix units utility, usable as a library, an escript, or a REPL. Evaluates expressions such as 3 meters to feet or 100 celsius to fahrenheit with dimensional analysis and locale-aware output.

Serialization

Ecto types and database support, so locale-aware values are stored structurally rather than flattened to strings.

  • localize_sql 1.0.0 — locale-aware PostgreSQL ICU collation for query ordering and comparison, resolved from a language tag by CLDR language matching, with migration helpers for collations PostgreSQL does not preload. Also provides Ecto types for units of measure, currencies, language tags, territories, scripts, integer and date ranges, and durations.
  • ex_money_sql 2.1.0 — Ecto type and database support for ex_money, storing money as a composite type with database-side aggregates (sum, min, max, avg) and arithmetic operators, built on the same DDL machinery as localize_sql.

Inputs

Phoenix LiveView components for locale-aware form input. These are pre-1.0 and still evolving. This is not an area of strength for me so feedback is very very welcome.

They all share a CSS token set, Gettext catalog, and validation error structure. Server-side parsers accept what the user types in their locale’s conventions — digit shaping, group and decimal separators, calendar systems, date patterns.

  • localize_inputs_core 0.2.0 — shared foundation: validation errors, the Gettext backend for UI strings, and CSS tokens. Pulled in transitively by the components below.
  • localize_number_inputs 0.2.0<.number_input> for decimals and integers with cursor-preserving live formatting, and <.unit_input> with a searchable unit picker covering CLDR units and locale-preferred unit systems.
  • localize_datetime_inputs 0.2.0<.date_input> with a popup calendar accepting CLDR short, medium, long, and full date patterns as well as ISO 8601, plus range selection. Multi-calendar input (Buddhist, Japanese imperial, Islamic, Persian, Hebrew, ROC) via calendrical.
  • ex_money_input 0.3.0<.money_input> with a searchable currency picker, parsing amounts in the locale’s conventions and producing a Money.t().

Tooling

  • localize_mcp 0.2.0 — a Model Context Protocol server exposing the Localize API to AI agents. Intended for local use, communicating over stdin. Which means it probably doesn’t work on Windows (definitely not tested on Windows).

Playgrounds

Two live instances for trying the libraries without installing anything. Note these are running on the free tier small shared hosts on fly.io so performance and scale are limited. They are both on Localize GitHub so feel free to spin them up on your own system too.

Requirements

Elixir 1.17 or later, Erlang/OTP 26 or later.

Documentation is on hexdocs and the organization is at github.com/elixir-localize. Comments, bugs, suggestions and abuse? Open an issue and I’ll get right on it.

Most Liked

AstonJ

AstonJ

Congrats Kip :048: and thanks for all the work you do on your awesome libraries :049:

Where Next?

Popular in News & Updates Top

fhunleth
I wanted to let everyone know that the Erlang Ecosystem Foundation (EEF) has a working group dedicated to embedded systems and IoT. We ha...
New
fhunleth
We recently released Nerves 1.6 and corresponding updates to the Nerves new project generator, nerves_bootstrap and our official systems....
New
jjcarstens
Do you like Hacktoberfest? Also enjoy working with Nerves and want to contribute? Fantastic! :tada: :beers: Here are some potential sta...
New
DominikWolek
Hey everyone! The Membrane Framework has a new website! It contains tutorials, blog posts, and other resources you’ll find handy while u...
New
fhunleth
The Nerves core team is proud to announce the Nerves v1.8.0 release. Nerves provides the core tooling for creating self-contained, BEAM-...
New
hugobarauna
Livebook v0.7 is out! This is a major release coming with significant features in the following areas: secret management visual represe...
New
bartblast
Hologram v0.6.0 is here, bringing production-ready features to the full-stack Elixir web framework! This release focuses on enhanced secu...
New

Other popular topics Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 55125 245
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

We're in Beta

About us Mission Statement