numberparrot

Parse localized numbers and currency strings in JavaScript

parseFloat("1.234,56") returns 1.234. numberparrot returns 1234.56. It is the missing parser for Intl.NumberFormat: zero dependencies, every locale.

Pico, the numberparrot mascot: a friendly green parrot that repeats numbers in any language

Playground: parseFloat vs numberparrot

parseFloat(text)1.234wrong number
Number(text)NaNwrong number
parse(text, locale)1234.56locale pt-BR: decimal ",", group "."
parseCurrency(text, locale)1234.56no currency in the input
detect(text)1234.56confidence 0.95. Both "." and "," appear; the last one, ",", is the decimal separator
round trip with Intl1.234,56Intl.NumberFormat("pt-BR").format(result)

Features

Any locale

Separators, digits and symbols come from Intl.NumberFormat for every locale your runtime knows.

Currency

Symbols and ISO codes on either side: R$ 1.234,56, 1 234,56 €, CHF 1'234.50.

Any digits

Arabic-Indic, Persian, Devanagari, Bengali, Thai, full width and every Unicode digit.

Accounting negatives

(1.234,56), trailing minus and every minus sign look alike.

Detection

detect() finds the decimal separator and flags real ambiguity like 1,234.

Money safety

toMinorUnits gives exact integer cents: 0,29 is 29, never 28.999999999999996.

Form input

normalizeInput() cleans fields while typing and keeps partial values like 1.234, valid.

parseFloat vs numberparrot, side by side

Animated comparison: 1.234.567,89 in pt-BR, 1'234'567.89 in de-CH, 12,34,567.89 in en-IN and Arabic-Indic digits in ar-EG all parse to 1234567.89 with numberparrot, while parseFloat returns 1.234, 1, 12 and NaN

Install

Terminal
npm install numberparrot
example.ts
import { parse, parseCurrency, detect, normalizeInput } from "numberparrot";

parse("1.234,56", "pt-BR");             // 1234.56
parse("1'234.56", "de-CH");             // 1234.56
parse("12,34,567.89", "en-IN");         // 1234567.89
parse("١٬٢٣٤٫٥٦", "ar-EG");             // 1234.56
parse("(1.234,56)", "de-DE");           // -1234.56
parse("15%", "en-US");                  // 0.15

parseCurrency("R$ 1.234,56", "pt-BR");  // { amount: 1234.56, currency: "BRL", ... }
parseCurrency("0,29", "pt-BR", { toMinorUnits: true }).amount; // 29

detect("1,234");                        // { ambiguous: true, alternatives: [1234, 1.234], ... }
normalizeInput("1.234,", "pt-BR");      // { text: "1.234,", value: 1234, valid: true, complete: false }

Works in Node.js 18+, Deno, Bun and every modern browser. ESM and CommonJS builds, TypeScript types, about 6 kB gzipped for the whole library. The full API reference is in the README.

Guides