Number formatting in JavaScript: toLocaleString and Intl.NumberFormat

Kinga Pomykała
Kinga Pomykała
••Last updated: May 07, 2026•4 min read
Number formatting in JavaScript: toLocaleString and Intl.NumberFormat

JavaScript has built-in APIs for locale-aware number formatting that cover the vast majority of i18n use cases without any third-party dependencies. This post focuses on toLocaleString() and Intl.NumberFormat, the two main tools, with practical examples for currencies, percentages, and units.

For a broader guide covering dates, times, time zones, and currencies together, see Handling dates, times, numbers, and currencies in i18n. Correct number formatting is one of the foundational i18n concerns, alongside date handling, pluralization, and locale detection, all covered in our complete technical guide to internationalization and software localization.

toLocaleString() vs Intl.NumberFormat

Both APIs format numbers locale-correctly. The difference is performance. Intl.NumberFormat is more efficient when you need to format many numbers with the same options because you create the formatter once and reuse it:

// toLocaleString: creates a formatter on every call
[1000, 2000, 3000].map(n => n.toLocaleString('de-DE'));
 
// Intl.NumberFormat: create once, format many
const fmt = new Intl.NumberFormat('de-DE');
[1000, 2000, 3000].map(n => fmt.format(n));

For one-off formatting, toLocaleString() is perfectly fine and more concise. Both accept the same locale and options arguments.

Syntax

// toLocaleString
number.toLocaleString(locale, options);
 
// Intl.NumberFormat
new Intl.NumberFormat(locale, options).format(number);

Parameters

  • locale (optional): if not provided, the method uses the host environment's current locale (e.g., default browser language). Pass undefined to use the system locale explicitly.
  • options (optional): object with formatting options
const n = 123456.789;
 
n.toLocaleString('pl-PL');
// → "123 456,789"
 
n.toLocaleString('ar-EG');
// → "١٢٣٬٤٥٦٫٧٨٩"

Limit significant digits

const price = 123456.789;
price.toLocaleString('en-IN', { 
  maximumSignificantDigits: 2 
});
// → "1,20,000"

Use system locale with controlled decimal places

Pass undefined as the first parameter to use the browser's default locale.

const price = 30000.65;
price.toLocaleString(undefined, { 
  minimumFractionDigits: 2, 
  maximumFractionDigits: 2 
});
// English output: 30,000.65
// German output: 30.000,65
// French output: 30 000,65

Formatting style

The style property accepts four values:

  • decimal (default)
  • currency
  • percent
  • unit

Style: Currencies

Use style property in options object with value currency to format number into a string.

const price = 123456.789;
 
price.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' });
// → "123.456,79 €"
 
price.toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' });
// → "¥123,457"

Note that JPY has no subunits, so the decimal is correctly omitted. Use minimumFractionDigits and maximumFractionDigits when you need consistent decimal places:

price.toLocaleString('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 2,
  maximumFractionDigits: 2,
});
// → "$123,456.79"

The currencyDisplay property changes how the currency identifier appears:

const price = 123456.789;
 
price.toLocaleString('de-DE', { 
  style: 'currency', 
  currencyDisplay: 'code', 
  currency: 'EUR' 
});
// → "123.456,79 EUR"
 
price.toLocaleString('ja-JP', { 
  style: 'currency', 
  currencyDisplay: 'name', 
  currency: 'JPY' 
});
// → "123,457円"

Possible currencyDisplay values: symbol (default), code, name, narrowSymbol.

Style: Percentages

Percentage sign placement and numeral style both vary by locale.

const value = 0.767;
 
value.toLocaleString('pl-PL', { style: 'percent' });
// → "77%"
 
value.toLocaleString('ar-SA', { style: 'percent' });
// → "٧٧٪"
 
value.toLocaleString('tr-TR', { style: 'percent' });
// → "%77"  (sign before the number in Turkish)
 
value.toLocaleString('fr-FR', { style: 'percent' });
// → "77 %"  (space before percent sign in French)

Style: Units

One of the most underused JavaScript locale features. It formats numbers into any of the standard measurement units with proper locale-appropriate notation.

Liter

const value = 3;
 
value.toLocaleString('pl-PL', { style: 'unit', unit: 'liter' });
// → "3 l"
 
value.toLocaleString('pl-PL', { style: 'unit', unit: 'liter', unitDisplay: 'long' });
// → "3 litry"
 
value.toLocaleString('pl-PL', { style: 'unit', unit: 'liter', unitDisplay: 'narrow' });
// → "3l"

unitDisplay accepts: short (default), long, narrow.

Kilometer per hour

Compound units use X-per-Y syntax. JavaScript picks the appropriate locale pattern:

const speed = 50.2137;
 
speed.toLocaleString('pt-PT', { style: 'unit', unit: 'kilometer-per-hour' });
// → "50,214 km/h"
 
speed.toLocaleString('en-US', { style: 'unit', unit: 'kilometer-per-hour' });
// → "50.214 km/h"

Supported units

Below, you can check all possible values for unit property.

unit value
acre
bit
byte
celsius
centimeter
day
degree
fahrenheit
fluid-ounce
foot
gallon
gigabit
gigabyte
gram
hectare
hour
inch
kilobit
kilobyte
kilogram
kilometer
liter
unit value
megabit
megabyte
meter
mile
mile-scandinavian
milliliter
millimeter
millisecond
minute
month
ounce
percent
petabyte
pound
second
stone
terabit
terabyte
week
yard
year

Terabyte per gram

The unit property doesn't have to make sense, it accepts any combination. 😊

const value = 50.2137;
value.toLocaleString('pl-PL', {
  style: 'unit',
  unit: 'terabyte-per-gram',
  unitDisplay: "long"
});
// output: 50,214 terabajta na gram

Compact notation

For dashboards and analytics UIs where space is limited:

const value = 1500000;
 
new Intl.NumberFormat('en-US', { notation: 'compact' }).format(value);
// → "1.5M"
 
new Intl.NumberFormat('de-DE', { notation: 'compact' }).format(value);
// → "1,5 Mio."
 
new Intl.NumberFormat('ja-JP', { notation: 'compact' }).format(value);
// → "150万"  (万 = 10,000 in Japanese grouping)

Accounting notation

Negative amounts shown in parentheses rather than with a minus sign, common in financial contexts:

const loss = -1234.56;
 
new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  currencySign: 'accounting',
}).format(loss);
// → "($1,234.56)"

Resources

Kinga Pomykała
Kinga Pomykała
Content creator of SimpleLocalize

Get started with SimpleLocalize

  • All-in-one localization platform
  • Web-based translation editor for your team
  • Auto-translation, QA-checks, AI and more
  • See how easily you can start localizing your product.
  • Powerful API, hosting, integrations and developer tools
  • Unmatched customer support
Start for free
No credit card required∙5-minute setup
"The product
and support
are fantastic."
Laars Buur|CTO
"The support is
blazing fast,
thank you Jakub!"
Stefan|Developer
"Interface that
makes any dev
feel at home!"
Dario De Cianni|CTO
"Excellent app,
saves my time
and money"
Dmitry Melnik|Developer