I used the idea from Kerry's answer, but I simplified it since I was just looking for something simple for my specific purpose. Here is what I have:

function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

function numberWithCommas(x) {
    return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} {result}`);
    return pass;
}

let failures = 0;
failures += !test(0,        "0");
failures += !test(100,      "100");
failures += !test(1000,     "1,000");
failures += !test(10000,    "10,000");
failures += !test(100000,   "100,000");
failures += !test(1000000,  "1,000,000");
failures += !test(10000000, "10,000,000");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}


The regex uses two lookahead assertions:

  • a positive one to look for any point in the string that has a multiple of 3 digits in a row after it,
  • a negative assertion to make sure that point only has exactly a multiple of 3 digits. The replacement expression puts a comma there.

For example, if you pass it 123456789.01, the positive assertion will match every spot to the left of the 7 (since 789 is a multiple of 3 digits, 678 is a multiple of 3 digits, 567, etc.).

The negative assertion checks that the multiple of 3 digits does not have any digits after it. 789 has a period after it so it is exactly a multiple of 3 digits, so a comma goes there. 678 is a multiple of 3 digits, but it has a 9 after it, so those 3 digits are part of a group of 4, and a comma does not go there. Similarly for 567.

456789 is 6 digits, which is a multiple of 3, so a comma goes before that. 345678 is a multiple of 3, but it has a 9 after it, so no comma goes there. And so on. The \B keeps the regex from putting a comma at the beginning of the string.

neu-rah mentioned that this function adds commas in undesirable places if there are more than 3 digits after the decimal point. If this is a problem, you can use this function:

function numberWithCommas(x) {
    var parts = x.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    return parts.join(".");
}

function numberWithCommas(x) {
    var parts = x.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    return parts.join(".");
}

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} {result}`);
    return pass;
}

let failures = 0;
failures += !test(0              , "0");
failures += !test(0.123456       , "0.123456");
failures += !test(100            , "100");
failures += !test(100.123456     , "100.123456");
failures += !test(1000           , "1,000");
failures += !test(1000.123456    , "1,000.123456");
failures += !test(10000          , "10,000");
failures += !test(10000.123456   , "10,000.123456");
failures += !test(100000         , "100,000");
failures += !test(100000.123456  , "100,000.123456");
failures += !test(1000000        , "1,000,000");
failures += !test(1000000.123456 , "1,000,000.123456");
failures += !test(10000000       , "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}

T.J. Crowder pointed out that now that JavaScript has lookbehind (support info), it can be solved in the regular expression itself:

function numberWithCommas(x) {
    return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

function numberWithCommas(x) {
    return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} {result}`);
    return pass;
}

let failures = 0;
failures += !test(0,               "0");
failures += !test(0.123456,        "0.123456");
failures += !test(100,             "100");
failures += !test(100.123456,      "100.123456");
failures += !test(1000,            "1,000");
failures += !test(1000.123456,     "1,000.123456");
failures += !test(10000,           "10,000");
failures += !test(10000.123456,    "10,000.123456");
failures += !test(100000,          "100,000");
failures += !test(100000.123456,   "100,000.123456");
failures += !test(1000000,         "1,000,000");
failures += !test(1000000.123456,  "1,000,000.123456");
failures += !test(10000000,        "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}

(?<!\.\d*) is a negative lookbehind that says the match can't be preceded by a . followed by zero or more digits. The negative lookbehind is faster than the split and join solution (comparison), at least in V8.

Answer from Elias Zamaria on Stack Overflow
Top answer
1 of 16
3955

I used the idea from Kerry's answer, but I simplified it since I was just looking for something simple for my specific purpose. Here is what I have:

function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

function numberWithCommas(x) {
    return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} {result}`);
    return pass;
}

let failures = 0;
failures += !test(0,        "0");
failures += !test(100,      "100");
failures += !test(1000,     "1,000");
failures += !test(10000,    "10,000");
failures += !test(100000,   "100,000");
failures += !test(1000000,  "1,000,000");
failures += !test(10000000, "10,000,000");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}


The regex uses two lookahead assertions:

  • a positive one to look for any point in the string that has a multiple of 3 digits in a row after it,
  • a negative assertion to make sure that point only has exactly a multiple of 3 digits. The replacement expression puts a comma there.

For example, if you pass it 123456789.01, the positive assertion will match every spot to the left of the 7 (since 789 is a multiple of 3 digits, 678 is a multiple of 3 digits, 567, etc.).

The negative assertion checks that the multiple of 3 digits does not have any digits after it. 789 has a period after it so it is exactly a multiple of 3 digits, so a comma goes there. 678 is a multiple of 3 digits, but it has a 9 after it, so those 3 digits are part of a group of 4, and a comma does not go there. Similarly for 567.

456789 is 6 digits, which is a multiple of 3, so a comma goes before that. 345678 is a multiple of 3, but it has a 9 after it, so no comma goes there. And so on. The \B keeps the regex from putting a comma at the beginning of the string.

neu-rah mentioned that this function adds commas in undesirable places if there are more than 3 digits after the decimal point. If this is a problem, you can use this function:

