Skip to main content

How to Convert Bytes to KB, MB, GB, or TB in JavaScript

When dealing with file sizes, network usage, or disk space, you often start with a raw number of bytes. To make this number understandable to humans, you need to convert it into a larger unit like kilobytes (KB), megabytes (MB), or gigabytes (GB).

This guide will teach you how to create a single, powerful function to format bytes into a human-readable string. You will learn the critical difference between decimal (base-1000) and binary (base-1024) units and see how to handle both scenarios cleanly.

Core Concept: Decimal (KB) vs. Binary (KiB)

Before writing any code, it's crucial to understand the two standards for file sizes:

  • Decimal (Base-1000): This is the standard used by hard drive manufacturers and for networking speeds. 1 KB = 1000 bytes, 1 MB = 1000 KB. The units are KB, MB, GB, etc.
  • Binary (Base-1024): This is the standard traditionally used by operating systems (like Windows) to report file sizes. 1 KiB = 1024 bytes, 1 MiB = 1024 KiB. The units are KiB, MiB, GiB (kibibyte, mebibyte, gibibyte).

Confusion between these two standards is common (e.g., a hard drive advertised as 1 TB appears as ~931 GiB in Windows). A robust function should be able to handle both.

The Modern Solution: A Reusable Formatting Function

This single function can handle both decimal and binary conversions, making it a flexible and powerful utility.

/**
* Formats bytes into a human-readable string (e.g., 1.23 KB).
*
* @param {number} bytes The number of bytes.
* @param {object} [options] Optional configuration.
* @param {number} [options.decimals=2] The number of decimal places to include.
* @param {boolean} [options.binary=false] If true, uses binary units (KiB, MiB).
* @returns {string} The formatted string.
*/
function formatBytes(bytes, options = {}) {
const { decimals = 2, binary = false } = options;

if (!Number.isFinite(bytes) || bytes === 0) {
return '0 Bytes';
}

const base = binary ? 1024 : 1000;
const sizes = binary
? ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']
: ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];

const i = Math.floor(Math.log(bytes) / Math.log(base));

const formattedSize = parseFloat(
(bytes / Math.pow(base, i)).toFixed(decimals < 0 ? 0 : decimals)
);

return `${formattedSize} ${sizes[i]}`;
}

Now, you can use this function to get the format you need.

const fileSize = 1234567; // approx 1.2 MB

// Example 1: Decimal (KB, MB) - Default
console.log(formatBytes(fileSize));
// Output: "1.23 MB"

// Example 2: Binary (KiB, MiB)
console.log(formatBytes(fileSize, { binary: true }));
// Output: "1.18 MiB"

// Example 3: With more decimal places
console.log(formatBytes(fileSize, { decimals: 4 }));
// Output: "1.2346 MB"

How the Function Works

  • Base and Sizes: The function first determines the base (1000 or 1024) and the corresponding sizes array based on the binary option.
  • Logarithmic Calculation: The line const i = Math.floor(Math.log(bytes) / Math.log(base)); is the mathematical core. It uses logarithms to efficiently calculate how many times you can divide the bytes by the base. The result, i, is the correct index for our sizes array. For example, for 1.2 MB, i will be 2, which corresponds to "MB" in the array.
  • Formatting: (bytes / Math.pow(base, i)) divides the original byte count by the correct power of the base (e.g., 1000^2 for MB).
  • .toFixed() rounds the result to the desired number of decimal places, and parseFloat() removes any trailing zeros that .toFixed() might add.

An Alternative for Production: Using a Library (like filesize)

While the custom function above is excellent, for a large production application, using a well-tested, community-vetted library like filesize can be a great choice. It handles more edge cases and offers extensive formatting options.

Installation of filesize library

npm install filesize

How to use filesize library

import { filesize } from 'filesize';

const fileSize = 1234567;

// Decimal (base-10) is the default in newer versions
console.log(filesize(fileSize));
// Output: "1.23 MB"

// Binary (base-2)
console.log(filesize(fileSize, { base: 2 }));
// Output: "1.18 MiB"

// With more options
console.log(filesize(fileSize, { round: 4, spacer: ' -> ' }));
// Output: "1.2346 -> MB"
note

Using a library can save you time and provide more features out of the box.

Conclusion

Formatting bytes for human readability is a common requirement with a few key considerations.

  • The most important decision is whether to use decimal (base-1000) or binary (base-1024) units, as this affects both the numeric value and the unit symbols (KB vs. KiB).
  • A single, parameterized function that uses a logarithmic calculation is the most efficient and flexible "vanilla JavaScript" solution for this task.
  • For production applications, a dedicated library like filesize can offer more features and robustness with less effort.