You might already be familiar with the Intl.NumberFormat API, as it’s been supported across modern environments for a while now.
- Chrome: supported since version 24
- Firefox: supported since version 29
- Safari: supported since version 10
- Node.js: supported since version 0.12
- Babel: supported
In its most basic form, Intl.NumberFormat lets you create a reusable formatter instance that supports locale-aware number formatting. Just like other Intl.*Format APIs, a formatter instance supports both a format and a formatToParts method:
const formatter = new Intl.NumberFormat('en');
formatter.format(987654.321);
formatter.formatToParts(987654.321);
Note: Although much of the Intl.NumberFormat functionality can be achieved using Number.prototype.toLocaleString, Intl.NumberFormat is often the better choice, since it enables creating a re-usable formatter instance which tends to be more efficient.
Recently, the Intl.NumberFormat API gained some new capabilities.
BigInt support #
In addition to Numbers, Intl.NumberFormat can now also format BigInts:
const formatter = new Intl.NumberFormat('fr');
formatter.format(12345678901234567890n);
formatter.formatToParts(123456n);
Units of measurement #
Intl.NumberFormat currently supports the following so-called simple units:
- angle:
degree - area:
acre, hectare - concentration:
percent - digital:
bit, byte, kilobit, kilobyte, megabit, megabyte, gigabit, gigabyte, terabit, terabyte, petabyte - duration:
millisecond, second, minute, hour, day, week, month, year - length:
millimeter, centimeter, meter, kilometer, inch, foot, yard, mile, mile-scandinavian - mass:
gram, kilogram, ounce, pound, stone - temperature:
celsius, fahrenheit - volume:
liter, milliliter, gallon, fluid-ounce
To format numbers with localized units, use the style and unit options:
const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'kilobyte',
});
formatter.format(1.234);
formatter.format(123.4);
Note that over time, support for more units may be added. Please refer to the spec for the latest up-to-date list.
The above simple units can be combined into arbitrary numerator and denominator pairs to express compound units such as “liters per acre” or “meters per second”:
const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'meter-per-second',
});
formatter.format(299792458);
- Chrome: supported since version 77
- Firefox: no support
- Safari: no support
- Node.js: no support
- Babel: no support
Compact, scientific, and engineering notation #
Compact notation uses locale-specific symbols to represent large numbers. It is a more human-friendly alternative to scientific notation:
{
const formatter = new Intl.NumberFormat('en', {
notation: 'standard',
});
formatter.format(1234.56);
formatter.format(123456);
formatter.format(123456789);
}
{
const formatter = new Intl.NumberFormat('en', {
notation: 'compact',
});
formatter.format(1234.56);
formatter.format(123456);
formatter.format(123456789);
}
Note: By default, compact notation rounds to the nearest integer, but always keeps 2 significant digits. You can set any of {minimum,maximum}FractionDigits or {minimum,maximum}SignificantDigits to override that behavior.
Intl.NumberFormat can also format numbers in scientific notation:
const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'meter-per-second',
notation: 'scientific',
});
formatter.format(299792458);
Engineering notation is supported as well:
const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'meter-per-second',
notation: 'engineering',
});
formatter.format(299792458);
- Chrome: supported since version 77
- Firefox: no support
- Safari: no support
- Node.js: no support
- Babel: no support
Sign display #
In certain situations (such as presenting deltas) it helps to explicitly display the sign, even when the number is positive. The new signDisplay option enables this:
const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'percent',
signDisplay: 'always',
});
formatter.format(-12.34);
formatter.format(12.34);
formatter.format(0);
formatter.format(-0);
To prevent showing the sign when the value is 0, use signDisplay: 'exceptZero':
const formatter = new Intl.NumberFormat('en', {
style: 'unit',
unit: 'percent',
signDisplay: 'exceptZero',
});
formatter.format(-12.34);
formatter.format(12.34);
formatter.format(0);
formatter.format(-0);
For currency, the currencySign option enables the accounting format, which enables a locale-specific format for negative currency amounts; for example, wrapping the amount in parentheses:
const formatter = new Intl.NumberFormat('en', {
style: 'currency',
currency: 'USD',
signDisplay: 'exceptZero',
currencySign: 'accounting',
});
formatter.format(-12.34);
formatter.format(12.34);
formatter.format(0);
formatter.format(-0);
- Chrome: supported since version 77
- Firefox: no support
- Safari: no support
- Node.js: no support
- Babel: no support
More info #
The relevant spec proposal has more information and examples, including guidance on how to feature-detect each individual Intl.NumberFormat feature.