npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@thi.ng/units

v1.1.9

Published

Extensible SI unit creation, conversions, quantities & calculations (incl. Lisp-like DSL and ~170 predefined units & constants)

Readme

@thi.ng/units

npm version npm downloads Mastodon Follow

[!NOTE] This is one of 214 standalone projects, maintained as part of the @thi.ng/umbrella monorepo and anti-framework.

🚀 Please help me to work full-time on these projects by sponsoring me on GitHub. Thank you! ❤️

About

Extensible SI unit creation, conversions, quantities & calculations (incl. Lisp-like DSL and ~170 predefined units & constants).

All unit definitions, quantities & conversions are based on the SI unit system & concepts described here:

  • https://en.wikipedia.org/wiki/International_System_of_Units
  • https://en.wikipedia.org/wiki/SI_base_unit
  • https://en.wikipedia.org/wiki/SI_derived_unit
  • https://en.wikipedia.org/wiki/Coherence_(units_of_measurement)
  • https://en.wikipedia.org/wiki/Metric_prefix

The overall conversion approach is inspired & partially based on:

Unit definitions

Each unit is defined via a 7-dimensional vector representing individual exponents for each of the SI base unit dimensions, in order:

| id | SI dimension | Base unit | Base unit symbol | |----|---------------------|-----------|------------------| | 0 | mass | kilogram | kg | | 1 | length | meter | m | | 2 | time | second | s | | 3 | current | ampere | A | | 4 | temperature | kelvin | K | | 5 | amount of substance | mole | mol | | 6 | luminous intensity | candela | cd |

Dimensionless units (e.g. radian, byte) are supported too and represented by a vector with all dimensions set to zero.

Additionally, we also define a scale factor and zero offset for each unit, with most dimensions' base units usually using a factor of 1 and no offset.

For example, here's how we can define kilograms and meters:

import { coherent, unit } from "@thi.ng/units";

// kilogram, SI dimension 0
const KG = coherent(0);
// { dim: [ 1, 0, 0, 0, 0, 0, 0 ], scale: 1, offset: 0, coherent: true }

// meters, SI dimension 1
const M = coherent(1);
// { dim: [ 0, 1, 0, 0, 0, 0, 0 ], scale: 1, offset: 0, coherent: true }

// kelvin, SI dimension 4 (here without syntax sugar)
const K = unit(4, 1, 0, true);
// { dim: [ 0, 0, 0, 0, 1, 0, 0 ], scale: 1, offset: 0, coherent: true }

// fahrenheit, SI dim 4 with custom scale factor and zero offset
const F = unit(4, 1 / 1.8, 459.67 / 1.8);
// { dim: [ 0, 0, 0, 0, 1, 0, 0 ],  scale: 0.5555, offset: 255.3722, coherent: false }

More complex units like electrical resistance (e.g. ohm) are based on more than a single dimension:

import { div, A, V } from "@thi.ng/units";

// ohm = volt / ampere
div(V, A)
// { dim: [ 1, 2, -3, -2, 0, 0,  0 ], scale: 1, offset: 0, coherent: true }

This dimension vector represents the unit definition for (see SI derived units):

Ω = kg⋅m2⋅s−3⋅A−2

Btw. The formatSI() function can be used to format a unit's dimension vector:

import { div, formatSI, A, V } from "@thi.ng/units";

formatSI(div(V, A));
// "kg·m2·s-3·A-2"

Predefined units

The following units are provided as "builtins", here grouped by dimension:

Acceleration

| Unit name | Variable name | Description | |-----------|---------------|---------------------------| | m/s2 | m_s2 | meter per second squared | | ft/s2 | ft_s2 | foot per second squared | | rad/s2 | rad_s2 | radian per second squared |

Angle

| Unit name | Variable name | Description | |-----------|---------------|-------------| | arcmin | arcmin | arc minute | | arcsec | arcsec | arc second | | deg | deg | degree | | gon | gon | gradian | | rad | rad | radian | | sr | sr | steradian | | turn | turn | turn |

