Abiodun Solomon I’m a software developer that is curious about modern technologies. I love contributing to the growth of knowledge for the betterment of humanity.

Rust internationalization, localization, and translation

4 min read 1293

Rust Internationalization Localization Translation

Over the past few years, Rust has gained in popularity as businesses increasingly look to promote their products and services on the world stage. According to Stack Overflow’s “2020 Developer Survey,” a whopping 86 percent of respondents who have used Rust plan to use it again, making Rust the most-loved programming language of 2020.

Internationalization (i18n) is a key consideration for companies planning to roll out their apps and software to a global audience. In this Rust internationalization tutorial, we’ll examine eight of the most popular Rust i18n crates and evaluate each for production-readiness and stability.

In this guide, we’ll look at eight of the most popular Rust internationalization crates and evaluate each for production-readiness and stability.

We’ll cover the following:

What is internationalization?

Internationalization is the process of developing content and applications that adapt to suit users from any region, language, or culture. In other words, internationalization is the process of making an app globally accessible by providing content that is appropriate for each region.

Internationalization is sometimes abbreviated as i18n because there are 18 letters between the initial “I” and the closing “N.”

Rust internationalization: Key terms

Before we proceed with our Rust internationalization tutorial, let’s define some key terms:

  • Internationalization (i18n) means designing computer programs or web apps that can be adapted to various languages and regions
  • Localization is the process of adapting internationalized web apps by adding locale-specific components for a given region or language. It uses the flexibility and capability provided by internationalization
  • Translation is the process of replacing strings from one language to another

Why use internationalization with Rust?

In the era of static websites, localization is done by copying the whole site structure in multiple locales. Changes are made to each structure directly by the translator because each page is translated separately. Internationalization tools streamline this tedious, time-consuming, error-prone process.

Among Rust’s most enriching features is the language locale, which makes it easy to translate an app to various languages.

Common localization systems

In general, there are three common localization systems:

We made a custom demo for .
No really. Click here to check it out.

  1. gettext
  2. Project Fluent
  3. ICU Message Format

Let’s examine each in more detail.


gettext is a localization system that separates translation files from the programming language and provides support for plural forms strings of any number. Sun Microsystems implemented the first version of gettext in 1993. In 1995, the GNU project released a free software implementation. Since then, gettext has been used by many programming languages, including Rust.

Here’s how to use gettext:

Gettext Localization System Use Instruction Chart

  1. Use gettext(), _() to accept translation strings in the source code
  2. Generate the .pot (portable object template) file using xgettext or other software to help keep track of translated string and the line on which gettext()/_() was used
  3. Generate .po (portable object) file for each language/locale using software such as PoEdit, Emacs, etc. to add appropriate translations to each source text
  4. Compile to .mo (machine object) file when translation is complete for easy distribution

Machine Object File Compilation

Project Fluent

Fluent is a translation system that focuses on producing natural-sounding translations by providing support for grammar expressions such as gender, plurals, conjugations, etc.

Fluent uses an expression from a file format called FTL (short for Fluent Translation List) to process translations. An FTL file represents a language that contains functions, attributes, variables, selectors, terms, etc. Each locale must have its own FTL file created in different locale directories with its own translations following the same syntax pattern.

# en-US
# Simple variable
text-layout = Fast track your productivity by testing out your code on the spot
# Attributes
form-layout = 
  .button = Save and Execute
  .font-seletion = Font Size

# Simple variable
text-layout = Acelere su productividad probando su código en el lugar
# Attributes
form-layout = 
  .button = Guardar y ejecutar
  .font-seletion = Tamaño de fuente

ICU Message Format

International Components for Unicode (ICU) is a standard encoding scheme that provides full-featured unicode services such as date manipulations, resource bundles for accessing localized information, character set conversion, etc. It provides conventional translation about the data expectation in the source message.

ICU depends on various data formats including XML, JSON, YAML, and properties files for message formatting and uses a message syntax that contains various standards including variables, select, pluralization, date, time, etc.

   "text": "Just write text without any variables"

# Representing numbers { variableName, number, style }. 
  "amount" : "Your total is {total, number, ::currency/EUR}"

   "created_at": "The todo was posted on {publishedAt, date, medium} at {publishedAt, time, short}"

