How to format a number as a currency value in JavaScript

By

Learn how to format a number as a currency value in JavaScript using Intl.NumberFormat, setting the locale, currency code, and minimumFractionDigits.

~~~

To format a number as a currency value in JavaScript, use Intl.NumberFormat. It’s built into the language, it knows the formatting rules of every currency, and it works in browsers and in Node.js.

Say you have a number like 10, and it represents the price of something.

You want to transform it to $10.00.

If the number has more than 3 digits however it should be displayed differently, for example 1000 should be displayed as $1,000.00

This is in USD, however.

Different countries have different conventions to display values.

JavaScript makes it very easy for us with the ECMAScript Internationalization API, a browser API that provides a lot of internationalization features, like dates and time formatting.

It is very well supported:

Browser support for the internationalization API

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 2
})

formatter.format(1000) // "$1,000.00"
formatter.format(10) // "$10.00"
formatter.format(123233000) // "$123,233,000.00"

The minimumFractionDigits property sets the fraction part to be always at least 2 digits. You can check which other parameters you can use in the NumberFormat MDN page.

format() also rounds for you:

formatter.format(4.567) // "$4.57"

How to format other currencies

This example creates a number formatter for the Euro currency, for the Italian country:

const formatter = new Intl.NumberFormat('it-IT', {
  style: 'currency',
  currency: 'EUR'
})

formatter.format(125000) // "125.000,00 €"

Notice everything changed compared to USD: the thousands separator is a dot, the decimal separator is a comma, and the symbol moved after the number. Same code, one different locale.

Some currencies have no decimal part at all. The Japanese yen is one:

const formatter = new Intl.NumberFormat('ja-JP', {
  style: 'currency',
  currency: 'JPY'
})

formatter.format(1000) // "¥1,000"

Intl.NumberFormat knows this rule already, so you don’t have to handle it.

Reuse the formatter

Creating a formatter has a cost, because JavaScript loads the locale data behind the scenes. Calling format() is cheap.

So if you’re formatting a list of 200 prices, create the formatter once outside the loop and call format() on each price. Don’t create a new formatter per item.

Watch out for floating point math

One pitfall: storing prices as decimal numbers. Floating point math is not exact:

0.1 + 0.2 // 0.30000000000000004

The formatter hides the problem because it rounds. formatter.format(0.1 + 0.2) returns "$0.30". But the underlying value is still wrong, and errors accumulate when you sum many prices.

The fix is to store prices as integer cents, like 1050 for $10.50, and divide by 100 only when formatting:

formatter.format(1050 / 100) // "$10.50"

I built a free Intl.NumberFormat playground where you can try locales, currencies and options and get the code.

~~~

Related posts about js: