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/27/2026
prettyBytes in [index.js:L124-L179] is the main function. Here's the step-by-step logic:
1. Input validation
It first checks the input is either a bigint or a finite number, throwing a TypeError otherwise [index.js:L125-L127].
2. Options setup
Defaults are merged in: bits: false, binary: false, space: true, nonBreakingSpace: false [index.js:L129-L135].
3. Unit table selection
Based on options.bits and options.binary, it picks one of four unit arrays defined at the top of the file:
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]
The selection happens at [index.js:L137-L140].
4. Separator A space, non-breaking space, or empty string is chosen as the separator between the number and unit [index.js:L142].
5. Zero handling
If the (possibly signed) input is zero, it short-circuits and returns e.g. ' 0 B' for signed zero, applying fixed-width padding [index.js:L144-L148].
6. Sign handling
It determines if the number is negative, builds a +/-/`` prefix depending on options.signed, and works with the absolute value from then on [index.js:L150-L155].
7. Formatting core logic [index.js:L157-L175]:
- If
number < 1, it's just formatted directly with unit index0(e.g.'0.4 B'). - Otherwise, it computes the exponent (which unit tier to use) via
Math.floorof a log calculation — using base-1024 log (log) for binary mode or base-1000 log (log10) otherwise, capped at the last available unit index [index.js:L163]. - The number is divided down into that unit's scale using a
dividehelper (1000 or 1024 to the power of the exponent). - If no locale formatting is used, it computes a
minPrecision(at least 3 significant digits, or more if the integer part is longer) and callstoPrecisionon it, so results like1.34 kBcome from this precision logic. - Finally it calls
toLocaleString(a helper for optional locale-aware formatting) and assemblesprefix + numberString + separator + unit.
8. BigInt support
Custom log10 and log helpers [index.js:L66-L83] handle both number and bigint inputs — for bigints, log10 works by counting the digit-string length and adding a fractional adjustment based on the leading digits, since Math.log10 can't take a bigint directly.
9. Fixed width
Finally, applyFixedWidth [index.js:L94-L109] optionally left-pads the result with spaces to a specified minimum width (used for aligning tables/progress bars), throwing if fixedWidth isn't a valid non-negative integer.
This overall design is confirmed by tests like [test.js:L36-L61], which show behavior across zero, fractional, large (PB/YB), negative, bigint, and locale-formatted inputs.
FOLLOW_UPS:
- How does the
dividehelper work for bigints? - What does
toLocaleStringdo for locale formatting? - How is
fixedWidthvalidated and applied?
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.