Bytes to human-readable size in JavaScript

const formatBytes = (n, i = 0) => n >= 1023.95 && i < 5 ? formatBytes(n / 1024, i + 1) : +n.toFixed(1) + ' ' + ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'][i];

formatBytes(123456789) returns '117.7 MiB' with the one-liner above. It divides by 1,024 until the number would print below 1024.0, then rounds to one decimal, and the unary + drops a trailing .0, so 1,048,576 bytes is '1 MiB'.

const formatBytes = (n, i = 0) => n >= 1023.95 && i < 5 ? formatBytes(n / 1024, i + 1) : +n.toFixed(1) + ' ' + ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'][i];

formatBytes(0);           // '0 B'
formatBytes(500);         // '500 B'
formatBytes(1536);        // '1.5 KiB'
formatBytes(123456789);   // '117.7 MiB'
formatBytes(4700000000);  // '4.4 GiB'

The tool below starts on 123456789 B and shows the exact values: 117.73756885528564453125 MiB and 123.456789 MB.

KiB or kB: the divisor and the label go together

A kilobyte (kB) is 1,000 bytes, by the SI prefix, and a kibibyte (KiB) is 1,024, a binary prefix from IEC 80000-13. Windows Explorer divides by 1,024 and still writes KB and MB; macOS Finder and drive makers divide by 1,000. Printing MB after dividing by 1,024 is how one file ends up with two sizes. This version does either, with the right label:

function formatBytes(bytes, { si = false, digits = 1 } = {}) {
  const k = si ? 1000 : 1024;
  const units = si ? ['B', 'kB', 'MB', 'GB', 'TB', 'PB'] : ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'];
  let i = 0;
  let value = bytes;
  // Compare the rounded value, so 1,048,575 bytes is 1 MiB and not 1024 KiB.
  while (i < units.length - 1 && Number(value.toFixed(digits)) >= k) {
    value /= k;
    i++;
  }
  return `${Number(value.toFixed(digits))} ${units[i]}`;
}

formatBytes(123456789);              // '117.7 MiB'
formatBytes(123456789, { si: true }); // '123.5 MB'
formatBytes(999999, { si: true });    // '1 MB'

The usual snippet has two bugs

const formatBytes = (n, i = Math.floor(Math.log(n) / Math.log(1024))) =>
  (n / 1024 ** i).toFixed(1) + ' ' + ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'][i];

formatBytes(0);        // 'NaN undefined'
formatBytes(1048575);  // '1024.0 KiB'

Math.log(0) is -Infinity, so zero bytes has no unit. And 1,048,575 bytes is 1023.999 KiB: the unit is picked before rounding, then toFixed(1) rounds up to 1024.0. The functions above test the rounded number instead; 1023.95 is where one decimal place turns into 1024.0.

Intl.NumberFormat labels, it doesn’t convert

new Intl.NumberFormat('en', { style: 'unit', unit: 'megabyte', maximumFractionDigits: 1 }).format(123456789 / 1e6);
// '123.5 MB'
new Intl.NumberFormat('fr', { style: 'unit', unit: 'megabyte', maximumFractionDigits: 1 }).format(123456789 / 1e6);
// '123,5 Mo'
new Intl.NumberFormat('en', { style: 'unit', unit: 'mebibyte' });
// RangeError: Invalid unit argument for Intl.NumberFormat() 'mebibyte'

You choose the unit and divide; Intl only writes the number and the localized label. Its byte units are the SI ones, byte and kilobyte through petabyte (Intl.supportedValuesOf('unit') lists them), so binary sizes need labels of your own. Two more surprises: unit: 'byte' prints '500 byte' unless you add unitDisplay: 'long' ('500 bytes'), and notation: 'compact' turns 123,456,789 bytes into '123M byte'.

Packages

pretty-bytes 7.0.0 rounds to three significant digits: prettyBytes(123456789) is '123 MB', { binary: true } gives '118 MiB', and 1,048,575 bytes comes out '1020 KiB'.

Try it in the Data Size Converter

A number with a unit: 1.5 GB, 700 MiB, 8 Gb. Typed all lowercase, mb or kib reads as bytes; mixed, as in Mb, it reads as bits.

123456789 B is 123,456,789 bytes

UnitValueIn words
Bytes, decimal (SI) — each step ×1,000
B123,456,789bytes
kB123,456.789kilobytes
MB123.456789megabytes
GB0.123456789gigabytes
TB0.000123456789terabytes
PB0.000000123456789petabytes
Bytes, binary (IEC) — each step ×1,024
KiB120,563.2705078125kibibytes
MiB117.73756885528564453125mebibytes
GiB0.114978094585239887gibibytes
TiB0.000112283295493398327tebibytes
PiB0.000000109651655755271804pebibytes
Bits — 8 to a byte
bit987,654,312bits
Kb987,654.312kilobits
Mb987.654312megabits
Gb0.987654312gigabits
Tb0.000987654312terabits
Pb0.000000987654312petabits

SI units count by thousands and IEC units by 1,024s: 1 kB is 1,000 bytes, while 1 KiB is 1,024 — 2.4% more. This page reads KB as 1,000 bytes; some systems mean 1,024.

Runs in your browser. Nothing you enter is sent anywhere.