pretty-bytes vs bytes vs filesize vs humanize-bytes
Formatting and Parsing Byte Sizes in JavaScript
pretty-bytesbytesfilesizehumanize-bytes

Formatting and Parsing Byte Sizes in JavaScript

These libraries handle the conversion of raw byte counts into human-readable strings, though they serve different roles in the stack. bytes is widely used in backend environments, particularly with Express.js, for parsing HTTP headers like Content-Length as well as formatting. filesize offers deep customization for formatting, supporting bits, bytes, and various rounding strategies. pretty-bytes is the frontend standard for clean, localized output with minimal configuration. humanize-bytes provides a lightweight alternative but sees less active maintenance compared to the others.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
pretty-bytes25,114,6601,31016.1 kB018 days agoMIT
bytes047412.3 kB11-MIT
filesize01,70964.4 kB07 days agoBSD-3-Clause
humanize-bytes03-011 years agoMIT

Formatting and Parsing Byte Sizes: bytes vs filesize vs humanize-bytes vs pretty-bytes

When displaying storage capacity, network speed, or file sizes, raw numbers like 1048576 mean nothing to users. These four packages solve that problem, but they target different layers of the application stack. Let's break down how they handle parsing, formatting, and localization.

🎯 Core Purpose: Parsing vs Formatting

The most critical difference lies in direction. Most tools only format numbers to strings, but bytes handles both directions, making it unique for server-side input handling.

bytes parses strings into numbers and formats numbers into strings.

  • Useful for reading Content-Length headers or config files.
  • Returns null if the string is invalid.
import bytes from 'bytes';

// Format number to string
console.log(bytes(1024)); // '1KB'

// Parse string to number
console.log(bytes('1kb')); // 1024

filesize focuses strictly on formatting numbers into readable strings.

  • Does not parse strings back to numbers.
  • Returns a formatted string immediately.
import { filesize } from 'filesize';

// Format number to string
console.log(filesize(1024)); // '1.02 kB'

// Parse string to number (Not supported)
// console.log(filesize('1kb')); // Error

humanize-bytes is a simple formatter for numbers.

  • No parsing capability.
  • Minimal output style.
import humanize from 'humanize-bytes';

// Format number to string
console.log(humanize(1024)); // '1KB'

// Parse string to number (Not supported)
// console.log(humanize('1kb')); // Error

pretty-bytes is a dedicated formatter optimized for UI display.

  • No parsing capability.
  • Focuses on clean, localized output.
import prettyBytes from 'pretty-bytes';

// Format number to string
console.log(prettyBytes(1024)); // '1.02 kB'

// Parse string to number (Not supported)
// console.log(prettyBytes('1kb')); // Error

πŸ›  Configuration & Control

Developers often need to tweak rounding, units, or separators. filesize leads here, while pretty-bytes prefers sensible defaults.

bytes allows basic separators and decimal control.

  • Good for matching existing backend styles.
  • Options are limited compared to dedicated formatters.
import bytes from 'bytes';

bytes(1000, { 
  decimalPlaces: 2, 
  thousandsSeparator: ',' 
}); // '1000.00B'

filesize offers the deepest configuration options.

  • Control rounding, base, bits vs bytes, and exponents.
  • Best for technical dashboards requiring specific rules.
import { filesize } from 'filesize';

filesize(1000, { 
  round: 3, 
  base: 2, 
  bits: true 
}); // '7.813 Kib'

humanize-bytes has minimal to no configuration.

  • Designed for zero-setup usage.
  • You get what you get without tuning.
import humanize from 'humanize-bytes';

// No options typically supported
humanize(1000); // '1KB'

pretty-bytes balances simplicity with key controls.

  • Allows binary toggle and digit limits.
  • Keeps API surface small to prevent misuse.
import prettyBytes from 'pretty-bytes';

prettyBytes(1000, { 
  binary: true, 
  maximumFractionDigits: 1 
}); // '1 KiB'

πŸ“ Unit Standards: IEC vs JEDEC

Confusion often arises between KB (1000 bytes) and KiB (1024 bytes). Different packages default to different standards.

bytes defaults to JEDEC (base 1024, no 'i').

  • Matches common HTTP and OS conventions.
  • Output looks like 1KB even if it means 1024.
import bytes from 'bytes';

bytes(1024); // '1KB' (JEDEC style)

filesize lets you choose explicitly.

  • Supports IEC (KiB), JEDEC (KB), and decimal (kB).
  • Prevents ambiguity in technical contexts.
