Locale-aware number and currency formatting

Intl.NumberFormat

Baseline widely available
  • Chrome24
  • Edge12
  • Firefox29
  • Safari10

Features it needs

  • IntlWidely available

These libraries hardcode their own thousands separators, currency symbols, and rounding rules, and most ship a single locale by default. Intl.NumberFormat is the same formatting logic the operating system already has: pass a locale and a style, currency, percent, or unit, and it places the symbol, separator, and decimal grouping the way that locale actually expects, with no formatting rules to maintain.

When this applies

Formatting a number as currency, a percentage, or a locale-correct thousands-grouped number for display.

The native approach

new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
}).format(1234.5); // "$1,234.50"

MDN reference

When the dependency is still right

An answer that always says "the platform covers it" is worse than no answer. These are the cases where this one does not hold.

  • You format units or compact notation. style: "unit" and notation: "compact" arrived long after the rest of Intl.NumberFormat, in Chrome 77, Firefox 78 and Safari 14.1, so an older target does not get them.
  • You need safe decimal arithmetic, such as adding money values without floating-point rounding errors. currency.js and accounting.js do that math for you; Intl.NumberFormat only formats a number you already computed correctly.
  • You need to parse a formatted string back into a number. Intl.NumberFormat is format-only; these libraries often provide the reverse direction too.
  • You need a custom format pattern, such as a specific abbreviation style, that the options Intl.NumberFormat exposes cannot express.

Packages this covers