This comparison evaluates six JavaScript libraries used for formatting numbers, currency, and performing mathematical operations. It covers dedicated formatting tools like accounting-js and numeral, visualization-focused utilities like d3-format, and comprehensive math engines like mathjs. The goal is to help developers select the right tool for financial displays, data dashboards, or scientific calculations without adding unnecessary bloat.
When building financial dashboards, data visualizations, or user-facing reports, presenting numbers clearly is critical. The JavaScript ecosystem offers several tools for this, ranging from dedicated formatters to full math engines. Let's compare how accounting-js, d3-format, format-number, mathjs, numeral, and sprintf-js handle common tasks.
Formatting raw numbers with thousand separators and decimal precision is the most common task.
accounting-js focuses on financial data but handles basic numbers well.
import accounting from 'accounting-js';
accounting.formatNumber(1000000, 2, '.', ',');
// "1.000.000,00" (depends on locale settings)
d3-format uses specifier strings similar to Python.
import { format } from 'd3-format';
const fmt = format(',.2f');
fmt(1000000);
// "1,000,000.00"
format-number is a minimal utility for adding separators.
import formatNumber from 'format-number';
const fmt = formatNumber({ round: 2, thousand: ',' });
fmt(1000000);
// "1,000,000.00"
mathjs provides formatting as part of its math suite.
import * as math from 'mathjs';
math.format(1000000, { precision: 3 });
// "1.00e+6" (default is often scientific for large numbers)
numeral uses a token-based system for formatting.
import numeral from 'numeral';
numeral(1000000).format('0,0.00');
// "1,000,000.00"
sprintf-js relies on C-style format specifiers.
import { sprintf } from 'sprintf-js';
sprintf('%0,.2f', 1000000);
// "1,000,000.00" (if locale supports, otherwise basic)
Displaying money values requires currency symbols and specific decimal rules.
accounting-js is built specifically for this use case.
accounting.formatMoney(50000, { symbol: '$', precision: 2 });
// "$50,000.00"
d3-format requires manual symbol addition or locale definitions.
const fmt = format('$,.2f');
fmt(50000);
// "$50,000.00"
format-number does not support currency symbols natively.
// Not supported directly, requires manual concatenation
'$' + fmt(50000);
// "$50,000.00"
mathjs does not specialize in currency formatting.
// No dedicated currency method, use basic format
'$' + math.format(50000, { precision: 2 });
// "$50000"
numeral has dedicated currency tokens.
numeral(50000).format('$0,0.00');
// "$50,000.00"
sprintf-js treats currency as a string pattern.
sprintf('$%0,.2f', 50000);
// "$50,000.00"
For data viz, large numbers often need abbreviations (1k, 1M) or scientific notation.
accounting-js does not support compact notation.
// No built-in support for 1k/1M styles
d3-format excels here with SI prefixes.
const fmt = format('.2s');
fmt(1200000);
// "1.2M"
format-number is too simple for this feature.
// Not supported
mathjs supports scientific notation output.
math.format(1200000, { notation: 'exponential' });
// "1.2e+6"
numeral supports abbreviations via tokens.
numeral(1200000).format('0.0a');
// "1.2m"
sprintf-js supports scientific notation via specifiers.
sprintf('%.2e', 1200000);
// "1.20e+6"
You need to display prices like $19.99 reliably across the site.
accounting-js (legacy) or Intl.NumberFormat (native)numeral works but is older.You are labeling axes with values like 1.2M or 500k.
d3-formatYou need to parse expressions and format results precisely.
mathjsYou are updating an old codebase that already uses a formatter.
numeral or accounting-js)Intl.| Package | Primary Use | Currency | Compact Notation | Math Ops | Status |
|---|---|---|---|---|---|
accounting-js | Finance | β | β | β | Legacy |
d3-format | Visualization | β (Manual) | β | β | Active |
format-number | Basic | β | β | β | Stable |
mathjs | Math Engine | β | β (Scientific) | β | Active |
numeral | General | β | β | β | Legacy |
sprintf-js | String Fmt | β (Manual) | β (Scientific) | β | Stable |
For new projects, the browser's native Intl.NumberFormat is often the best choice β it requires no dependencies and handles locales perfectly. However, if you need a library:
d3-format for data visualization and scientific notation.mathjs only if you need complex math calculations alongside formatting.sprintf-js for fixed-width string generation or logging.accounting-js and numeral for new work; they are largely unmaintained compared to modern standards.These tools help keep your number display consistent β which builds trust with your users.
Choose accounting-js if you are maintaining a legacy project that already depends on it for simple currency formatting. It is lightweight and easy to use for basic financial displays. However, avoid it for new projects as it is no longer actively maintained and lacks modern locale support.
Choose d3-format if you are building data visualizations or need scientific notation and SI prefixes like 1k or 1M. It integrates seamlessly with D3 charts and offers precise control over number specifiers. It is the industry standard for dashboard and graph labeling.
Choose format-number if you need a extremely lightweight solution for adding thousand separators without extra features. It is suitable for simple use cases where you do not need currency symbols or complex locale handling. Do not use it if you require internationalization or advanced formatting options.
Choose mathjs if your application requires complex mathematical calculations, expression parsing, or matrix operations alongside formatting. It is a full math engine, so it is overkill if you only need to format numbers. Use it when calculation logic and display formatting must live in the same dependency.
Choose numeral only if you are working on an existing codebase that already relies on its specific token syntax. It offers a familiar API for currency and percentage formatting. For new development, prefer native browser APIs or d3-format because numeral development has largely stalled.
Choose sprintf-js when you need C-style printf formatting for generating fixed-width strings or logs. It is ideal for scenarios where you need to format numbers and strings together in a specific pattern. It is not designed for currency localization but excels at structural string formatting.
accounting-js is a tiny JavaScript library for number, money and currency parsing/formatting. It's lightweight, fully localizable, has no dependencies, and works great client-side or server-side. Use standalone or as a nodeJS/npm and AMD/requireJS module.
npm install accounting-js
import { formatNumber } from 'accounting-js';
// Default usage
formatNumber(5318008);
// β¨ 5,318,008
// Custom format
formatNumber(9876543.21, { precision: 3, thousand: " " });
// β¨ 9 876 543.210
import { formatMoney } from 'accounting-js';
// Default usage
formatMoney(12345678);
// β¨ $12,345,678.00
// European formatting (custom symbol and separators)
formatMoney(4999.99, { symbol: "β¬", precision: 2, thousand: ".", decimal: "," });
// β¨ β¬4.999,99
import { unformat } from 'accounting-js';
unformat('Β£ 12,345,678.90 GBP');
// β¨ 12345678.9
// Native toFixed has rounding issues
(0.615).toFixed(2);
// β¨ '0.61'
// With accounting-js
toFixed(0.615, 2);
// β¨ '0.62'
Copyright (c) 2016-present Stanislav Lesnikov, MIT License
Copyright (c) 2014 Open Exchange Rates, MIT License