Get started
Add dxn_intl as a git dependency, learn how its pieces fit together, and format a first plural, price and date for a locale.
dxn_intl formats the three things apps localize most: plural forms, numbers and dates. You reach for it when text has to follow the user’s language (“1 file”, “2 files”, “5 datoteka”) and the same code has to print the same text in a native app, on a server and in WebAssembly.
#Install
The crate is not on crates.io. Releases are git tags (vX.Y.Z), so depend on a tag:
cargo add dxn_intl --git https://github.com/dXnSix/dXn.Intl --tag v0.1.0
or in Cargo.toml:
[dependencies]
dxn_intl = { git = "https://github.com/dXnSix/dXn.Intl", tag = "v0.1.1" }
Cargo.lock records the tagged commit. To upgrade, change the tag; see Releases. The crate has no Cargo features and needs Rust 1.97 or newer (the library is edition 2024, and CI checks 1.97).
The locale data is compiled into your binary, so there is nothing to download or ship next to it. There is no docs.rs page because the crate is not published; build the API reference with cargo doc --open.
#A first program
Every formatter is made from a Locale, which parse_locale reads from a language tag, plus the options for what it shows.
use dxn_intl::{
DateTime, DateTimeFormatter, DateTimeOptions, IntlError, Length, NumberFormatter,
NumberOptions, PluralKind, PluralRules, parse_locale,
};
fn main() -> Result<(), IntlError> {
let locale = parse_locale("hr-HR")?;
let plurals = PluralRules::new(&locale, PluralKind::Cardinal)?;
println!("{}", plurals.category(23)); // few
let money = NumberFormatter::new(&locale, NumberOptions::currency("EUR"))?;
println!("{}", money.format(1234.5)?); // 1.234,50 €
let dates = DateTimeFormatter::new(&locale, DateTimeOptions::date(Length::Long))?;
println!("{}", dates.format(&DateTime::date(2026, 10, 27)?)?); // 27. listopada 2026.
Ok(())
}
few
1.234,50 €
27. listopada 2026.
The snippets in these docs use ? and are meant to run inside a function that returns Result<_, IntlError> (or Result<_, Box<dyn std::error::Error>>: IntlError implements std::error::Error). Output shown in assert_eq! was produced by running the snippet.
#How the pieces fit
A formatter is built once for a locale and reused. Number and DateTime are plain values: a Number goes to the plural rules and the number formatter, a DateTime to the date formatter.
#What to reach for
| You need | Use | Page |
|---|---|---|
A locale from a tag, LANG or Accept-Language | parse_locale, negotiate | Locales |
| “1 item” or “2 items” | PluralRules::category | Plurals |
| “1st”, “2nd”, “3rd” | PluralRules with PluralKind::Ordinal | Plurals |
1,234.5, 25%, $1,234.50 | NumberFormatter with NumberOptions | Numbers |
| The number as it will be shown | NumberFormatter::resolve | Numbers |
Oct 27, 2026, 15:45 | DateTimeFormatter with DateTimeOptions | Dates and times |
| The wall time of a Unix timestamp | DateTime::from_unix_millis | Dates and times |
| Left to right or right to left | direction | Locales |
#Things to know early
- Formatters are not
SendorSync.PluralRules,NumberFormatterandDateTimeFormatterhold ICU4X data behindRc, so they stay on the thread that made them.Number,DateTime,LocaleandIntlErrorareSend + Sync. See Platforms. - Floats lose trailing zeros.
1.0_f64becomes the number1. Parse text ("1.0".parse::<Number>()) or format with fixed fraction digits when the digits matter. See Numbers. - No clock, no time zones. You pass the wall time. See Dates and times.
- It is a 0.x library. A minor release can break the API; read the release notes before bumping.
#Next
Locales covers reading tags and choosing the locale to format for. Plurals is the page to read if you only need “1 item, 2 items”.