Number.prototype.toLocaleString()

Formats a number using locale conventions for grouping, decimals, currency and percent.

Signature
toLocaleString()
toLocaleString(locales)
toLocaleString(locales, options)

Parameters

ParameterTypeDescription
$localesoptionalstring | string[]A BCP 47 language tag, or an array of them. Matches the locales parameter of the Intl.NumberFormat() constructor. Ignored where Intl.NumberFormat is unsupported, in which case the host locale is used.
$optionsoptionalobjectAn object adjusting the output format, matching the options parameter of the Intl.NumberFormat() constructor — style, currency, minimumFractionDigits, notation and the rest. Ignored where Intl.NumberFormat is unsupported.

Return value

stringA string representing the number according to language-specific conventions. Where Intl.NumberFormat is available this equals `new Intl.NumberFormat(locales, options).format(number)`.

Errors

Throws a RangeError for an invalid locale tag or an out-of-range option value, following the Intl.NumberFormat() constructor.

This is the method to reach for whenever a number is going to be read by a person. It inserts the grouping separator, uses the right decimal mark, and — with options — handles currency, percentages and compact notation without any string surgery on your part.

Always pass a locale

With no arguments the output depends on whoever is running the code. The same call gives "1,234,567.891" in en-US and "1.234.567,891" in de-DE. Snapshot tests, fixtures and any value you plan to parse back need an explicit tag such as 'en-US'; leave it out only when you genuinely want the user's own convention.

Useful options

  • { style: 'currency', currency: 'USD' } — adds the symbol and the correct number of minor digits for that currency.
  • { style: 'percent' } — multiplies by 100 and appends the sign, so pass 0.256, not 25.6.
  • { notation: 'compact' } — "1.2M".
  • { maximumFractionDigits: 2 } — like toFixed() but with grouping and without forced trailing zeros.

Performance

Each call builds a formatter. In a loop or a table render, construct one Intl.NumberFormat up front and reuse its format() method instead.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Render a price with the right symbol and decimal count for a market
  • Show a large count as "1.2M" in a dashboard tile
  • Format a ratio as a percentage without manual multiplication

Frequently asked questions

How do I add commas to a number in JavaScript?

Call n.toLocaleString('en-US'), which inserts the grouping separators for that locale. Pin the locale rather than calling with no arguments, since other locales group with periods or spaces.

Why does my percent come out 100 times too large?

style: 'percent' multiplies the value by 100 itself, so pass the ratio (0.256) rather than the already-scaled number (25.6).

Is toLocaleString() slow in a loop?

Each call creates a new formatter, so for many values create one Intl.NumberFormat with the same locale and options and call its format() method instead.

More examples

Compact notation for dashboards

Compact notation picks the right suffix per locale and rounds sensibly, replacing the usual hand-rolled divide-by-1000 ladder.

Example · javascript
const counts = [999, 1234, 1234567, 9876543210];

for (const c of counts) {
  console.log(c.toLocaleString('en-US', { notation: 'compact' }));
}
// "999"
// "1.2K"
// "1.2M"
// "9.9B"

Reusing a formatter in a loop

toLocaleString() constructs a formatter on every call; hoisting one Intl.NumberFormat and calling format() gives identical output and avoids repeating that setup per row.

Example · javascript
const fmt = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'EUR',
});

const rows = [12.5, 1999, 0.99];
for (const r of rows) {
  console.log(fmt.format(r));
}
// "€12.50"
// "€1,999.00"
// "€0.99"

Controlling fraction digits

The fraction-digit options give toFixed()-style control while keeping the grouping separator, which toFixed() never adds.

Example · javascript
const v = 1234.5678;

console.log(v.toLocaleString('en-US', { maximumFractionDigits: 2 })); // "1,234.57"
console.log(v.toLocaleString('en-US', { minimumFractionDigits: 6 })); // "1,234.567800"
console.log((5).toLocaleString('en-US', { minimumFractionDigits: 2 })); // "5.00"
console.log(v.toFixed(2)); // "1234.57" — no grouping

Discussion

  • Be the first to comment on this lesson.