Convert a String with a Comma to a Number in JavaScript
Half the world writes decimals with a comma. JavaScript only understands a dot. Here is why the usual fixes break and how to convert comma strings reliably.
The problem
A user in Brazil, Germany or France types 1.234,56. JavaScript reads it like this:
parseFloat("1.234,56"); // 1.234 (stops at the second ".")
Number("1.234,56"); // NaN
parseFloat("1,5"); // 1 (stops at the ",")Why replace(",", ".") is not enough
The most common answer online is to swap the comma for a dot. It works for "1,5" and breaks for everything else:
| Input | Meaning | Number(s.replace(",", ".")) |
|---|---|---|
1,5 | 1.5 (de-DE) | 1.5 |
1.234,56 | 1234.56 (pt-BR) | NaN |
1,234 | 1234 (en-US) | 1.234 |
1 234,56 | 1234.56 (fr-FR) | NaN |
R$ 10,00 | 10 (pt-BR) | NaN |
Removing every dot first (s.replace(/\./g, "").replace(",", ".")) fixes Brazilian input and silently corrupts English input, where the dot is the decimal separator. There is no character swap that is right for every locale, because the meaning of . and , depends on who wrote the number.
The fix: parse with the locale
numberparrot reads the decimal and group separators for the locale from Intl.NumberFormat, so it parses exactly what the locale writes, and returns NaN for anything else instead of guessing:
import { parse } from "numberparrot";
parse("1,5", "de-DE"); // 1.5
parse("1.234,56", "pt-BR"); // 1234.56
parse("1 234,56", "fr-FR"); // 1234.56 (any kind of space)
parse("R$ 10,00", "pt-BR"); // 10
parse("1,234", "en-US"); // 1234
parse("1.234,56", "en-US"); // NaN, not an en-US numberWhen you do not know the locale
For CSV files or pasted values, detect() works out the decimal separator from the string itself and tells you when it cannot be sure:
import { detect } from "numberparrot";
detect("1.234,56").value; // 1234.56, confidence 0.95
detect("1,5").value; // 1.5
detect("1,234"); // ambiguous: true, alternatives [1234, 1.234]In a form field
import { createParser } from "numberparrot";
const brl = createParser(navigator.language); // for example "pt-BR"
input.addEventListener("change", () => {
const value = brl.parse(input.value);
input.setCustomValidity(Number.isNaN(value) ? "Please enter a number" : "");
});Install
npm install numberparrotZero dependencies, ESM and CommonJS, TypeScript types included. Works in Node.js 18+, Deno, Bun and browsers. Try it in the playground.