anyamount API reference
Overview
anyamount is a tiny number formatter built entirely on the native Intl.NumberFormat browser API. One function, one options object, three modes — plus a helper for bare currency symbols. The 1.x API is stable: new options arrive in minors, breaking changes only in majors.
The browser already knows how to format numbers, money, and units in 200+ languages. anyamount just makes that API pleasant to use.
import { anyamount } from 'anyamount'
anyamount(1234567)
// "1.2M" — smart mode (default)
anyamount(1999, { mode: 'currency', currency: 'EUR' })
// "€1,999.00"
anyamount(3.2, { mode: 'unit', unit: 'gigabyte' })
// "3.2 GB"Install
npm install anyamount
# or
pnpm add anyamount
# or
yarn add anyamountOr take the whole family at once with npm install anyfamily.
anyamount()
The single entry point. Pass a number, optionally pass options.
anyamount(value)
anyamount(value, options?)
anyamount(1234567)
// runtime locale, smart mode
anyamount(9999, { locale: 'en' })
// "9,999" — below the compact cutoff
anyamount(1234567, { locale: 'en', style: 'long' })
// "1.2 million"
anyamount(1999.99, { mode: 'currency', currency: 'EUR', locale: 'en', digits: 0 })
// "€2,000"anyamountParts()
Same arguments as anyamount(), but returns the Intl.NumberFormat.formatToParts output unchanged — style the number apart from the currency symbol or unit, or rebuild the output your own way.
import { anyamountParts } from 'anyamount'
anyamountParts(1999, { mode: 'currency', currency: 'EUR', locale: 'en' })
// [
// { type: 'currency', value: '€' },
// { type: 'integer', value: '1' },
// { type: 'group', value: ',' },
// { type: 'integer', value: '999' },
// { type: 'decimal', value: '.' },
// { type: 'fraction', value: '00' },
// ]
// React: shrink the currency symbol
anyamountParts(price, { mode: 'currency', currency: 'EUR' }).map((p, i) =>
p.type === 'currency' ? <small key={i}>{p.value}</small> : p.value,
)Note: part values keep the original Intl characters — the space between number and unit can be U+00A0 or U+202F (no-break spaces) depending on locale and ICU version.
anyamountSymbol()
Resolves an ISO 4217 code to its localized symbol, with no number attached — for labels, currency pickers, and input affixes, where the amount is rendered separately (or not at all).
import { anyamountSymbol } from 'anyamount'
anyamountSymbol('USD', { locale: 'en' }) // "$"
anyamountSymbol('EUR', { locale: 'en' }) // "€"
anyamountSymbol('GBP', { locale: 'en' }) // "£"
anyamountSymbol('JPY', { locale: 'ja' }) // "¥"
anyamountSymbol('RUB', { locale: 'ru' }) // "₽"
anyamountSymbol('USD', { locale: 'en', display: 'code' }) // "USD"
anyamountSymbol('USD', { locale: 'en', display: 'name' }) // "US dollars"display defaults to 'narrowSymbol' — the bare symbol, never the disambiguated US$some locales prefer. Codes with no symbol in the locale's data come back as the code itself.
Note: a malformed code throws a RangeError straight from Intl — 'US' is not a currency. Formatting a full amount? Stay in currency mode with currencyDisplay; this is the escape hatch for when there is no amount.
Modes
The mode option picks the rendering strategy. Each mode reads only the options that apply to it — the rest are ignored.
smart (default)
Compact notation for big numbers, plain formatting for small ones. The cutoff is |value| >= 10000.
reads: locale, style, digits
currency
Money via the Intl.NumberFormat currency style. currency is required — any ISO 4217 code. Missing it throws a TypeError.
anyamount(1999, { mode: 'currency', currency: 'EUR', locale: 'en' })
// "€1,999.00"
anyamount(1999, { mode: 'currency', currency: 'RSD', locale: 'sr' })
// "1.999,00 RSD"
anyamount(1999, { mode: 'currency', currency: 'JPY', locale: 'ja' })
// "¥1,999" — JPY has no minor unit, Intl knows
anyamount(1999.99, { mode: 'currency', currency: 'EUR', locale: 'en', digits: 0 })
// "€2,000"currencyDisplay picks how the currency itself is spelled — symbol by default, opt into anything else.
anyamount(1999, { mode: 'currency', currency: 'USD', locale: 'en' })
// "$1,999.00" — 'symbol' (default)
anyamount(1999, { mode: 'currency', currency: 'USD', locale: 'en-CA', currencyDisplay: 'narrowSymbol' })
// "$1,999.00" — bare symbol, where the locale would print "US$"
anyamount(1999, { mode: 'currency', currency: 'USD', locale: 'en', currencyDisplay: 'code' })
// "USD 1,999.00"
anyamount(1999, { mode: 'currency', currency: 'USD', locale: 'en', currencyDisplay: 'name' })
// "1,999.00 US dollars"reads: locale, currency, currencyDisplay, digits
unit
Measurements via the Intl.NumberFormat unit style. unit is required — any sanctioned identifier, including compound -per- pairs. Missing it throws a TypeError.
anyamount(3.2, { mode: 'unit', unit: 'gigabyte', locale: 'en' })
// "3.2 GB"
anyamount(120, { mode: 'unit', unit: 'kilometer-per-hour', locale: 'en' })
// "120 km/h"
anyamount(3.2, { mode: 'unit', unit: 'gigabyte', locale: 'en', style: 'long' })
// "3.2 gigabytes"
anyamount(5, { mode: 'unit', unit: 'kilometer', locale: 'en', style: 'narrow' })
// "5km"reads: locale, unit, style, digits
Options
mode'smart' | 'currency' | 'unit'default: 'smart'Rendering strategy. Each mode reads only the options that apply to it.
localestring | string[]default: runtime localeAny valid BCP 47 locale tag, or a fallback array — 'en', 'en-US', 'zh-TW', ['sr-Latn-RS', 'en'].
currencystringCurrency mode only, required. Any ISO 4217 code — 'EUR', 'USD', 'JPY', 'RSD'.
currencyDisplay'symbol' | 'narrowSymbol' | 'code' | 'name'default: 'symbol'Currency mode only. How the currency is spelled: '$1,999.00', 'USD 1,999.00', or '1,999.00 US dollars'. 'narrowSymbol' keeps the bare '$' where a locale would print 'US$'.
unitUnitUnit mode only, required. A sanctioned unit identifier or a compound '<unit>-per-<unit>' pair. Typed as a union — your editor autocompletes it.
style'long' | 'short' | 'narrow'default: 'short'Smart and unit modes. Wording length: '1.2M' vs '1.2 million', '3.2 GB' vs '3.2 gigabytes'.
digitsnumberdefault: per modemaximumFractionDigits — a ceiling, not a fixed width: trailing zeros are not padded on, so digits: 2 renders 2.5, not 2.50. Defaults: smart — 2 plain / 1 compact, unit — 2, currency — the currency's own (which it keeps as a minimum).
Units
Intl supports a fixed, sanctioned list of unit identifiers (from ECMA-402), plus any <unit>-per-<unit> compound of them. anyamount ships the full list as a TypeScript union, so invalid units fail at compile time.
acre bit byte celsius centimeter day degree fahrenheit
fluid-ounce foot gallon gigabit gigabyte gram hectare hour
inch kilobit kilobyte kilogram kilometer liter megabit
megabyte meter microsecond mile mile-scandinavian milliliter
millimeter millisecond minute month nanosecond ounce percent
petabyte pound second stone terabit terabyte week yard year// compounds work too
anyamount(120, { mode: 'unit', unit: 'kilometer-per-hour' }) // "120 km/h"
anyamount(8.5, { mode: 'unit', unit: 'liter-per-kilometer' }) // "8.5 L/km"
anyamount(2, { mode: 'unit', unit: 'meter-per-second' }) // "2 m/s"Locales
Same calls in a few languages — no extra setup, no locale files.
// smart mode
anyamount(1234567, { locale: 'ru' }) // "1,2 млн"
anyamount(1234567, { locale: 'de' }) // "1,2 Mio."
anyamount(1234567, { locale: 'ja' }) // "123.5万"
// currency mode
anyamount(1999, { mode: 'currency', currency: 'USD', locale: 'de' })
// "1.999,00 $"
anyamount(1999, { mode: 'currency', currency: 'INR', locale: 'hi' })
// "₹1,999.00"
// unit mode
anyamount(120, { mode: 'unit', unit: 'kilometer-per-hour', locale: 'ru' })
// "120 км/ч"Pass any valid BCP 47 language tag — including regional variants like en-GB, zh-TW, or pt-BR. Locale is optional; when omitted, native Intl uses the runtime locale. Fallback arrays like ['sr-Latn-RS', 'en'] also work.
Output is pure — no clock reads, no environment sniffing — so server and client render identically. SSR-safe by construction.
Compatibility
anyamount uses Intl.NumberFormat with compact notation and unit support — widely available since 2020.
Limitations
A few things worth knowing before you ship:
No byte auto-scaling yet
anyamount(3200000000, { mode: 'unit', unit: 'byte' }) will not pick GB for you — pass the unit you want. Automatic scaling is planned for a future minor.
Output depends on the runtime's Intl data
anyamount delegates all formatting to native Intl. Exact output — separators, spacing, compact suffixes — may vary between Node versions, browsers, and OSes. Don't hardcode expected strings in tests; use pattern matching instead.
Sanctioned units only
Intl supports a fixed list of unit identifiers and -per- compounds of them. There is no way to format arbitrary custom units — that's an Intl constraint, not an anyamount one.
Deliberately small
One function, three modes, on purpose. No percent mode, no ranges, no parsing. anyamount follows semver — the 1.x API is stable, new options arrive in minors, breaking changes only in majors.