Area

| Unit name | Variable name | Description | |-----------|---------------|-------------------| | m2 | m2 | square meter | | cm2 | cm2 | square centimeter | | mm2 | mm2 | square millimeter | | km2 | km2 | square kilometer | | ha | ha | hectar | | ac | ac | acre | | sqin | sqin | square inch | | sqft | sqft | square foot | | sqmi | sqmi | square mile |

Data

| Unit name | Variable name | Description | |-----------|---------------|-------------------| | bit | bit | bit | | kbit | kbit | kilobit | | Mbit | Mbit | megabit | | Gbit | Gbit | gigabit | | Tbit | Tbit | terabit | | kibit | kibit | kibibit (1024) | | Mibit | Mibit | mebibit (1024) | | Gibit | Gibit | gibibit (1024) | | Tibit | Tibit | tebibit (1024) | | B | B | byte (8 bit) | | kB | kB | kilobyte (metric) | | MB | MB | megabyte (metric) | | GB | GB | gigabyte (metric) | | TB | TB | terabyte (metric) | | PB | PB | petabyte (metric) | | EB | EB | exabyte (metric) | | KiB | KiB | kibibyte (1024) | | MiB | MiB | mebibyte (1024) | | GiB | GiB | gibibyte (1024) | | TiB | TiB | tebibyte (1024) | | PiB | PiB | pebibyte (1024) | | EiB | EiB | exbibyte (1024) |

Density

| Unit | Variable name | Description | |----------|---------------|---------------| | kg/m3 | kg_m3 | density | | 1/inch | dpi | dots per inch |

Electric current

| Unit | Variable name | Description | |-------|---------------|-------------------| | A | A | ampere | | mA | mA | milliampere | | mAh | mAh | milliampere-hours | | C | C | coulomb | | V | V | volt | | mV | mV | millivolt | | kV | kV | kilovolt | | MV | MV | megavolt | | F | F | farad | | pF | pF | picofarad | | µF | µF | microfarad | | Ω | Ω / ohm | ohm | | | / kohm | kiloohm | | | / Mohm | megaohm | | | / Gohm | gigaohm | | S | S | siemens | | Wb | Wb | weber | | T | T | tesla | | H | H | henry |

Energy

| Unit | Variable name | Description | |--------|---------------|-------------| | J | J | joule | | kJ | kJ | kilojoule | | MJ | MJ | megajoule | | GJ | GJ | gigajoule | | cal | cal | calorie | | kcal | kcal | kilocalorie |

Force

| Unit | Variable name | Description | |------|---------------|-------------| | N | N | newton |

Frequency

| Unit | Variable name | Description | |-------|---------------|---------------------| | Hz | Hz | hertz | | kHz | KHz | kilohertz | | MHz | MHz | megahertz | | GHz | GHz | gigahertz | | THz | THz | terahertz | | rpm | rpm | rotation per minute | | ω | ω / omega | radian per second |

Length

| Unit name | Variable name | Description | |-----------|----------------|-------------------| | m | m | meter | | Å | angstrom | angstrom | | nm | nm | nanometer | | µm | µm | micrometer | | mm | mm | millimeter | | cm | cm | centimeter | | km | km | kilometer | | au | au | astronomical unit | | pc | pc | parsec | | ly | ly | light year | | in | in | inch | | mil | mil / thou | 1/1000th inch | | ft | ft | foot | | yd | yd | yard | | mi | mi | mile | | nmi | nmi | nautical mile | | pica | pica | pica | | point | point | point |

Luminous intensity

| Unit | Variable name | Description | |------|---------------|-------------| | cd | cd | candela | | lm | lm | lumen | | lx | lx | lux |

Mass

| Unit name | Variable name | Description | |-----------|---------------|----------------| | µg | µg | microgram | | mg | mg | milligram | | g | g | gram | | kg | kg | kilogram | | t | t | tonne | | kt | kt | kilotonne | | Mt | Mt | megatonne | | Gt | Gt | gigatonne | | lb | lb | imperial pound | | st | st | stone |

