human-readable – create user-friendly strings for byte sizes in NodeJS

Lightweight npm-package for creating human-readable strings from bytes (e.g. 17238 → 17.24 kB) or other sizes.

Many functions dealing with sizes of files, buffers, objects etc. often return an amount of bytes. That’s good for further checks, calculations etc. but not for presenting these sizes to users. A classic example is the filesize.

const fs = require('fs');

var stats = fs. statSync('/tmp/large.txt');
console.log('File Size: ' + stats. size);

// File Size: 10485760

To deal with that very common situation we provided a handy package human-readable. The example above then looks like that.

const fs = require('fs');
const hr = require('@tsmx/human-readable');

var stats = fs. statSync('/tmp/large.txt');
console.log('File Size: ' + hr.fromBytes(stats. size));

// File Size: 10.49 MB

One now may say: “Calculating the new number and adding ‘MB’ is quite easy… why should I import a package dependency for that?” At first sight yes, but on deeper examination there are some good reasons to outsource this functionality to a package, because it helps you to…

  • Don’t bloat your projects with self-implemented boilerplate code. Keep them DRY.
  • Don’t waste your time on dealing with byte conversion details like decimal and binary units – focus on your business case.
  • Rely on an out-of-the box well-tested solution instead of having to take care of quality assurance for this task yourself.

YABCP – yet another byte conversion package?

There are quite a lot and also some very good packages dealing with size conversions around at npm. So why this YABCP?

Investigating the available packages and the pros and cons each has, no one seemed to be 100% fitting to the need of our use cases, which are

  • Converting sizes supporting both, decimal (SI) and binary (IEC) units.
  • Supporting manual conversion of sizes in both directions – from small to large and from large to small.
  • Ease of use for directly displaying the result to the user.

If your intentions and use-cases are similar, you might be right with our package… so go ahead.

Usage

Install the package as a dependency.

npm i @tsmx/human-readable --save

Then import an use the functions provided to create human-readable strings.

const hr = require('@tsmx/human-readable');
 
hr.fromBytes(17238);
// '17.24 kB'
 
hr.fromBytes(17238, { mode: 'IEC' });
// '16.83 KiB'
 
hr.fromBytes(17238, { numberOnly: true });
// '17.24'
 
hr.fromBytes(17238, { fixedPrecision: 1 });
// '17.2 kB'
 
hr.fromBytes(17238, { fullPrecision: true });
// '17.238 kB'
 
hr.fromTo(17, 'GBYTE', 'KBYTE');
// '17000000 kB'
 
hr.fromTo(17, 'GBYTE', 'KBYTE', { mode: 'IEC' });
// '17825792 KiB'
 
hr.availableSizes();
// [ 'BYTE', 'KBYTE', 'MBYTE', 'GBYTE', 'TBYTE', 'PBYTE' ]

Note: If you need to use the package in client-side JavaScript in the browser, refer to this guide.

Functionality and API

To cover the mentioned use-cases two functions are exported: fromBytes and fromTo. With fromBytes you can “automatically” create a readable string out of a given amount of bytes. The function takes care of choosing the appropriate target unit etc. If you want an explicit conversion from a size unit to another, use fromTo instead.

fromBytes(bytes, options)

Automatically converts the amount of bytes to a readable string and returns it. Switch to the next size is done when the value of the greater unit is at least 1. So fromBytes(999) would result in 999 B whereas fromBytes(1000) would return 1 kB

ParameterDescription
bytesnumber of bytes to convert
optionsoptional JSON object containing all custom options for the conversion, can have the following properties:

mode
Type: String 
Default: none (use decimal mode)

Can be set to IEC to use binary conversion (factor 1.024) and units (KiB,MiB,…). If not set or to any other value, decimal conversion (factor 1.000) and units (kB, MB,…) are used.

numberOnly
Type: Boolean 
Default: false

If set to true, conversion only returns the number and omits the unit. Overrides 
noWhitespace.

fixedPrecision
Type: Number

If set the returned number string is formatted to the given fixed decimal places. If not set, the default behaviour of the conversion is to use a dynamic number of decimal places from zero up to two.

fullPrecision
Type: Boolean 
Default: false

If set to true, the returned number value will be presented with full available decimal places. Overrides fixedPrecision.

noWhitespace
Type: Boolean 
Default: false

If set to true, the whitespace between the number and unit string is omitted. E.g. 10MB instead of 10 MB.

Without specifying custom options, the function will have the follwing behaviour:

  • Use of decimal units (kB, MB, GB,…) with conversion factor 1.000 between each size.
  • Returns a string containing the resulting value followed by a whitespace and the corresponding decimal unit.
  • Uses a floating amount of decimal places from 0 to 2 according to the calculated result.

Examples:

const hr = require('@tsmx/human-readable');

console.log(hr.fromBytes(17522071));
// '17.52 MB'

console.log(hr.fromBytes(17522071, { fixedPrecision: 0 }));
// '18 MB'

console.log(hr.fromBytes(17522071, { mode: 'IEC', fixedPrecision: 3, noWhitespace: true }));
// '16.710MiB'

console.log(hr.fromBytes(17522071, { mode: 'IEC', fullPrecision: true }));
// '16.710349082946777 MiB'

fromTo(value, fromSize, toSize, options)

Converts the value assuming it is given in fromSize to toSize. Conversion can be done from smaller to a greater size (e.g. kB to MB) or from greater to smaller (e.g. GB to MB). Default behaviour (unit string, precision) and available options are the same as in fromBytes.

ParameterDescription
valuevalue to convert
fromSizethe size value has, must be one out of availableSizes()
toSizethe size value should be converted to, must be one out of availableSizes()
optionsoptional object containing all custom options for the conversion, see fromBytes

Examples:

const hr = require('@tsmx/human-readable');

console.log(hr.fromTo(3, 'MBYTE', 'KBYTE', { mode: 'IEC' }));
// '3072 KiB'

console.log(hr.fromTo(793, 'MBYTE', 'GBYTE', { numberOnly: true }));
// '0.79'

availableSizes()

Returns an array of strings representing the available sizes for manual conversion with fromTo.

Array Entrydecimal unit (SI)binary unit (IEC)
BYTEByte (B)Byte (B)
KBYTEKilobyte (kB)Kibibyte (KiB)
MBYTEMegabyte (MB)Mebibtye (MiB)
GBYTEGigabyte (GB)Gibibyte (GiB)
TBYTETerabyte (TB)Tebibyte (TiB)
PBYTEPetabyte (PB)Pebibyte (PiB)

Testing

The package contains a set of unit tests with a good overall coverage of the code. To run them, install or clone the package and run the tests via npm:

npm run test

To output the code coverage run:

npm run test-coverage

Also check out the current coverage stats at Coveralls.

Useful Links