RepoPilot

How does pretty-bytes format byte counts into a human-readable string?

About sindresorhus/pretty-bytes · 2 messages · last activity 8/1/2026

Question

How does pretty-bytes format byte counts into a human-readable string?

RepoPilot

The core logic lives in the prettyBytes function [index.js:L124-L179]. Here's the flow:

1. Input validation It first checks that the input is a finite number (or a bigint, which bypasses the finiteness check since bigints are always integral): if (typeof number !== 'bigint' && !Number.isFinite(number)) it throws a TypeError [index.js:L125-L127].

2. Options setup Defaults are merged in (bits: false, binary: false, space: true, nonBreakingSpace: false) [index.js:L129-L135]. Based on bits/binary, it picks which unit array to use — BYTE_UNITS, BIBYTE_UNITS, BIT_UNITS, or BIBIT_UNITS [index.js:L137-L139], all defined at the top of the file [index.js:L1-L41]. It also determines the separator character (regular space, non-breaking space, or none) [index.js:L141].

3. Zero handling If signed is true and the value is zero, it returns a specially-formatted ' 0 B'-style string (space instead of +/-) for alignment purposes [index.js:L144-L148].

4. Sign handling It computes whether the number is negative, decides the prefix (-, +, or nothing depending on signed), and normalizes negative numbers to positive for the rest of the computation [index.js:L150-L155].

5. Formatting

  • If the number is less than 1, it's just localized and combined with the base unit (B or b) directly — no scaling needed [index.js:L160-L163].
  • Otherwise, it computes the appropriate exponent/magnitude using log10 (SI) or log base 1024 (binary) to pick a unit index, capped at the last unit in the array [index.js:L165-L166]. It then divides the number by 1000^exponent or 1024^exponent [index.js:L167].
  • If no locale-based formatting options are set, it computes a minPrecision (at least 3 significant digits, or more if the integer part is longer) and calls toPrecision on the number — this is what gives results like 1.34 kB rather than arbitrary decimal noise [index.js:L169-L172].
  • The number is then run through toLocaleString (a helper that optionally applies locale formatting) and concatenated with the prefix, separator, and the resolved unit string [index.js:L174-L176].

6. Fixed width Finally, applyFixedWidth is called, which pads the result with leading spaces if a fixedWidth option was given and the result is shorter than that width [index.js:L94-L107], returning the finished string.

So for prettyBytes(1337), it picks BYTE_UNITS, computes exponent 1 (kB range), divides 1337 by 1000 → 1.337, applies 3-digit precision → "1.34", and returns '1.34 kB'.

FOLLOW_UPS:

  • How does the locale option format numbers differently?
  • What does toLocaleString helper do exactly?
  • How is binary vs SI unit exponent calculated?

Want to ask your own question?

Open chat for sindresorhus/pretty-bytes

Public Q&A. Generated by RepoPilot from the actual source of sindresorhus/pretty-bytes. AI answers can be incomplete or stale — verify before relying on them.