Parts per notation

https://en.wikipedia.org/wiki/Parts-per_notation

| Unit name | Variable name | Description | |-----------|---------------|---------------------------| | % | percent | part per hundred | | | permille | part per thousand | | | permyriad | part per ten thousand | | pcm | pcm | part per hundred thousand | | ppm | ppm | part per million | | ppb | ppb | part per billion | | ppt | ppt | part per trillion |

Power

| Unit name | Variable name | Description | |-----------|---------------|---------------| | W | W | watt | | mW | mW | milliwatt | | kW | kW | kilowatt | | MW | MW | megawatt | | GW | GW | gigawatt | | TW | TW | terawatt | | Wh | Wh | watt-hour | | kWh | kWh | kilowatt-hour |

Pressure

| Unit name | Variable name | Description | |-----------|---------------|-----------------------| | Pa | Pa | pascal | | kPa | KPa | kilopascal | | MPa | MPa | megapascal | | GPa | GPa | gigapascal | | at | at | technical atmosphere | | atm | atm | atmosphere | | bar | bar | bar | | psi | psi | pound per square inch |

Speed

| Unit | Variable name | Description | |--------|---------------|--------------------| | m/s | m_s | meter per second | | km/h | km_h | kilometer per hour | | mph | mph | mile per hour | | kn | kn | knot |

Substance

| Unit | Variable name | Description | |-------|---------------|-------------| | mol | mol | mole |

Temperature

| Unit | Variable name | Description | |------|---------------|-------------------| | K | K | kelvin | | | celsius | degree celsius | | | fahrenheit | degree fahrenheit |

Time

| Unit | Variable name | Description | |---------|---------------|--------------------| | s | s | second | | ms | ms | millisecond | | µs | µs | microsecond | | ns | ns | nanosecond | | min | min | minute | | h | h | hour | | d | d | day | | week | week | week | | month | month | month (30 days) | | year | year | year (365.25 days) |

Volume

| Unit | Variable name | Description | |------------|---------------|----------------------| | m3 | m3 | cubic meter | | mm3 | mm3 | cubic millimeter | | cm3 | cm3 | cubic centimeter | | km3 | km3 | cubic kilometer | | l | l | liter | | cl | cl | centiliter | | ml | ml | milliliter | | gal | gal | imperial gallon | | pt | pt | imperial pint | | fl oz | floz | imperial fluid ounce | | us gal | us_gal | US gallon | | us pt | us_pt | US pint | | us cup | us_cup | US cup | | us fl oz | us_floz | US fluid ounce |

Creating & deriving units

Using standard metric prefixes

Existing coherent units can be prefixed to produce derived versions:

import { prefix, Hz } from "@thi.ng/units";

// define micrometer (also available as preset)
prefix("µ", "m")
// { dim: [ 0, 1, 0, 0, 0, 0, 0 ], scale: 0.000001, offset: 0, coherent: false }

// define kKhz
prefix("k", Hz);
// { dim: [ 0, 0, -1, 0, 0, 0, 0 ], scale: 1000, offset: 0, coherent: false }

Unit combinators

The following combinators can be used to derive scaled and/or more complex units (or quantities) in multiple SI dimensions:

  • div(a, b): derives a new unit via the division of the given units
  • mul(a, b): derives a new unit as the product of the given units
  • pow(u, k): raises given unit to power k (e.g. meter ⇒ square meter)
  • reciprocal(u): Creates reciprocal of given unit (e.g. Hz ⇒ 1/second)
import { div, mul, pow, prefix, reciprocal, bit, m, s } from "@thi.ng/units";

// acceleration (meter per second squared)
const m_s2 = div(m, pow(s, 2));
// { dim: [ 0, 1, -2, 0, 0, 0,  0 ], scale: 1, offset: 0, coherent: false }