import { filesize } from 'filesize';

filesize(1024, { standard: 'iec' }); // '1 KiB'
filesize(1024, { standard: 'jedec' }); // '1 KB'

humanize-bytes typically follows JEDEC.

  • Less explicit control over standards.
  • Assumes common usage patterns.
import humanize from 'humanize-bytes';

humanize(1024); // '1KB' (JEDEC style)

pretty-bytes defaults to SI (base 1000) but supports binary.

  • Aligns with modern web standards for storage.
  • Switch to binary for memory-specific displays.
import prettyBytes from 'pretty-bytes';

prettyBytes(1000); // '1 kB' (SI style)
prettyBytes(1024, { binary: true }); // '1 KiB'

🌍 Locale & Internationalization

Global applications need number formatting that respects local conventions (e.g., commas vs periods).

bytes has no built-in locale support.

  • You must handle separators manually.
  • Suitable for server logs or internal systems.
import bytes from 'bytes';

// No locale option
bytes(1000.5); // '1000.5B'

filesize supports locale via options.

  • Pass an ISO locale code to format numbers correctly.
  • Useful for international admin panels.
import { filesize } from 'filesize';

filesize(1000.5, { locale: 'de-DE' }); // '1.000,5 B'

humanize-bytes lacks locale features.

  • Output is fixed to English conventions.
  • Not recommended for global consumer apps.
import humanize from 'humanize-bytes';

// No locale option
humanize(1000.5); // '1KB'

pretty-bytes has robust locale support.

  • Uses Intl.NumberFormat under the hood.
  • Best choice for user-facing frontend interfaces.
import prettyBytes from 'pretty-bytes';

prettyBytes(1000.5, { locale: 'de-DE' }); // '1 kB'

πŸ“Š Summary Table

Featurebytesfilesizehumanize-bytespretty-bytes
Parse Stringβœ… Yes❌ No❌ No❌ No
Format Numberβœ… Yesβœ… Yesβœ… Yesβœ… Yes
Bits Support❌ Noβœ… Yes❌ No❌ No
Locale Support❌ Noβœ… Yes❌ Noβœ… Yes
Config DepthLowHighNoneMedium
Primary UseBackend/HTTPDashboardsSimple ScriptsFrontend UI

πŸ’‘ Final Recommendation

These tools solve similar problems but fit different slots in your architecture.

bytes is the backend specialist πŸ–₯️. Use it in Node.js services when you need to read configuration values like 512mb or parse HTTP headers. It is the only choice here that handles input parsing reliably.

filesize is the power user tool πŸ› οΈ. Reach for it when you need to display network speeds in bits, enforce specific rounding rules, or support obscure unit standards. It handles edge cases the others ignore.

humanize-bytes is the legacy lightweight πŸͺΆ. Only use it for quick internal scripts where dependencies must be minimal and features like localization do not matter. For new projects, prefer pretty-bytes.

pretty-bytes is the frontend standard 🎨. It is the default choice for React, Vue, or Angular apps. It provides localized, clean output without requiring complex configuration.

Final Thought: For most modern web apps, pair bytes on the server for parsing inputs and pretty-bytes on the client for displaying results. This combination covers the full lifecycle of data handling β€” from ingestion to presentation.

How to Choose: pretty-bytes vs bytes vs filesize vs humanize-bytes

  • pretty-bytes:

    Choose pretty-bytes for modern frontend applications where clean, localized UI text is the priority. It handles internationalization out of the box and follows current best practices for unit display. It is the default choice for build tools, download progress bars, and user-facing file size indicators.

  • bytes:

    Choose bytes when working in Node.js environments, especially with Express, where you need to parse incoming byte strings from headers or configuration files. It is the only package in this group designed for bidirectional conversion (string to number and number to string). Use it for server-side logic where HTTP standards matter.

  • filesize:

    Choose filesize when you need granular control over output formatting, such as displaying network speeds in bits instead of bytes. It supports custom rounding, specific unit standards (JEDEC vs IEC), and locale formatting. It is ideal for dashboards or technical tools where precision and configuration are critical.

  • humanize-bytes:

    Choose humanize-bytes only for simple projects where you need a quick, zero-config solution and do not require locale support or advanced options. Be aware that it receives less maintenance than pretty-bytes, so it may not keep up with newer JavaScript standards. It works for internal tools where exact formatting rules are not strict.

README for pretty-bytes

pretty-bytes

