SnippetJavaScript

Format bytes as KB/MB/GB

Turns a raw byte count into a readable KB/MB/GB string using 1024-based units — the OS convention for file sizes, not 1000-based SI.

Last updated

Snippetjavascript
function formatBytes(bytes, decimals = 2) {
  if (bytes === 0) return "0 B";
  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB", "TB", "PB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  const value = bytes / Math.pow(k, i);
  return `${value.toFixed(decimals)} ${sizes[i]}`;
}

// formatBytes(1536) -> "1.50 KB"

How it works

The unit index i comes from Math.log(bytes) / Math.log(1024) floored — that's just "how many times does 1024 divide into this number" without a loop. k = 1024 is a deliberate choice: file managers and OSes report sizes in binary units (a 1 MB file is 1,048,576 bytes on disk), even though drive manufacturers market capacity in 1000-based SI units. If you're matching a spec that wants SI, swap k to 1000 and relabel as KB/MB with no other change.

toFixed(decimals) is applied uniformly, including to plain bytes, so formatBytes(523) reads "523.00 B" rather than a special-cased whole number — consistent formatting beats a prettier edge case here.

Edge cases to know

  • bytes === 0 is special-cased because Math.log(0) is -Infinity, which would otherwise send the unit index out of bounds.
  • Negative byte counts aren't guarded against — Math.log of a negative number is NaN, so validate upstream if the value could come from a subtraction.
  • The sizes array tops out at PB; anything larger falls off the end and prints undefined — extend the array if you're working with exabyte-scale numbers.

Related in Snippets