// define kilowatt-hour (also available as preset)
const kWh = mul(prefix("k","W"), "h");
// { dim: [ 1, 2, -2, 0, 0, 0, 0 ], scale: 3600000, offset: 0, coherent: false }

// define `word` as 16 bits
const word = mul(bit, 16);
// { dim: [ 0, 0, 0, 0, 0, 0, 0 ], scale: 16, offset: 0, coherent: false }

// Hz = 1/s
const Hz = reciprocal(s);
// { dim: [ 0, 0, -1, 0, 0, 0, 0 ], scale: 1, offset: 0, coherent: false }

Unit conversions

Units (and quantities) can be converted using convert(). Only units with compatible (incl. reciprocal) dimensions can be converted, otherwise an error will be thrown. On the other hand, all dimensionless units can be converted to other dimensionless units (even if it would be semantic nonsense).

Units can be specified in various ways:

import { convert, div, reciprocal, h, km_h, mph, yd } from "@thi.ng/units";

// convert from km/h to mph using unit names
convert(100, "km/h", "mph");
// 62.13711922373341

// or using predefined unit constants directly
convert(60, mph, km_h);
// 96.56063999999998

// or using anonymous units (meter/second ⇒ yard/hour)
convert(1, "m/s", div(yd, h));
// 3937.007874015749

// convert into opposite direction (meter/second  ⇒ second/meter)
convert(10, "m/s", reciprocal("m/s"));
// 0.1

Another example using dimensionless units (here angles, arc second ⇒ radian) to compute the distance of 10 arcsec on the earth surface (in meters):

import { convert, R } from "@thi.ng/units";

// earth radius in meters
// (also available as quantity EARTH_RADIUS, see section below)
const R = 6371000;

convert(10, "arcsec", "rad") * R;
// 308.87479623488537

Quantities

The library also supports defining quantities, i.e. certain finite amounts of a given unit. These can be a number or vector-based and can be used for calculations & conversions using the above mentioned polymorphic functions: div(), mul(), reciprocal() and convert().

Quantities are created via quantity() which acts as factory function for a thin Quantity class wrapper. The latter also implements the standard IDeref interface to obtain the unwrapped amount (though it only should be used for dimensionless quantities). Use convert() otherwise!

import { convert, div, quantity } from "@thi.ng/units";

// (also available as preset)
const speedOfLight = quantity(299792458, "m/s");

// compute wavelength of a WiFi signal in millimeters
convert(div(speedOfLight, quantity(2.4,"GHz")), "mm");
// 124.9135

Some examples using vector quantities:

import { convert, mul, quantity, NONE } from "@thi.ng/units";

// DIN A4 paper size (also available as preset)
const A4 = quantity([210, 297], "mm");
// (also available as preset)
const DPI_300 = quantity(300, "dpi");

// convert paper size to inches
convert(A4, "in");
// [ 8.2677, 11.6929 ]

// or calculate pixel dimensions @ 300 dpi
// the result of this product is dimensionless,
// so we use the NONE preset as target unit...
convert(mul(A4, DPI_300), NONE)
// [ 2480.314960629921, 3507.8740157480315 ]

// alternatively, dimensionless units can be deref'd directly
mul(A4, DPI_300).deref()
// [ 2480.314960629921, 3507.8740157480315 ]

When combining different quantities, their units do not need to be the same (but compatible):

import { convert, mul, quantity } from "@thi.ng/units";

// compute 10 mm x 2 inch and convert to square centimeter
convert(mul(quantity(10, "mm"), quantity(2, "in")), "cm2")
// 5.08

Constants

The following constants are provided (more to come):