Convert bytes to a human readable string: 1337 β†’ 1.34 kB

Useful for displaying file sizes for humans.

Note that it uses base-10 (e.g. kilobyte). Read about the difference between kilobyte and kibibyte.

Install

npm install pretty-bytes

Usage

import prettyBytes from 'pretty-bytes';

prettyBytes(1337);
//=> '1.34 kB'

prettyBytes(100);
//=> '100 B'

// Display with units of bits
prettyBytes(1337, {bits: true});
//=> '1.34 kbit'

// Display file size differences
prettyBytes(42, {signed: true});
//=> '+42 B'

// Localized output using German locale
prettyBytes(1337, {locale: 'de'});
//=> '1,34 kB'

// Fixed width for alignment (useful for progress bars and tables)
prettyBytes(1337, {fixedWidth: 8});
//=> ' 1.34 kB'

API

prettyBytes(number, options?)

number

Type: number | bigint

The number to format.

options

Type: object

signed

Type: boolean
Default: false

Include plus sign for positive numbers. If the difference is exactly zero a space character will be prepended instead for better alignment.

bits

Type: boolean
Default: false

Format the number as bits instead of bytes. This can be useful when, for example, referring to bit rate.

import prettyBytes from 'pretty-bytes';

prettyBytes(1337, {bits: true});
//=> '1.34 kbit'
binary

Type: boolean
Default: false

Format the number using the Binary Prefix instead of the SI Prefix. This can be useful for presenting memory amounts. However, this should not be used for presenting file sizes.

import prettyBytes from 'pretty-bytes';

prettyBytes(1000, {binary: true});
//=> '1000 B'

prettyBytes(1024, {binary: true});
//=> '1 KiB'
locale

Type: boolean | string | string[]
Default: false

  • If false: Output won't be localized.
  • If true: Localize the output using the system/browser locale.
  • If string: Expects a BCP 47 language tag (For example: en, de, …)
  • If string[]: Expects a list of BCP 47 language tags (For example: en, de, …)

[!IMPORTANT] Only the number and decimal separator are localized. The unit title is not and will not be localized.

minimumFractionDigits

Type: number
Default: undefined

The minimum number of fraction digits to display.

If neither minimumFractionDigits nor maximumFractionDigits is set, the default behavior is to round to 3 significant digits.

[!NOTE] When minimumFractionDigits or maximumFractionDigits is specified, values are truncated instead of rounded to provide more intuitive results for file sizes.

import prettyBytes from 'pretty-bytes';

// Show the number with at least 3 fractional digits
prettyBytes(1900, {minimumFractionDigits: 3});
//=> '1.900 kB'

prettyBytes(1900);
//=> '1.9 kB'
maximumFractionDigits

Type: number
Default: undefined

The maximum number of fraction digits to display.

If neither minimumFractionDigits nor maximumFractionDigits is set, the default behavior is to round to 3 significant digits.

[!NOTE] When minimumFractionDigits or maximumFractionDigits is specified, values are truncated instead of rounded to provide more intuitive results for file sizes.

import prettyBytes from 'pretty-bytes';

// Show the number with at most 1 fractional digit
prettyBytes(1920, {maximumFractionDigits: 1});
//=> '1.9 kB'

prettyBytes(1920);
//=> '1.92 kB'
space

Type: boolean
Default: true

Put a space between the number and unit.

import prettyBytes from 'pretty-bytes';

prettyBytes(1920, {space: false});
//=> '1.92kB'

prettyBytes(1920);
//=> '1.92 kB'
nonBreakingSpace

Type: boolean
Default: false

Use a non-breaking space instead of a regular space to prevent the unit from wrapping to a new line.

Has no effect when space is false.

fixedWidth

Type: number
Default: undefined

Pad the output to a fixed width by right-aligning it.

Useful for creating aligned columns in tables or progress bars.

If the output is longer than the specified width, no padding is applied.

Must be a non-negative integer. Throws a TypeError for invalid values.

import prettyBytes from 'pretty-bytes';

prettyBytes(1337, {fixedWidth: 10});
//=> '   1.34 kB'

prettyBytes(100_000, {fixedWidth: 10});
//=> '  100 kB'

// Useful for progress bars and tables
[1000, 10_000, 100_000].map(bytes => prettyBytes(bytes, {fixedWidth: 8}));
//=> ['   1 kB', '  10 kB', ' 100 kB']

FAQ

Why kB and not KB?

k is the standardized SI prefix for kilo.

Related