function numberWithCommas(x) {
    var parts = x.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    return parts.join(".");
}

function numberWithCommas(x) {
    var parts = x.toString().split(".");
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    return parts.join(".");
}

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} {result}`);
    return pass;
}

let failures = 0;
failures += !test(0              , "0");
failures += !test(0.123456       , "0.123456");
failures += !test(100            , "100");
failures += !test(100.123456     , "100.123456");
failures += !test(1000           , "1,000");
failures += !test(1000.123456    , "1,000.123456");
failures += !test(10000          , "10,000");
failures += !test(10000.123456   , "10,000.123456");
failures += !test(100000         , "100,000");
failures += !test(100000.123456  , "100,000.123456");
failures += !test(1000000        , "1,000,000");
failures += !test(1000000.123456 , "1,000,000.123456");
failures += !test(10000000       , "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}

T.J. Crowder pointed out that now that JavaScript has lookbehind (support info), it can be solved in the regular expression itself:

function numberWithCommas(x) {
    return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

function numberWithCommas(x) {
    return x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
}

function test(x, expect) {
    const result = numberWithCommas(x);
    const pass = result === expect;
    console.log(`${pass ? "✓" : "ERROR ====>"} {result}`);
    return pass;
}

let failures = 0;
failures += !test(0,               "0");
failures += !test(0.123456,        "0.123456");
failures += !test(100,             "100");
failures += !test(100.123456,      "100.123456");
failures += !test(1000,            "1,000");
failures += !test(1000.123456,     "1,000.123456");
failures += !test(10000,           "10,000");
failures += !test(10000.123456,    "10,000.123456");
failures += !test(100000,          "100,000");
failures += !test(100000.123456,   "100,000.123456");
failures += !test(1000000,         "1,000,000");
failures += !test(1000000.123456,  "1,000,000.123456");
failures += !test(10000000,        "10,000,000");
failures += !test(10000000.123456, "10,000,000.123456");
if (failures) {
    console.log(`${failures} test(s) failed`);
} else {
    console.log("All tests passed");
}
.as-console-wrapper {
    max-height: 100% !important;
}

(?<!\.\d*) is a negative lookbehind that says the match can't be preceded by a . followed by zero or more digits. The negative lookbehind is faster than the split and join solution (comparison), at least in V8.

2 of 16
3275

I'm surprised nobody mentioned Number.prototype.toLocaleString. It's implemented in JavaScript 1.5 (which was introduced in 1999), so it's basically supported across all major browsers.

var n = 34523453.345;
console.log(n.toLocaleString());    // "34,523,453.345"

It also works in Node.js as of v0.12 via inclusion of Intl.

If you want something different, Numeral.js might be interesting.

Discussions

Formatting a number with commas as a thousand digits without converting it into a string
I’ve tried this but when I checked it with console.log(isNaN(conversion));, it returns true. How do you format this without it converting into a string? const income = Number(8000); const conversion = income.toLocaleString(navigator.language, { minimumFractionDigits: 2 }); console.log(is... More on forum.freecodecamp.org
🌐 forum.freecodecamp.org
1
1
March 7, 2022
Format a Number with Commas in React
This is just vanilla JS, no? More on reddit.com
🌐 r/react
4
0
March 22, 2023
jquery - Javascript Number Formatting With Commas - Stack Overflow
I'm trying to format numbers so they have commas between every 3 numbers. It is very glitchy however and doesn't work once it gets to 8 numbers. I've put all the code in a jsfiddle below: function More on stackoverflow.com
🌐 stackoverflow.com
Format number to string for commas
Wondering if anybody has a snippet in Verse for formatting an int or float to a string with commas in it at the thousand, million mark? Can’t find anything anywhere so far. Wish there was a format function… or is there? More on forums.unrealengine.com
🌐 forums.unrealengine.com
0
0
October 5, 2023
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Global_Objects › Intl › NumberFormat
Intl.NumberFormat - JavaScript | MDN
In order to get the format of the language used in the user interface of your application, make sure to specify that language (and possibly some fallback languages) using the locales argument: ... const number = 123456.789; // German uses comma as decimal separator and period for thousands console.log(new Intl.NumberFormat("de-DE").format(number)); // 123.456,789 // Arabic in most Arabic speaking countries uses real Arabic digits console.log(new Intl.NumberFormat("ar-EG").format(number)); // ١٢٣٤٥٦٫٧٨٩ // India uses thousands/lakh/crore separators console.log(new Intl.NumberFormat("en-IN").format(number)); // 1,23,456.789 // the nu extension key requests a numbering system, e.g.
🌐
Reddit
reddit.com › r/react › format a number with commas in react
r/react on Reddit: Format a Number with Commas in React
March 22, 2023 -

If you’re working with large numbers in React, formatting them with commas for readability is often helpful. Fortunately, there’s a simple way to do this using the built-in Intl.NumberFormat and toLocaleString() method.

import React from "react";  
export default function App() {  
    const num = 123456.789;  
    const options = {  maximumFractionDigits: 2   }   
    const formattedNumber = Intl.NumberFormat("en-US",options).format(num); 
  
    return <h2>{formattedNumber}</h2>; 
}  
//Output => 123,456.78

To learn more about the Intl.NumberFormat and toLocaleString() methods, visit 👉 : Format a Number with Commas in React

🌐
DEV Community
dev.to › lavary › add-commas-to-numbers-in-javascript-explained-with-examples-27k8
Add commas to numbers in JavaScript (Explained with examples) - DEV Community
February 6, 2023 - This regular expression starts with a boundary (\B) to avoid a comma at the beginning of the number. Then, it uses to lookaheads to mark numbers in hundreds. Consequently, The replace() method places a comma in each match. Formatting numbers can be done in a variety of ways in JavaScript.
Find elsewhere
🌐
Crio
crio.do › blog › format-numbers-with-commas-as-thousands-separators-2025-javascript-criodo
How to Format a Number with Commas as Thousands Separators?
December 26, 2024 - Formatting numbers with commas as thousands separators is essential for enhancing readability, especially when displaying large numbers in user interfaces. This is a common requirement for financial data, statistics, and other applications. Here’s a concise and effective way to format numbers using JavaScript...
🌐
Favtutor
favtutor.com › articles › format-numbers-commas-javascript
Format Numbers with Commas in JavaScript (with code)
February 5, 2024 - JavaScript offers several methods for formatting numbers with commas. Here we will cover the toLocaleString() method, leveraging the Intl.NumberFormat() object, and using regular expressions.
🌐
GeeksforGeeks
geeksforgeeks.org › javascript › how-to-print-a-number-with-commas-as-thousands-separators-in-javascript
How to print a number with commas as thousands separators in JavaScript? - GeeksforGeeks
July 12, 2025 - The locale 'en-US' is used to specify that the locale takes the format of the United States and the English language, where numbers are represented with a comma between the thousands. This will format the number with commas at the thousands of places and return a string with the formatted number. ... <h1 style="color: green">GeeksforGeeks</h1> <b> How to print a number with commas as thousands separators in JavaScript?
🌐
Stack Abuse
stackabuse.com › bytes › format-numbers-with-commas-in-javascript
Format Numbers with Commas in JavaScript
August 7, 2023 - This method automatically formats the number according to the user's locale, making it an excellent choice for internationalization. For my locale, it uses commas after every third digit. Note: We're used to seeing numbers, like the one shown above, presented with only two digits after the decimal when displayed as currency.
🌐
DEV Community
dev.to › onlinemsr › big-numbers-no-worries-javascript-format-number-with-commas-n6j
Big Numbers, No Worries: JavaScript Format Number With Commas - DEV Community
March 23, 2024 - Do you want to make your numbers look more readable and friendly? You can do that with the toLocaleString() method in JavaScript! This method lets you format numbers based on the user’s location and preferences.
🌐
Dhairyashah
dhairyashah.dev › posts › how-to-seperate-number-with-commas-in-javascript
How to seperate number with commas in Javascript
const number = 14500240 const formatedNumber = number.toLocaleString("en-IN") console.log(formatedNumber) function numberWithCommas(num) { return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } const number = numberWithCommas(234234.555); ...
🌐
Unreal Engine
forums.unrealengine.com › development › programming & scripting
Format number to string for commas - Programming & Scripting - Epic Developer Community Forums
October 5, 2023 - Wondering if anybody has a snippet in Verse for formatting an int or float to a string with commas in it at the thousand, million mark? Can’t find anything anywhere so far. Wish there was a format function… or is there?
🌐
RSWP Themes
rswpthemes.com › home › javascript tutorial › how to format numbers in javascript with commas
How to Format Numbers in JavaScript with Commas
January 12, 2024 - This step-by-step guide will walk you through the process of formatting numbers with commas in JavaScript.
🌐
Medium
medium.com › @onlinemsr › big-numbers-no-worries-javascript-format-number-with-commas-17ec7f878834
Big Numbers, No Worries: JavaScript Format Number With Commas
March 23, 2024 - If you are a web developer, you may have encountered the challenge of formatting numbers with commas in JavaScript. For example, you can display a large number, like 1000000 or 1,000,000, for better readability. Using the toLocaleString() method you ...
🌐
Codingexercises
codingexercises.com › format-a-number-with-a-comma-as-a-thousands-separator-js
Format a number with comma as a thousands separator in JS
January 12, 2021 - In JS, we can add a comma as thousands separator using the toLocaleString() method, or using Intl.NumberFormat().format, or using a RegExp. In this tutorial, we'll cover the first two listed means of doing this.
🌐
DevGenius
blog.devgenius.io › how-to-format-a-number-with-commas-as-thousands-digit-separators-in-javascript-ce6ff8475192
How to Format a Number with Commas as Thousands Digit Separators in JavaScript? | by John Au-Yeung | Dev Genius
May 18, 2021 - We can use the replace method with a regex to add a comma every 3 digits. ... The \B(?=(\d{3})+ looks for groups of 3 digits before the decimal place. The \B keeps replace from adding a comma at the beginning of the string.