How to format numbers as 1K, 1M, 1B

Use compact notation to display large numbers in a space-efficient, readable format

Introduction

Large numbers take up significant space and are difficult to scan quickly. A number like 1,500,000 requires seven digits plus formatting, while 1.5M conveys the same magnitude in three characters. This compact representation is common in social media follower counts, video view counts, dashboard metrics, and file sizes.

JavaScript provides built-in support for compact number formatting through the Intl.NumberFormat API. This API handles the conversion automatically and adapts the formatting to different languages and regions, ensuring your numbers display correctly for all users.

Why large numbers need compact formatting

When you display large numbers in user interfaces, two problems emerge. First, the numbers consume horizontal space. A counter showing 1,234,567 views requires more room than one showing 1.2M views. Second, users process compact numbers faster. The human brain recognizes 1.5M as one and a half million more quickly than parsing 1,500,000.

Compact notation solves both problems by replacing trailing zeros with magnitude indicators. Instead of showing all digits, it shows only the significant figures followed by a letter that represents the magnitude. This approach balances precision with readability.

Different contexts require different levels of precision. A social media follower count rarely needs exact numbers. Showing 1.2M followers instead of 1,234,567 provides sufficient information. A financial dashboard might need more precision, showing 1.23M instead of 1.2M. The Intl API lets you control this precision while maintaining compact formatting.

Using compact notation in JavaScript

The notation option in Intl.NumberFormat controls how numbers are represented. Setting it to "compact" enables compact formatting.

const formatter = new Intl.NumberFormat("en-US", {
  notation: "compact"
});

console.log(formatter.format(1500));
// Output: "1.5K"

console.log(formatter.format(1500000));
// Output: "1.5M"

console.log(formatter.format(1500000000));
// Output: "1.5B"

The formatter automatically chooses the appropriate magnitude indicator based on the number's size. Thousands become K, millions become M, and billions become B. The formatter also reduces the number to a readable figure, showing 1.5K instead of 1.5 thousand.

You do not need to write logic to determine when to use K, M, or B. The Intl API handles this decision based on the number's magnitude.

How compact notation formats different magnitudes

Compact notation applies different formatting at different scales. Understanding these thresholds helps you predict how your numbers will display.

const formatter = new Intl.NumberFormat("en-US", {
  notation: "compact"
});

console.log(formatter.format(500));
// Output: "500"

console.log(formatter.format(1000));
// Output: "1K"

console.log(formatter.format(1500));
// Output: "1.5K"

console.log(formatter.format(999000));
// Output: "999K"

console.log(formatter.format(1000000));
// Output: "1M"

console.log(formatter.format(1500000));
// Output: "1.5M"

console.log(formatter.format(1000000000));
// Output: "1B"

console.log(formatter.format(1000000000000));
// Output: "1T"

Numbers below one thousand display without compaction. Once a number reaches one thousand, it switches to K notation. The same pattern continues for millions, billions, and trillions.

The formatter rounds numbers to fit the compact representation. A number like 1,234,567 becomes 1.2M by default. The next lesson will cover how to control the number of decimal places shown in compact notation.

Choosing between short and long display

Compact notation offers two display styles. The short style uses letters like K, M, and B. The long style spells out the magnitude as a word.

const shortFormatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  compactDisplay: "short"
});

console.log(shortFormatter.format(1500));
// Output: "1.5K"

console.log(shortFormatter.format(1500000));
// Output: "1.5M"

const longFormatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  compactDisplay: "long"
});

console.log(longFormatter.format(1500));
// Output: "1.5 thousand"

console.log(longFormatter.format(1500000));
// Output: "1.5 million"

The compactDisplay option controls this behavior. It accepts two values: "short" and "long". If you omit this option, it defaults to "short".

Short display works well when space is limited. Dashboard cards, mobile interfaces, and data tables benefit from the brevity of K, M, and B. Long display works better when clarity matters more than space. Educational content, financial reports, and accessibility-focused interfaces benefit from spelling out the magnitude.

How compact notation works in different languages

Compact notation adapts to the language and region specified in the locale. Different languages use different letters, words, and formatting conventions for magnitude indicators.

const enFormatter = new Intl.NumberFormat("en-US", {
  notation: "compact"
});

console.log(enFormatter.format(1500000));
// Output: "1.5M"

const frFormatter = new Intl.NumberFormat("fr-FR", {
  notation: "compact"
});

console.log(frFormatter.format(1500000));
// Output: "1,5 M"