# Spanish version
  "created_at": "La tarea fue publicada en {publishedAt, date, medium} a {publishedAt, time, short}"

Comparing internationalization tools for Rust

Let’s zoom in on eight of the most popular Rust internationalization APIs and compare their production-readiness, stability, and the overall developer experience.

  1. Fluent
  2. Fluent LangNeg
  3. gettext
  4. gettext-rs
  5. r_i18n
  6. JSON Get Text
  7. i18n_codegen
  8. Rocket I18N


Fluent is designed to improve the process of translation on platforms. It enables syntax operations, parsers, and core localization structs to use a low-level structure for formatting and storing messages in a single locale.

Fluent also provides an API that supports user-friendly helpers, framework binding, error fall-backing, language negotiation between user requested languages, resources, and input/output for processing selected resources.

  • Production-ready: Yes
  • Stable: Yes

Fluent LangNeg

Fluent LangNeg is based on fluent-langneg, a JavaScript library implementation associated with Project Fluent, which was formerly called fluent-locale. It uses unic-langid and unic-locale to retrieve and operate on locale identifiers. Fluent LangNeg also provides option for negotiating between different locales lists.

  • Production-ready: Yes
  • Stable: Yes


Rust gettext is based on GNU gettext, which is supported and modeled for vast number of languages such as php-gettext, gettext-go, js-gettext, and more. It stores the translated data in a .mo file, which is separated from the language files because it does not enforce directory structure for storage.

At the time of writing, this crate is still in the development stage.

  • Production-ready: No
  • Stable: Yes


gettext-rs uses the GNU Gettext FFI binding for Rust to build script execution based on environment variables. It currently has support for only Linux and Windows.

  • Production-ready: No
  • Stable: Yes


r_i18n is a tool that translates string by accessing a string’s related key-value pair from the JSON file created for each languages in a configuration directory.

  • Production-ready: Yes
  • Stable: Yes

JSON Get Text

json-gettext extracts strings from a JSON locale file to get a user’s catalog. The localization works by creating different JSON locales in a directory that has to be accessed by Rust.

json-gettext provides support for Rocket web framework and unic languid.

  • Production-ready: Yes
  • Stable: Yes


i18ncodegen is closely related to ri18n, which generates new code snippets based on the key-value pair specified in each JSON locale. The key in the JSON file becomes a method that can be accessed via implementation. This procedures is designed to help you avoid common bugs such as missing interpolations, i18n keys typos, etc.

  • Production-ready: Yes
  • Stable: Yes

Rocket I18N

rocket_i18n8is designed to translate locale based on user request on rocket or actix web frameworks via i18n macro. Rocket I18N was built to support only compiled templates, such as the rcute and Askama template engines.

  • Production-ready: Yes
  • Stable: Yes


With these internationalization APIs, you can extend your business to other regional demographics, which could help boost overall user engagement with your Rust app.

The best internationalization tool to serve your needs will depend on your particular use case and what you hope to accomplish with your app. Some of the APIs mentioned above are more production-ready and stable than others, so make sure you do your homework before committing to a solution.

LogRocket: Full visibility into production Rust apps

Debugging Rust applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking performance of your Rust apps, automatically surfacing errors, and tracking slow network requests and load time, try LogRocket.

LogRocket is like a DVR for web apps, recording literally everything that happens on your Rust app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.

Modernize how you debug your Rust apps — .

Abiodun Solomon I’m a software developer that is curious about modern technologies. I love contributing to the growth of knowledge for the betterment of humanity.

One Reply to “Rust internationalization, localization, and translation”

  1. Nice post! I’m glad this topic is getting some more publicity. Just a little shout out for some tools I’ve been developing to support localization in Rust https://github.com/kellpossible/cargo-i18n It is aimed both at libraries, providing an API for libraries to expose their localization capabilities, and end users localizing their binary projects and wanting to embed the localizations in the binary, and having the correct language detected and selected at runtime. There is support for fluent, and gettext at the moment. There is also a super handy macro to use with fluent projects to have your message keys checked at compile time. I plan to add support for more validations and any other localization system that has interest.

Leave a Reply