The Intl namespace provides locale-aware formatting and comparison built into JavaScript. This
reference lists the main constructors and runs them live in your browser so you can see real output.
How it works
Each Intl constructor takes a locale (a BCP 47 tag like en-US, de-DE, ar-EG) and an options
object, then exposes a .format() (or .compare(), .select()) method:
new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR" }).format(1234.5);
// → "1.234,50 €"
new Intl.RelativeTimeFormat("en", { numeric: "auto" }).format(-1, "day");
// → "yesterday"
new Intl.PluralRules("ar-EG").select(3);
// → "few"
Locale data ships with the engine, so the same code adapts grouping separators, decimal marks, currency placement, plural categories and collation order per language automatically.
Constructor quick-reference
| Constructor | What it formats | Key options |
|---|---|---|
Intl.NumberFormat | numbers, currency, percent, units | style, currency, unit, maximumFractionDigits |
Intl.DateTimeFormat | dates and times | dateStyle, timeStyle, timeZone, hour12 |
Intl.RelativeTimeFormat | relative phrases like “3 days ago” | numeric (always/auto), style |
Intl.ListFormat | human-readable lists like “a, b and c” | type (conjunction/disjunction), style |
Intl.PluralRules | plural category selection | type (cardinal/ordinal) |
Intl.Collator | locale-aware string sorting | sensitivity, numeric, caseFirst |
Practical worked examples
Currency formatting across locales
The same amount of money formats very differently depending on locale — the currency symbol placement, the decimal separator, and the grouping character all vary:
const amount = 1234567.89;
new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(amount);
// → "$1,234,567.89"
new Intl.NumberFormat("de-DE", { style: "currency", currency: "EUR" }).format(amount);
// → "1.234.567,89 €"
new Intl.NumberFormat("ja-JP", { style: "currency", currency: "JPY" }).format(amount);
// → "¥1,234,568" (yen has no fractional digits)
For example, if your app serves both US and German users and you hard-code $ or a comma separator, German users will see malformed output. Intl.NumberFormat resolves this with a single API call.
Plural rules in practice
English uses only two plural categories (one and other), but many languages have more. Arabic has six; Polish distinguishes few from many:
const pr = new Intl.PluralRules("pl"); // Polish
pr.select(1); // → "one" → "1 jabłko"
pr.select(2); // → "few" → "2 jabłka"
pr.select(5); // → "many" → "5 jabłek"
pr.select(21); // → "few" → "21 jabłek" — same as 2!
Using PluralRules.select(n) to pick from a message map is the correct approach; hard-coding n === 1 ? singular : plural breaks for any language beyond English.
Natural sort with Collator
Without a Collator, JavaScript’s default Array.sort() uses Unicode code-point order, which puts a10 before a2 because '1' < '2' lexically:
["a10", "a2", "a1"].sort();
// → ["a1", "a10", "a2"] — wrong order
new Intl.Collator("en", { numeric: true }).compare;
["a10", "a2", "a1"].sort(new Intl.Collator("en", { numeric: true }).compare);
// → ["a1", "a2", "a10"] — natural sort
Tips and notes
- Reuse formatters. Constructing an
Intlobject is expensive (it loads locale data); calling.format()is cheap. Build once, format many — especially inside loops or React render functions. - Plural categories are language-specific. Don’t assume
one/other— Arabic has six. UsePluralRules.select(n)to choose the right message form. numeric: "auto"onRelativeTimeFormatproduces idiomatic words (yesterday,next week) instead of always printing"1 day ago".Intl.Collatorwithnumeric: truesortsa2beforea10(natural sort).- Check support with
Intl.supportedValuesOf— for exampleIntl.supportedValuesOf('calendar')lists calendars available in the runtime (gregory,buddhist,hebrew, etc.).
The live demo below uses these exact constructors on your machine, so its output reflects your runtime’s locale support.