Formatting Compact Numbers with JavaScript
Tags: i18n, internationalization
Published: 2023-04-28 23:24:40


by [Satyam Tripathi](https://blog.openreplay.com/authors/satyam-tripathi)

<blockquote><em>Whether you’re using any social media apps or YouTube, you might have seen that the number of likes, subscribers/followers, comments, etc., are always shown in rounded, compact form, like 23K instead of 23145. This article will look at the JavaScript Internationalization API and how to produce compact numbers with it.</em></blockquote>

Compact numbers are the compact/concise way of representing large numbers. Like using **"K"** for ***thousands***, **"M"** for ***millions***, **"B"** for ***billions***, etc.

The JavaScript Internationalization API is a built-in library that is reliable and flexible for formatting compact numbers and is consistent across different browsers. The JS Internationalization API is a more efficient approach than using third-party packages.

## How to use Intl.NumberFormat Object?
An `Intl.NumberFormat` object is part of the JS Internationalization API and is used to format numbers according to a particular locale and options. 

When developers use the `Intl.NumberFormat` objects, their applications display numbers consistently regardless of the user's locale or preference.

As a first step, you must create an instance of the `Intl.NumberFormat` object by calling its constructor with the new keyword.

```javascript
let formater = new Intl.NumberFormat();
let formater = new Intl.NumberFormat(locales);
let formater = new Intl.NumberFormat(locales, options);
```

* **Locales:** It specifies the language and the region to format the number like `en-US` (US English), `fr-FR` (French), `de-DE` (German), and `zh-CN` (Chinese).
* **Options:** It provides several options that could be used to format numbers.

### Set the Locales and Options
`Intl.NumberFormat` provides several locales that you can set to customize how numbers are formatted. If you display any large number to a user in the US, then the number should be separated with a *comma at every thousand*. However, for a German user, it should be separated with a *dot at every thousand*, etc.

It also provides several options to format the number in a different style. Some of the options are given below:

* **style:** It’s the formatting style, the ***default*** is `decimal`. There are various styles, such as *currency for current formatting*, *percent for percent formatting*, and *unit for unit formatting*.
* **notation:** The ***default*** is `standard`. It could be `scientific`, `engineering`, and `compact`.
* **currencyDisplay:** This is used to display the currency in currency format. The default value is `Symbol`, which could be `narrowSymbol`, `code`, and `name`.


**Advice:** If you'd like to learn more about the options and locales, [**click here**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options).

To set the options for formatting numbers, the object would be created like this:

```javascript
let uscurrencyformatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
});

```

The locale is set to `en-US,` and the style is `currency`, which formats the numbers in currency format. The currency is also defined as USD.

### Using the format method
Once an instance of `Intl.NumberFormat` has been created and options and locales have been set, you can use the format method to format the numbers. 

Here is an example:

```javascript
let number = 987654321;
let formattedNumber = uscurrencyformatter.format(number);
console.log(formattedNumber);

// Output:
// $987,654,321.00
```

Above, you can see the **2 0's** after the decimal. You can also handle them easily by using the `minimumFractionDigits`. 

```javascript
let uscurrencyformatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  minimumFractionDigits: 0,
});
```

<div style="background-color:#efefef; border-radius:8px; padding:10px; display:block;">
<hr/>
<h3><em>Session Replay for Developers</em></h3> 
<p><em>Uncover frustrations, understand bugs and fix slowdowns like never before with <strong><a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a></strong> — an open-source session replay suite for developers. It can be <strong>self-hosted</strong> in minutes, giving you complete control over your customer data.</em></p>
<img alt="OpenReplay" style="margin-top:5px; margin-bottom:5px;" width="768" height="400" src="https://raw.githubusercontent.com/openreplay/openreplay/main/static/openreplay-git-hero.svg" class="astro-UXNKDZ4E" loading="lazy" decoding="async">
<p><em>Happy debugging! <a href="https://openreplay.com" target="_blank">Try using OpenReplay today.</a></em><p>
<hr/>
</div>


## Examples

Let's see a few examples to add clarity!


### Example 1:
Below, the same number is formatted in *3 different locales*. The first is separated by *commas*, the second by *dots*, and the third by  *spaces*.

```javascript
let number = 987654321987;

let USformatter = new Intl.NumberFormat("en-US");
let USformattedNumber = USformatter.format(number);
console.log(USformattedNumber); // 987,654,321,987

let germanformatter = new Intl.NumberFormat("de-DE");
let DEformattedNumber = germanformatter.format(number);
console.log(DEformattedNumber); // 987.654.321.987

let frenchformatter = new Intl.NumberFormat("fr-FR");
let FRformattedNumber = frenchformatter.format(number);
console.log(FRformattedNumber); // 987 654 321 987
```

### Example 2:
In this example, we have added the `options`. Here the *`notation`* is set to *`compact`*, which means the larger number will be formatted to a small notation like *1000000* will be formatted to *1M*.

```javascript
let options = {
  notation: "compact",
};

let number = 987654321987;

let USformatter = new Intl.NumberFormat("en-US", options);
let USformattedNumber = USformatter.format(number);
console.log(USformattedNumber); // 988B

let germanformatter = new Intl.NumberFormat("de-DE", options);
let DEformattedNumber = germanformatter.format(number);
console.log(DEformattedNumber); // 988 Mrd.

let frenchformatter = new Intl.NumberFormat("fr-FR", options);
let FRformattedNumber = frenchformatter.format(number);
console.log(FRformattedNumber); // 988 Md 
```

### Example 3:
In the following, the compact numbers are formatted in "K", "M", "B", and "T". If you change the `compactDisplay` to `long`, then "K" would be replaced by a thousand, "M" by Million, "B" by Billion, and "T" by Trillion.
```javascript
let options = {
  notation: "compact",
  compactDisplay: "short",
};
function formatCmpctNumber(number) {
  const usformatter = Intl.NumberFormat("en-US", options);
  return usformatter.format(number);
}

console.log(formatCmpctNumber(-32)); // -32
console.log(formatCmpctNumber(999)); // 999
console.log(formatCmpctNumber(5678)); // 5.7K
console.log(formatCmpctNumber(230000)); // 230K
console.log(formatCmpctNumber(32333435)); // 32M
console.log(formatCmpctNumber(92351236547)); // 92B
console.log(formatCmpctNumber(12233445566778)); // 12T
```


### Conclusion
In this article, we took a look at the JS Internationalization API and how to use it to format compact numbers. We also explored the `Intl.NumberFormat` object to format the compact numbers and how to use locales and options. Then at the end, we looked at some examples to clarify everything.