The quickest way to format numbers with commas in TypeScript is value.toLocaleString("en-US"). It returns a string with a comma between every group of three digits, so 1284567.5 becomes “1,284,567.5”:
const display = revenue.toLocaleString("en-US"); // "1,284,567.5"
Nothing below is hand-typed output: I pasted each result from TypeScript 7.0.2 and Node.js v22.22.2, compiling with --strict turned on.
Below, I’ll cover toLocaleString, a reusable Intl.NumberFormat, decimals, a regex fallback, compact labels like 1.3M, and turning a formatted string back into a number.
Add commas with toLocaleString()
Always pass the locale. Without it, the result follows the browser or server settings, so a user in Germany sees periods where you expected commas. toLocaleString() also works on bigint:
const population: number = 39431263;
const revenue: number = 1284567.5;
const bigTotal: bigint = 36218604000000n;
console.log(population.toLocaleString("en-US"));
console.log(revenue.toLocaleString("en-US"));
console.log(bigTotal.toLocaleString("en-US"));
console.log(revenue.toLocaleString("de-DE")); // German separators
Output:
39,431,263
1,284,567.5
36,218,604,000,000
1.284.567,5
Remember that the result is a string, meant for display only. If you only need plain digits without grouping, converting a number to a string in TypeScript is the simpler route.
Use Intl.NumberFormat for repeated formatting
toLocaleString() builds a formatter on every call. When you format a whole table or list, create one Intl.NumberFormat and reuse its format() method. It’s faster and keeps the options in one place:
const withCommas = new Intl.NumberFormat("en-US");
const twoDecimals = new Intl.NumberFormat("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
const amounts: number[] = [1234.5678, 98765.4, 2500000, -45210.999];
for (const n of amounts) {
console.log(String(n).padEnd(12), withCommas.format(n).padEnd(12), twoDecimals.format(n));
}
console.log("no grouping:", new Intl.NumberFormat("en-US", { useGrouping: false }).format(2500000));
Output:
1234.5678 1,234.568 1,234.57
98765.4 98,765.4 98,765.40
2500000 2,500,000 2,500,000.00
-45210.999 -45,210.999 -45,211.00
no grouping: 2500000

useGrouping: false turning commas off.Look at the first row. With no options, maximumFractionDigits defaults to 3, so 1234.5678 is rounded to “1,234.568”. That catches people who expect every digit to survive.
The array loop here is a simple for...of; to build a new array of labels, use map() as shown in mapping an array of objects in TypeScript.
How do you format decimals with commas?
Set minimumFractionDigits and maximumFractionDigits to the same number, as in twoDecimals above. You get commas and a fixed decimal count in one step, with 2500000 showing as “2,500,000.00”. For zero-padding and toFixed(), see formatting a number to 2 digits in TypeScript.
Don’t chain toFixed(2) before toLocaleString(), though. toFixed() returns a string, and a string can’t be grouped like a number, so you’d lose the commas.
Add thousands separators with a regex
A regular expression gives you commas without the Intl API, which is handy for fixed-format exports. The popular one-liner has a bug with decimals, so compare it with the fixed version:
function addCommasNaive(value: number): string {
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function addCommas(value: number): string {
const [whole, fraction] = value.toString().split(".");
const grouped = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return fraction === undefined ? grouped : `${grouped}.${fraction}`;
}
console.log("naive:", addCommasNaive(8405837), addCommasNaive(-1234567), addCommasNaive(1234.5678));
console.log("fixed:", addCommas(8405837), addCommas(-1234567), addCommas(1234.5678));
Output:
naive: 8,405,837 -1,234,567 1,234.5,678
fixed: 8,405,837 -1,234,567 1,234.5678

The fix formats only the whole-number part, then glues the fraction back on. Negatives work because \B never matches right after the minus sign. More on replace() patterns is in replacing all occurrences of a substring in TypeScript.
Common TypeScript errors with formatted numbers
The formatted value is a string, and strict mode won’t let you treat it as a number. A misspelled option is caught too:
const miles: number = 2789.6;
const total: number = miles.toLocaleString("en-US");
const doubled = miles.toLocaleString("en-US") * 2;
const label = new Intl.NumberFormat("en-US", { maximumFractionDigit: 1 }).format(miles);
Output:
commas_types.ts(3,7): error TS2322: Type 'string' is not assignable to type 'number'.
commas_types.ts(4,17): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
commas_types.ts(5,48): error TS2769: No overload matches this call.
The last overload gave the following error.
Object literal may only specify known properties, but 'maximumFractionDigit' does not exist in type 'NumberFormatOptions'. Did you mean to write 'maximumFractionDigits'?

maximumFractionDigit and suggests the right name.Keep the raw number for math and sorting, and format only when you display it.
Compact numbers and parsing commas back
For dashboards, notation: "compact" turns 1,250,000 into “1.3M”. Going the other way, Number() returns NaN for “1,234.56”, so strip the separators first.
I read the separators from formatToParts(), so one function handles German input too. Other string-to-number cases are in converting a string to a double in TypeScript.
const compact = new Intl.NumberFormat("en-US", { notation: "compact", maximumFractionDigits: 1 });
for (const views of [950, 12_400, 1_250_000, 3_800_000_000]) {
console.log(views.toLocaleString("en-US").padStart(13), "->", compact.format(views));
}
console.log('Number("1,234.56"):', Number("1,234.56"));
function parseLocaleNumber(text: string, locale = "en-US"): number {
const parts = new Intl.NumberFormat(locale).formatToParts(12345.6);
const group = parts.find((p) => p.type === "group")?.value ?? ",";
const decimal = parts.find((p) => p.type === "decimal")?.value ?? ".";
return Number(text.replaceAll(group, "").replace(decimal, "."));
}
console.log("en-US:", parseLocaleNumber("1,234,567.89"));
console.log("de-DE:", parseLocaleNumber("1.234.567,89", "de-DE"));
Output:
950 -> 950
12,400 -> 12.4K
1,250,000 -> 1.3M
3,800,000,000 -> 3.8B
Number("1,234.56"): NaN
en-US: 1234567.89
de-DE: 1234567.89

NaN from a plain Number() call, and the locale-aware parser.Validate user input before parsing; checking if a string is a number in TypeScript covers that.
Which way to add commas in TypeScript should you use?
| Method | Best for | Watch out for |
|---|---|---|
toLocaleString("en-US") | One-off values, bigint | Omitting the locale |
Intl.NumberFormat | Tables, lists, fixed decimals | Default 3-digit rounding |
| Regex | Fixed-format exports | Decimals; split on . first |
notation: "compact" | Dashboards and labels | It drops precision |
I reach for Intl.NumberFormat in nearly every app and keep the regex for the rare case where the output must never change with the locale.
Want to keep going? These guides pair well with this one:
- Convert a string to a number in TypeScript
- Convert a number to a string with leading zeros
- Split a string by comma in TypeScript
- Format a number with commas in Python
Frequently asked questions
How do I format a number with commas in TypeScript?
Call n.toLocaleString("en-US") or new Intl.NumberFormat("en-US").format(n). Both return a string like “1,234,567”.
Why does toLocaleString() show periods instead of commas?
No locale was passed, so the runtime’s default locale was used. Pass "en-US" explicitly for comma grouping.
How do I keep two decimals and add commas?
Use Intl.NumberFormat with minimumFractionDigits: 2 and maximumFractionDigits: 2.
How do I remove commas from a number string?
Use Number(text.replaceAll(",", "")) for US input, or read the separators from formatToParts() for other locales.
Does toLocaleString() work with bigint?
Yes. BigInt values have their own toLocaleString(), so 36218604000000n prints as “36,218,604,000,000”.
Where are the Intl.NumberFormat options documented?
See the Intl.NumberFormat() constructor on MDN.