const deFormatter = new Intl.NumberFormat("de-DE", {
  notation: "compact"
});

console.log(deFormatter.format(1500000));
// Output: "1,5 Mio."

const jaFormatter = new Intl.NumberFormat("ja-JP", {
  notation: "compact"
});

console.log(jaFormatter.format(15000000));
// Output: "1500万"

French uses M with a space before it. German uses Mio. as an abbreviation for Million. Japanese uses a completely different number system with 万 representing ten thousand.

These differences happen automatically based on the locale. You do not need to write locale-specific code to handle different magnitude indicators. Pass the user's language preference to the formatter, and it produces the correct output for that language.

Long display also adapts to each language.

const enFormatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  compactDisplay: "long"
});

console.log(enFormatter.format(1500000));
// Output: "1.5 million"

const frFormatter = new Intl.NumberFormat("fr-FR", {
  notation: "compact",
  compactDisplay: "long"
});

console.log(frFormatter.format(1500000));
// Output: "1,5 million"

const deFormatter = new Intl.NumberFormat("de-DE", {
  notation: "compact",
  compactDisplay: "long"
});

console.log(deFormatter.format(1500000));
// Output: "1,5 Millionen"

German uses Millionen for the plural form of million. French uses million without an s. The Intl API handles these linguistic variations for you.

When small numbers are not compacted

Numbers below the compact threshold display normally. This threshold varies by locale, but typically starts at one thousand in most Western languages.

const formatter = new Intl.NumberFormat("en-US", {
  notation: "compact"
});

console.log(formatter.format(10));
// Output: "10"

console.log(formatter.format(100));
// Output: "100"

console.log(formatter.format(999));
// Output: "999"

console.log(formatter.format(1000));
// Output: "1K"

This behavior prevents awkward formatting for small numbers. Showing 500 as 500 is clearer than showing it as 0.5K. The formatter only applies compact notation when it improves readability.

The threshold is not always one thousand. Some languages, like Japanese, use different number grouping systems. Japanese groups by ten thousand, so compact notation might start at a different threshold.

const jaFormatter = new Intl.NumberFormat("ja-JP", {
  notation: "compact"
});

console.log(jaFormatter.format(9999));
// Output: "9999"

console.log(jaFormatter.format(10000));
// Output: "1万"

The Intl API handles these locale-specific thresholds automatically.

Combining compact notation with other formatting options

Compact notation works with other number formatting options. You can control decimal places, grouping separators, and rounding while using compact notation.

const formatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  maximumFractionDigits: 1
});

console.log(formatter.format(1234567));
// Output: "1.2M"

const preciseFormatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  maximumFractionDigits: 2
});

console.log(preciseFormatter.format(1234567));
// Output: "1.23M"

const noDecimalsFormatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  maximumFractionDigits: 0
});

console.log(noDecimalsFormatter.format(1234567));
// Output: "1M"

The maximumFractionDigits option controls how many decimal places appear after the whole number. Setting it to 0 removes all decimal places, making the number even more compact.

You can also combine compact notation with minimum digit options to ensure consistent formatting across a range of numbers.

const formatter = new Intl.NumberFormat("en-US", {
  notation: "compact",
  minimumFractionDigits: 1,
  maximumFractionDigits: 1
});

console.log(formatter.format(1000));
// Output: "1.0K"

console.log(formatter.format(1500));
// Output: "1.5K"

console.log(formatter.format(2000));
// Output: "2.0K"

This approach ensures all numbers show one decimal place, which helps maintain visual consistency in tables and charts.

When to use compact notation

Compact notation works best when space is limited or when exact precision is not critical. Social media counters, dashboard metrics, and summary statistics are ideal use cases. Users do not need to know that a video has exactly 1,234,567 views. Knowing it has 1.2M views provides sufficient information.

Do not use compact notation when exact numbers matter. Financial transactions, scientific measurements, and legal documents require full precision. A bank balance should show $1,234.56, not $1.2K. An invoice should show $1,500.00, not $1.5K.

Consider your audience and context. Data analysts might prefer seeing full numbers to understand exact values. General consumers often prefer compact numbers because they process them faster. Some interfaces offer both options, showing compact numbers by default with a way to reveal exact numbers on demand.

Compact notation also works well for file sizes, though the implementation differs slightly. File sizes typically use powers of 1024 rather than 1000, resulting in kibibytes and mebibytes rather than kilobytes and megabytes. The Intl API does not handle binary units, so file size formatting requires custom logic or a dedicated library.