How to format a number as a currency string using JavaScript

There's nothing more horrible than reading big numbers like 1234566123 without separators. I mean, we aren't machines, it's hard to read that if we can't identify immediately the thousand's separator. This has been a regular problem for every developer that starts with number formatting in JavaScript as there are a lot of ways to format numbers in order to display them beautifully to the user.

In this article, I will show you 2 of the most useful ways to format a number to display it as a currency string in JavaScript.

A. Using the internationalization API localeString

If you prefer a really short way to format the numeric value using using a default method of JavaScript, then the internationalization API is the right thing for you. In JavaScript, the toLocaleString() method returns a string with a language-sensitive representation of this number:

(12345.25).toLocaleString(locale, { options ... })

This method expects as first argument the locale string, a BCP 47 language tag or an array of such tags that will be used to determine the numeric representation of the number. A BCP 47 language tag defines a language that may contain a primary language code as well as an extension. If this parameter is not provided, the toLocaleString() method will use the host environment's current locale. 

The second argument is an object whose properties are shown in the following table:

Value Description
localeMatcher

Determines the locale matching algorithm to use. It can be one of the following values:

  • lookup
  • best fit (default)
style

Determines the formatting style to use. It can be one of the following values:

  • decimal - general number formatting (default)
  • currency - currency formatting
  • percent - percent formatting
currency

Determines the currency formatting to use. It can be one of the 3-digit alphabetic currency codes from the ISO 4217 Currency Codes. For example, EUR for Euro, USD for US Dollar, or INR for Indian Rupee (See list of ISO 4217 currency codes).

currencyDisplay

Determines the how to display the currency formatting. It can be one of the following values:

  • symbol - use locale-specific currency symbol such as "$" (default)
  • code - use the ISO currency code such as "USD"
  • name - use the locale-specific currency name such as "dollar"
useGrouping

Determines whether to display grouping separators. It can be one of the following values:

  • true - grouping separators will be displayed (default)
  • false - grouping separators will not be displayed
minimumIntegerDigits

Determines the minimum number of integer digits to display. It can be a value between 1 and 21. If omitted, the default is 1.

minimumFractionDigits

Determines the minimum number of fractional digits to display. It can be a value between 0 and 20. If omitted, the default for decimal is 0, the default for percent is 0, and the default for currency is the "minor unit" value for the specified ISO 4217 currency code.

maximumFractionDigits

Determines the maximum number of fractional digits to display. It can be a value between 0 and 20. If omitted, the default for decimal is the larger of 3 and the minimumFractionDigits, the default for percent is the larger value of 0 and minimumFractionDigits, and the default for currency is the larger of the "minor unit" value for the specified ISO 4217 currency code and the minimumFractionDigits.

minimumSignificantDigits

Determines the minimum number of significant digits to display. It can be a value between 1 and 21. If omitted, the default is 1.

maximumSignificantDigits

Determines the maximum number of significant digits to display. It can be a value between 1 and 21. If omitted, the default is 21.

For example, you could easily format some numeric value to its currency representation like this:

// "$12,345.25"
(12345.25).toLocaleString("en-US", {
    style: "currency",
    currency: "USD"
});

// 12.345,25 €
(12345.25).toLocaleString("de-DE", {
    style: "currency",
    currency: "EUR"
});

// £12,345.25
(12345.25).toLocaleString("en-GB", {
    style: "currency",
    currency: "GBP"
});

// $ 12.345,25
(12345.25).toLocaleString("es-CO", {
    style: "currency",
    currency: "COP"
});

The tedious thing here is to determine the user's current locale, so if you have no way in your app to obtain it, you may simply use the in-browser locale and use a regular currency like the dollar to place the always present dollar symbol $ or use a custom currency:

// "COP 12,345.25"
(12345.25).toLocaleString(navigator.language, {
    style: "currency",
    currency: "COP"
});

If you want, you can use the Intl.NumberFormat class as well:

// $12,345.25
new Intl.NumberFormat('en-US', { 
    style: 'currency', 
    currency: 'USD' 
}).format(12345.25);

If you want to use the current visitor's locale, you may simply use a quite simple and short syntax:

// 123,456.67
Number((123456.67).toFixed(2)).toLocaleString();

You will need to add the currency symbol though.

B. Using the awesome number_format function of PHP in JavaScript

For full-stack developers, the number_format of PHP may sound familiar. This function included by default in PHP, helps the developer to easily format a number with grouped thousands, custom amount of decimals, decimal separator, and thousand's separator. In JavaScript, the alternatives don't look the same way, however, there's a JavaScript implementation of the mentioned PHP function. I'm talking about the PHP.js implementation of number_format available on this website. The function is the following one:

function number_format(number, decimals, decPoint, thousandsSep) { // eslint-disable-line camelcase
    number = (number + '').replace(/[^0-9+\-Ee.]/g, '')
    const n = !isFinite(+number) ? 0 : +number
    const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
    const sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep
    const dec = (typeof decPoint === 'undefined') ? '.' : decPoint
    let s = ''
    const toFixedFix = function (n, prec) {
        if (('' + n).indexOf('e') === -1) {
            return +(Math.round(n + 'e+' + prec) + 'e-' + prec)
        } else {
            const arr = ('' + n).split('e')
            let sig = ''
            if (+arr[1] + prec > 0) {
                sig = '+'
            }
            return (+(Math.round(+arr[0] + 'e' + sig + (+arr[1] + prec)) + 'e-' + prec)).toFixed(prec)
        }
    }
    // @todo: for IE parseFloat(0.55).toFixed(0) = 0;
    s = (prec ? toFixedFix(n, prec).toString() : '' + Math.round(n)).split('.')
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep)
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || ''
        s[1] += new Array(prec - s[1].length + 1).join('0')
    }
    return s.join(dec)
}

And it can be used like this:

number_format(1234.56)
//   outputs: '1,235'
number_format(1234.56, 2, ',', ' ')
//   outputs: '1 234,56'
number_format(1234.5678, 2, '.', '')
//   outputs: '1234.57'
number_format(67, 2, ',', '.')
//   outputs: '67,00'
number_format(1000)
//   outputs: '1,000'
number_format(67.311, 2)
//   outputs: '67.31'
number_format(1000.55, 1)
//   outputs: '1,000.6'
number_format(67000, 5, ',', '.')
//   outputs: '67.000,00000'
number_format(0.9, 0)
//   outputs: '1'
number_format('1.20', 2)
//  outputs 10: '1.20'
number_format('1.20', 4)
//  outputs: '1.2000'
number_format('1.2000', 3)
//  outputs: '1.200'
number_format('1 000,50', 2, '.', ' ')
//  outputs: '100 050.00'
number_format(1e-8, 8, '.', '')
//  outputs: '0.00000001'

Happy coding ❤️!

This could interest you

Become a more social person