kip
Localize - next generation localisation (ex_cldr v3.0)
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released before the end of March 2026 and is under active development.
The goals and objectives are documented on Github, with the headline objectives being:
- No “backend” architecture, CLDR data will be stored in
:persistent_term. - No compile-time configuration. Runtime all the way.
- Dynamic loading of locales. No more compile-time configuration of supported locales. Downloading and storage/access will be pluggable. This may suit organisations with specific security policies or running Localize on devices with limited connectivity or resources.
- Simplified library packaging.
Localizewill have everything except web-oriented and SQL oriented modules which will go in their own libraries. - A Phoenix-based locale explorer will be available to make it easier and clearer to see what capabilities are possible with Localize (enabled by CLDR). At a later stage the locale explorer will also be hosted on a publicly available web server.
Note this will not be a drop-in replacement. However the public API will be very very similar with the main breaking change being the removal of any backend argument.
Feedback, suggestions all very welcome either here, or on GitHub discussions.
Most Liked
kip
Localize will officially launch next Monday. I’ve got a full week of launch activity planned. And a shiny new blog at elixir-localize.com where I’m committed to spending more time writing about they why and how localisation matters and how localize can make it almost trivial to write localised Elixir applications.
Each day next week there is something launching:
-
Monday is the core
localizelibrary. It compiles faster thanex_cldr, runs faster, uses less memory, has simpler packaging (nearly everything in one package). -
Tuesday is
localize_webthat includesaccept-headerparsing and locale setting, localised routes and some HTML helpers. -
Wednesday is the launch of
localize_person_namesfor formatting names in a localised manner; in formal, informal and other ways. Andthe launch of Calendricalwhich is a consolidated set of calendars now including Gregorian, Julian, Islamic (four variants), Hebrew, Persian, Indian, Buddhist, Composite and user definable. And a few more I probably missed. -
Thursday its time for some new fun things.
localize_phonenumberthat wraps libphonenumber for parsing and formatting phone numbers and localize_address for parsing free-form address data and then formatting its using the OpenCageData templates. -
Friday is the “one more thing” release. It’s called
Intland its an API wrapper forLocalizethat maps very closely to the JavascriptIntlAPI. This should make it easier for developers who are more front-end savvy to adopt localisation in Elixir more easily.
I’ll be posting more long form content at elixir-localize.com as the week progresses.
Eight years into developing ex_cldr and friends I think I can say confidently that localize is better in every way. I hope you’ll try it out, give feedback, open issues and help me make that claim a reality.
kip
Day #1 of Localize launch week and Localize version 0.1.0 is now live on hex. It brings 8 years of experience of building ex_cldr together with a revised and simplified architecture, more capabilities, greater CLDR conformance, faster performance and better developer experience.
My hope is that localize will encourage more developers to build localisation into their apps from the beginning. Whether you plan to deliver an app in a single locale or many, localize just makes it easier. In a single library you get just about everything CLDR can deliver to make localisation and personalisation a pleasurable experience.
It’s a 0.1.0 release but its build on years of experience from ex_cldr. It will look very similar to developers who have used ex_cldr, but there are tons of changes and additions too. So I expect a few rough edges and I would really encourage anyone jumping on board to open issues or start a discussion. I think it won’t take too long to get to a 1.0 release.
I’ll also be blogging about the changes in localize, about localisation in general and about tips and trick on the Elixir Localize blog. There’s an RSS feed too. The blog is built using static_blog that I build for the site - but you might find it useful too.
Design goals met
- No backend architecture, runtime everything.
- Compiles and runs faster than
ex_cldr. A performance report details the performance improvements. - Consistent error returns - always
{:error, exception}with exception messages that can be translated through gettext - An opt-in NIF for several of the formatters - hint, the NIF is not always faster!
- Improved documentation and a series of guides: Number formatting, Date and Time formatting, Units of Measure formatting, Message Formatting and Collation
- Pluggable behaviour for locale loading, storing and accessing with a default that stores data in
:persistent_term - Locales are hosted on Cloudflare R2 and downloaded with mix localize.download_locales or can be configured to be downloaded dynamically at runtime from https://elixir-localize/locales. This is more reliable that using Github as a CDN and faster for many people.
Migrating from ex_cldr
If you’re migrating from ex_cldr, the migration guide will help. The overall API will look very familiar, with the most obvious change being that there is never a backend function argument or option.
And of course you don’t need to juggle multiple libraries, deal with compile-time configuration or generate backend modules.
Functional Highlights
-
Current CLDR v48.2 locale data with lazy runtime loading from ETF files cached in
:persistent_term. No compile-time backend configuration required. -
Number formatting — integers, decimals, percentages, currencies, ranges, and rule-based number formats (RBNF) including Roman numerals and CJK ideographs.
-
Date, time, and datetime formatting using CLDR calendar patterns with
:short,:medium,:long, and:fullstyles, custom skeleton patterns, and interval formatting. -
Unit formatting with plural-aware patterns, SI/binary prefixes, compound units, measurement system conversion, custom unit registration, and
Localize.Unit.Operatorsfor natural arithmetic (km + m). -
List formatting with locale-appropriate conjunctions, disjunctions, and unit list styles. Per-element formatting via
Localize.Chars. -
ICU MessageFormat 2 (MF2) parser and interpreter with custom function registry, offset selection, JSON interchange, and bidirectional text support.
-
Gettext integration —
Localize.Gettext.Interpolationprovides MF2-based interpolation for Gettext backends. -
Localize.Charsprotocol — polymorphic locale-aware formatting with built-in implementations for 14 types andAnyfallback toKernel.to_string/1. -
Currency metadata, ISO 4217 validation, and territory-to-currency mapping.
-
Display names for territories, languages, scripts, calendars, and full locale display names per the CLDR algorithm.
-
Unicode Collation Algorithm (UCA) with CLDR locale-specific tailoring for 97 languages, including digraph expansion and script reordering.
lawik
You absolute legend.
Popular in Announcing
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









