Formatting Numbers in JavaScript with Intl.NumberFormat
Tags: javascript, intlnumberformat, number, languages
Published: 2020-01-13 20:34:45

---
title: Formatting Numbers in JavaScript with Intl.NumberFormat
published: true
description: learn how to use the power of Intl.NumberFormat to help you format numbers in JavaScript based on human language.
tags: JavaScript, Intl.NumberFormat, number, languages
cover_image:
---

<center><img src="https://media.giphy.com/media/1yMcQTLvuB1Evg4buK/source.gif"></center>

According to the [documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat),

> The `Intl.NumberFormat` object is a constructor for objects that enable language-sensitive number formatting

And this means what in practice?

It simply means that with `Intl.NumberFormat`, JavaScript can construct an object that will have the ability to style (or to be technically correct, format) numbers based on human languages. In other words, numbers can be styled in a more human-understandable format.

Instead of numbers being presented as bland as `1234` or `4561254`, numbers can be better presented as `1,234` or `$4,561.254`. You get the gist? Good!

How does this work? Well, the syntax is simple.

`const formatterObject = new Intl.NumberFormat([locales[, options]]);`

What the syntax above means is this:

- `formatterObject` is the object constructed (created) by `Intl.NumberFormat`. `formatterObject` holds methods that can be used to format numbers,
- `locales` represents the code for human language that we want to format the number in. And why is this important?

  Different languages have different ways of displaying numbers. A number like `123456` will be displayed in Spanish as `123.456`, in English as `123,456` and in the Indian numerical system as `1,23,456`. `locales`is a code in the form of a string that informs `formatterObject` of which language to use when formatting.

  You can find a list of the locales under `subtag`
  [here](http://www.iana.org/assignments/language-subtag-registry). Examples are `'hi'` for Hindi, `'de-AT'` for German (de) used in Austria (AT) and `'en-IN'` for English (en) used in India (IN). Number system codes such as `"arab"`, `"arabext"` and `"latn"`

- `options` refers to additional configurations that can be used to configure how `formatterObject` styles numbers. `options` is an object.

Don't be dismayed by the square braces `[]` in the syntax. They are simply saying _Hey developer! Whatever is within me is optional. You can decide to exclude them when writing the syntax and the default configurations will be used_.

Using the number `1234567890.1234` as an example, lets convert our knowledge into code.

```javascript
const num = 1234567890.1234;

// setup formatters
const hindiNumberFormatter = new Intl.NumberFormat("en-IN");
const britishNumberFormatter = new Intl.NumberFormat("en-GB");
const spanishNumberFormatter = new Intl.NumberFormat("es-ES");

// use formatters
console.log(hindiNumberFormatter.format(num)); // 1,23,45,67,890.123
console.log(britishNumberFormatter.format(num)); // 1,234,567,890.123
console.log(spanishNumberFormatter.format(num)); // 1.234.567.890,123
```

What happened?

We created three types of number formatters with Intl.NumberFormat: `hindiNumberFormatter`, `britishNumberFormatter` and `spanishNumberFormatter`. Each formatter was created with a locale configuration that sets the formatting language of the formatter.

Next, we use the `format` method on the formatters to style the number `num` and display the result on the console.

And why is the last `4` not displayed in the formatted result? Did you notice that? Okay. Lets try another example:

```javascript
const num = 1234567890.1234;
const formatConfig = {
  style: "currency",
  currency: "USD", // CNY for Chinese Yen, EUR for Euro
  minimumFractionDigits: 2,
  currencyDisplay: "symbol",
};

// setup formatters
const britishNumberFormatter = new Intl.NumberFormat("en-GB", formatConfig);
const spanishNumberFormatter = new Intl.NumberFormat("es-ES", formatConfig);

// use formatters
console.log(britishNumberFormatter.format(num)); // US$1,234,567,890.12
console.log(spanishNumberFormatter.format(num)); // 1.234.567.890,12 US$
```

😃 Interesting! What happened here again?

Remember the second parameter in the `Intl.NumberFormat`? The `options` object? It is used to setup additional configurations for how `formatterObject` would format numbers passed to it. With properties such as `style` (possible values are `"decimal"` for plain number formatting, `"currency"` for currency formatting, and `"percent"` for percent formatting; the default is `"decimal"`), `currency`, `maximumSignificantDigits` (values are integers that determine how many significant digits the number to be formatted should have), `minimumFractionDigits` (having the value of an integer that determines the how many decimal digits the formatted number should have).

As in the second example, did you notice that the last two decimal digits (3 and 4) are not in the formatted number? That's because the minimum number of decimal digits we set in the `options` parameter as `formatConfig`, (`minimumFractionDigits`) was 2. See?

Apart from the `format` method on the `formatterObject`, there is also another method, the `formatToParts` method which returns an array of objects representing the number string in parts that can be used for custom locale-aware formatting.
For example:

```javascript
const num = 1234.5678;

const britishNumberFormatter = new Intl.NumberFormat("en-GB");
const spanishNumberFormatter = new Intl.NumberFormat("es-ES");

console.log(britishNumberFormatter.formatToParts(num));
/*
[
  0: Object { type: "integer", value: "1" }
  1: Object { type: "group", value: "," }
  2: Object { type: "integer", value: "234" }
  3: Object { type: "decimal", value: "." }
  4: Object { type: "fraction", value: "568" }
]
*/
console.log(spanishNumberFormatter.formatToParts(num)); // 1.234.567.890,123
/*
[
  0: Object { type: "integer", value: "1234" }
  1: Object { type: "decimal", value: "," }
  2: Object { type: "fraction", value: "568" }
] */
```

`formatToParts` splits the formatted number into parts, and determines the digit type (integer or fraction) and the symbol type (group or decimal).

Other configuration options for `options` can be found in the [MDN documentation for `Intl.NumberFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat).

### Experimental Features with Intl.NumberFormat

Some interesting features are being added to `Intl.NumberFormat` such as the ability to format with units (`l, mi/h, mph`), using exponential notations (E<sup>8</sup>, E<sup>-2</sup>) and BigInt support. These features cannot be used in production code yet. At the moment, only Chrome 77+ provides support for these features.

```javascript
const num = 1235.12;
const formatConfig = {
  style: "units",
  unit: "meter-per-second",
};

// setup formatters
const britishNumberFormatter = new Intl.NumberFormat("en", formatConfig); // 1,235.12 m/s
```

It's a pity but at the time of this writing, `Intl.NumberFormat` does not exist in Node.js.

All the best of all the best as you use `Intl.NumberFormat` to display numbers in styles customised for human languages and human-readable formats.

Cheers!