How does pretty-bytes format byte counts into a human-readable string?
How does pretty-bytes format byte counts into a human-readable string?
About sindresorhus/pretty-bytes · 2 messages · last activity 7/20/2026
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 (
Borb) [index.js:L160-L163]. - Otherwise, the exponent is computed via
log(number) / Math.log(1024)(binary) orlog10(number) / 3(decimal), floored and capped atUNITS.length - 1so it never exceeds the largest unit (e.g., YB) [index.js:L165-L166]. - The number is divided by
1024^exponentor1000^exponentaccordingly using adividehelper (to support bothnumberandbigint) [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
dividehelper function do? - How is
applyFixedWidthimplemented? - Why is minimum precision capped at 3 significant digits?
Want to ask your own question?
Open chat for sindresorhus/pretty-bytesPublic 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.