RepoPilot

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

About sindresorhus/pretty-bytes · 2 messages · last activity 7/20/2026

Question

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

RepoPilot

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

1. Input validation Only non-bigint numbers must be finite; a TypeError is thrown otherwise [index.js:L125-L127].

2. Options resolution Default options (bits: false, binary: false, space: true, nonBreakingSpace: false) are merged with the user-supplied options [index.js:L129-L135].

3. Unit table selection Based on bits/binary, one of four unit arrays is chosen [index.js:L137-L139]:

  • BYTE_UNITS: B, kB, MB, GB, TB, PB, EB, ZB, YB [index.js:L1-L11]
  • BIBYTE_UNITS: B, KiB, MiB, GiB, ... [index.js:L13-L23]
  • BIT_UNITS: b, kbit, Mbit, ... [index.js:L25-L35]
  • BIBIT_UNITS: b, kibit, Mibit, ... [index.js:L37-L47]

4. Separator A space, non-breaking space (\u00A0), or empty string is chosen depending on space/nonBreakingSpace [index.js:L141].

5. Signed-zero special case If signed is true and the value is zero (handles both number and bigint zero), it returns a string with a leading space instead of a sign, e.g. ' 0 B' [index.js:L144-L148].

6. Sign handling Negative numbers get a - prefix and are negated for magnitude calculation; if signed is set, positive numbers get a + prefix [index.js:L150-L155].

7. Magnitude / exponent calculation

  • If the (absolute) number is less than 1, it's formatted directly using unit index 0 (B or b) [index.js:L160-L163].
  • Otherwise, the exponent is computed via log(number) / Math.log(1024) (binary) or log10(number) / 3 (decimal), floored and capped at UNITS.length - 1 so it never exceeds the largest unit (e.g., YB) [index.js:L165-L166].
  • The number is divided by 1024^exponent or 1000^exponent accordingly using a divide helper (to support both number and bigint) [index.js:L167].

8. Precision formatting If no locale formatting is requested, it computes a minimum precision (Math.max(3, ...) based on the integer part's digit length) and applies toPrecision — this is how 1337 becomes 1.34 (3 significant digits) [index.js:L169-L172].

9. Locale-aware string conversion toLocaleString is applied to produce the final numeric string, respecting any locale option [index.js:L174].

10. Assembly The result is prefix + numberString + separator + unit [index.js:L162-L163, L175-L176].

11. Fixed width Finally, applyFixedWidth pads the result if a fixedWidth option was passed [index.js:L154, L178].

This design lets the same function handle regular bytes, bits, binary (KiB-style) prefixes, signed differences, locales, non-breaking spaces, and fixed-width alignment, as shown in the usage examples in the README [readme.md:L16-L43].

FOLLOW_UPS:

  • What does the divide helper function do?
  • How is applyFixedWidth implemented?
  • Why is minimum precision capped at 3 significant digits?

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.