Skip to content
Carl Victor Fontanos
Carl Victor Fontanos

Carl Victor Fontanos

Software Engineer

I build web applications and share what I learn along the way.

© 2026

Format Currencies and "1.2K" Counts Without a Library

C
Carlo Fontanos
· 2 min read

Money formatting is where hand-rolled code goes to embarrass itself: '$' + price.toFixed(2) works right up until you need euros, or thousands separators, or a locale where the symbol goes after the number. The browser has a complete solution built in.

Currency

const usd = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
usd.format(1234.5);      // "$1,234.50"

const eur = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' });
eur.format(1234.5);      // "1.234,50 €"

Separators, symbol placement, decimal conventions - all handled per locale. Pass navigator.language as the locale and prices render the way each visitor expects, while the currency itself stays whatever your store charges in.

Compact notation: the "12.5K views" formatter

const compact = new Intl.NumberFormat('en', {
    notation: 'compact',
    maximumFractionDigits: 1,
});

compact.format(12500);      // "12.5K"
compact.format(3400000);    // "3.4M"

Every social-style counter you've ever seen, one option. Localized too - German gives "12.500" vs "12,5 Tsd." depending on settings.

Percent and units

new Intl.NumberFormat('en', { style: 'percent', maximumFractionDigits: 1 })
    .format(0.847);          // "84.7%"  (note: input is the fraction!)

new Intl.NumberFormat('en', { style: 'unit', unit: 'megabyte' })
    .format(245);            // "245 MB"

new Intl.NumberFormat('en', { style: 'unit', unit: 'kilometer-per-hour' })
    .format(88);             // "88 km/h"

The percent style multiplying by 100 for you is the classic first-use surprise: format(84.7) prints "8,470%".

Performance note that actually matters

Formatter construction is heavyweight; format() calls are cheap. In a list of 500 prices, create one formatter outside the loop. I keep a memoized helper around:

const formatters = {};
function money(amount, currency = 'USD', locale = navigator.language) {
    const key = locale + currency;
    formatters[key] ??= new Intl.NumberFormat(locale, { style: 'currency', currency });
    return formatters[key].format(amount);
}

Same rule as Intl.RelativeTimeFormat for timestamps: build once, format often.

Support is universal, including Node. Between this, RelativeTimeFormat and Intl.ListFormat ("a, b, and c"), the days of shipping a formatting library to the client are over for most apps.

C
Written by Carlo Fontanos

Full-stack web developer sharing practical tutorials and building tools that ship.

Got something on your mind?

My inbox is open - no forms disappearing into the void here.

  • Just say hello Found a tutorial useful? Spotted a mistake? Tell me.
  • Hire me for a project Have something custom in mind? Let's talk scope and timelines.
  • Product support Bought something here? I'll help you get it running.

I usually reply within 1-2 business days.

Message sent!

Your details are only used to reply to you.

Keep reading