Intermediate · Modules, errors, JSON and dates · topic 30 of 61 · 20 min
Formatting numbers, money and text with Intl
Explanation
Why not format by hand?
Formatting looks easy until you meet real users. India groups digits as 12,34,567 (lakhs and crores) while the US writes 1,234,567. Germany writes 1.234.567,50. Some languages have several plural forms. Writing all of this yourself is slow and full of bugs. The Intl object, built into every modern browser and Node.js, already knows these rules.
Locales
A locale is a code for a language and region: 'en-IN' (English, India), 'hi-IN' (Hindi, India), 'en-US', 'de-DE'. Intl uses it to choose the right format.
Intl.NumberFormat
const inr = new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR' });
console.log(inr.format(1234567.5)); // '₹12,34,567.50'
console.log(new Intl.NumberFormat('en-IN').format(123456)); // '1,23,456'
console.log(new Intl.NumberFormat('en-US').format(123456)); // '123,456'
console.log(new Intl.NumberFormat('en-IN', { notation: 'compact' }).format(1500000)); // '15L'
console.log(new Intl.NumberFormat('en-IN', { style: 'percent' }).format(0.18)); // '18%'Create the formatter once and reuse it; creating a new NumberFormat for every row of a big table is slow.
Plurals and relative times
const rules = new Intl.PluralRules('en');
const word = (n) => (rules.select(n) === 'one' ? 'ticket' : 'tickets');
console.log(`1 ${word(1)}, 3 ${word(3)}`); // 1 ticket, 3 tickets
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
console.log(rtf.format(-1, 'day')); // 'yesterday'
console.log(rtf.format(3, 'hour')); // 'in 3 hours'Sorting text properly: Intl.Collator
The default sort compares character codes, so capital letters come before small letters and accented letters go to the end. A collator compares the way people expect in a language.
const names = ['Zoya', 'arjun', 'Émile'];
console.log([...names].sort()); // ['Zoya', 'arjun', 'Émile']
console.log([...names].sort(new Intl.Collator('en').compare)); // ['arjun', 'Émile', 'Zoya']
console.log('a'.localeCompare('B', 'en')); // -1 (a comes before B)Quick helpers: toLocaleString
Numbers and Dates have toLocaleString(locale, options), a shortcut that uses Intl underneath: (1234567).toLocaleString('en-IN') gives '12,34,567'. Fine for one-off use; reuse a formatter object in loops.
Dates in Indian languages
The same Intl.DateTimeFormat you met in the last topic works for Indian languages too. With the locale 'hi-IN' the month names come out in Hindi, and with 'ta-IN' in Tamil. You do not need a translation table for month or weekday names; the browser or Node.js already has them. Pass the user's preferred locale (for example from a settings page) into one helper function and use it everywhere, so a single change switches the whole app.
const when = new Date(Date.UTC(2026, 7, 15, 4, 30));
const opts = { timeZone: 'Asia/Kolkata', day: 'numeric', month: 'long', year: 'numeric' };
console.log(new Intl.DateTimeFormat('en-IN', opts).format(when)); // '15 August 2026'
console.log(new Intl.DateTimeFormat('hi-IN', opts).format(when)); // the same date with the month name in HindiNeed help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Formatting numbers, money and text with Intl · 1/6
In this lesson you will format numbers, money and text correctly for any region with Intl.
Prefer a video by a teacher? Find free videos on “javascript Intl NumberFormat currency INR locale formatting” on YouTube ↗
In real life: A mutual fund dashboard
An investment app shows portfolio values to Indian users in lakhs and crores and to NRI users abroad in their own format. The same number goes through a formatter chosen by the user's locale setting.
const value = 2575000;
const show = (locale, currency) =>
new Intl.NumberFormat(locale, { style: 'currency', currency, maximumFractionDigits: 0 }).format(value);
console.log(show('en-IN', 'INR')); // ₹25,75,000
console.log(show('en-US', 'INR')); // ₹2,575,000Practice (0/3 done)
Write indianNumber(n) that returns n formatted with Indian digit grouping, using Intl.NumberFormat("en-IN"). indianNumber(1234567) returns "12,34,567".
Write sortNames(names) that returns a NEW array sorted alphabetically the way people expect, ignoring upper/lower case, using Intl.Collator("en").compare.
Write ticketsLabel(n) that returns "1 ticket" or "<n> tickets" using Intl.PluralRules("en").
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- JSON: data in and outModules, errors, JSON and dates · same module
- Error handling: try, catch, finally and throwModules, errors, JSON and dates · same module
- Strings in depthFrontend Web Development · JavaScript in depth
- Numbers: from one to one croreSpoken English: Zero to Fluent · Numbers, time and money
- Data types, naming and good habitsSQL and Databases · Schema design and normalisation
- Tricky sounds: th, v and w, z, and moreSpoken English: Zero to Fluent · Clear pronunciation and listening
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What does new Intl.NumberFormat('en-IN').format(1500000) give?
Answer: 15,00,000
en-IN groups as lakhs: 15,00,000.
What is a locale?
Answer: A language and region code like en-IN
Locales tell Intl which language and regional rules to use.
Where should "₹1,499.00" be used?
Answer: Shown to the user
Formatted strings are for display only.
Why use Intl.Collator to sort names?
Answer: It sorts as people expect, handling case and accents
Default sort compares character codes, which puts all capitals first.
Which gives the last character of the string text?Related
Answer: text.at(-1)
at(-1) counts from the end. text[-1] is undefined, there is no last() method, and slice(0, 1) gives the first character.
From Strings in depth
Two Date objects for the same moment: a === b is…Related
One crore is equal to...Related
Answer: ten million
1 crore = 1,00,00,000 = 10,000,000 = ten million.
What is the safest way to store ₹199.99 for calculations?Related
Answer: 19999 paise as a whole number
Whole numbers are exact, so store the smallest unit.
From Numbers and Math
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- This is the last topic of “Modules, errors, JSON and dates”. The module exam comes next.
- Module 6 exam: Modules, errors, JSON and dates · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Map, Set, iterators, generators and regular expressions. 61 topics left in the course before the final exam.