| Var name | Unit | Comment | |----------------------------------------------|---------------------|---------------------------| | DIN_A0 ... DIN_A8 | 2d vector of mm | Paper sizes(1) | | DPI_72 / DPI_150 / DPI_300 / DPI_600 | dots per inch | Screen/print resolutions | | EARTH_GRAVITY | m/s | | | EARTH_CIRCUMFERENCE | m | | | EARTH_MASS | kg | | | EARTH_RADIUS | m | | | G0 | m/s2 | Standard gravity | | GRAVITATION | kg-1·m3·s-2 | Gravitational constant | | SPEED_OF_LIGHT | m/s | | | SPEED_OF_SOUND_IN_AIR | m/s | at 20 ℃ | | SPEED_OF_SOUND_IN_WATER | m/s | at 20 ℃ | | US_ANSI_A ... US_ANSI_E | 2d vector of inch | Paper sizes(1) | | US_ARCH_A ... US_ARCH_E | 2d vector of inch | Paper sizes(1) | | US_LETTER / US_HALF_LETTER | 2d vector of inch | Paper sizes(1) | | US_LEGAL / US_JUNIOR_LEGAL | 2d vector of inch | Paper sizes(1) |

  • (1) - all paper sizes are also available as landscape presets (using _LANDSCAPE as suffix).

Densities of selected materials:

| Var name | Unit | |--------------|---------| | AIR | kg/m3 | | ALUMINIUM | kg/m3 | | CONCRETE | kg/m3 | | COPPER | kg/m3 | | DIAMOND | kg/m3 | | GLASS | kg/m3 | | GOLD | kg/m3 | | ICE | kg/m3 | | IRON | kg/m3 | | NYLON | kg/m3 | | PLASTIC | kg/m3 | | PLATINUM | kg/m3 | | SAND | kg/m3 | | SALT_WATER | kg/m3 | | SILICON | kg/m3 | | SILVER | kg/m3 | | STEEL | kg/m3 | | TITANIUM | kg/m3 | | WATER | kg/m3 | | WOOD | kg/m3 |

Domain-specific language

The package includes a minimal Lisp-like formula expression language to compute, combine or convert quantities in a more concise style than the default JS API provided by this package.

The minimal domain specific language defined here only includes the following functions (all following basic Lisp syntax, also see examples below):

  • Math operators: +, -, *, / to combine two or more quantities (all quantities MUST be compatible)
  • area: Computes the area of a given 2D quantity (e.g. (area DIN_A4) computes the area of a sheet of paper)
  • volume: Computes the volume of a given 3D quantity
  • width: Returns the 1st dimension quantity of a 2D/3D quantity (e.g. (width DIN_A4) = 210mm)
  • height: Returns the 2nd dimension quantity of a 2D/3D quantity
  • depth: Returns the 3rd dimension quantity of a 3D quantity

Any other symbol is interpreted as quantity or pre-defined registered unit or constant (see readme). Quantities always have to be given without whitespace, i.e. 100mm vs. 100 mm.

import { $eval } from "@thi.ng/units";

// compute weight in grams of A4 paper with 320 grams per square meter
console.log($eval(`(g (* (area din_a4) 320gsm))`));
// 19.9584

// compute weight in kg of 1/2 inch thick 200x300mm glass plate
console.log($eval(`(kg (* 200mm 300mm 0.5in 2500kg/m3))`));
// 1.905

// same as previous but using the `glass` density preset
console.log($eval(`(kg (* 200mm 300mm 0.5in glass))`));
// 1.905

Status

BETA - possibly breaking changes forthcoming

Search or submit any issues for this package

Installation

yarn add @thi.ng/units

ESM import:

import * as units from "@thi.ng/units";

Browser ESM import:

<script type="module" src="https://esm.run/@thi.ng/units"></script>

JSDelivr documentation

For Node.js REPL:

const units = await import("@thi.ng/units");

Package sizes (brotli'd, pre-treeshake): ESM: 5.69 KB

Dependencies

Note: @thi.ng/api is in most cases a type-only import (not used at runtime)

API

Generated API docs

Authors

If this project contributes to an academic publication, please cite it as:

@misc{thing-units,
  title = "@thi.ng/units",
  author = "Karsten Schmidt",
  note = "https://thi.ng/units",
  year = 2021
}

License

© 2021 - 2026 Karsten Schmidt // Apache License 2.0