{"id":28089458,"url":"https://github.com/alanhussey/unit-system","last_synced_at":"2025-09-01T12:38:35.336Z","repository":{"id":57386436,"uuid":"155317566","full_name":"alanhussey/unit-system","owner":"alanhussey","description":"A library for defining unit systems and performing unit-safe calculations","archived":false,"fork":false,"pushed_at":"2023-11-13T07:03:36.000Z","size":392,"stargazers_count":4,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-23T06:47:17.314Z","etag":null,"topics":["converter","javascript","javascript-library","measure-conversion","measurement","measurement-units","system","unit","unit-safety","units","units-of-measurement"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/unit-system","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alanhussey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-30T03:16:34.000Z","updated_at":"2022-12-14T15:52:33.000Z","dependencies_parsed_at":"2022-09-05T05:00:23.431Z","dependency_job_id":null,"html_url":"https://github.com/alanhussey/unit-system","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alanhussey%2Funit-system","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alanhussey%2Funit-system/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alanhussey%2Funit-system/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alanhussey%2Funit-system/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alanhussey","download_url":"https://codeload.github.com/alanhussey/unit-system/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253948387,"owners_count":21988953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["converter","javascript","javascript-library","measure-conversion","measurement","measurement-units","system","unit","unit-safety","units","units-of-measurement"],"created_at":"2025-05-13T12:58:26.881Z","updated_at":"2025-05-13T12:58:27.440Z","avatar_url":"https://github.com/alanhussey.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `unit-system`\n\nΜΕΤΡΩ ΧΡΩ\n\n_Use the measure_\n\nA library for defining unit systems and performing unit-safe calculations\n\n## Demo\n\n```js\nconst { createUnitSystem, conversion } = require('unit-system');\n\nconst { createUnit, m, equal, add } = createUnitSystem();\n\nconst inch = createUnit('inch');\nconst yard = createUnit('yard', {\n  alias: ['yd', 'yard', 'yards'],\n});\n\nconst foot = createUnit('foot', {\n  alias: 'feet',\n  convert: {\n    to: [yard, conversion.divideBy(3)],\n    from: [inch, conversion.divideBy(12)],\n  },\n});\n\nconst twoYards = add(m`1 yard`, m`3 feet`);\n\nequal(twoYards, m(72, inch)) === true;\n```\n\n## Documentation\n\n### `createUnitSystem(units)`\n\nMost uses of `unit-system` start with `createUnitSystem()`.\n\n```js\nconst { createUnitSystem } = require('unit-system');\n\nconst { createUnit, m, convert, system } = createUnitSystem();\n```\n\n#### `createUnit(name, options)`\n\nCreates a new `Unit` and automatically registers it with `system` (the `UnitSystem` created by `createUnitSystem`).\n\n```js\nconst inch = createUnit('inch', { alias: 'inches' });\n\nconst foot = createUnit('foot', {\n  convert: {\n    from: [inch, conversion.divideBy(12)],\n  },\n});\n```\n\n#### `m(number, unit)`\n\nShorthand function for creating new `Measurement` instances. If a unit is defined with an alias, that alias can be used instead of passing in the unit. (see `UnitSystem#measure()` for details)\n\n```js\nm`12 inches`;\n```\n\n#### `convert(measurement, unit)`\n\nGiven a `Measurement` and a `Unit`, `convert(measurement, unit)` will attempt to convert that measurement to the given unit. (see `UnitSystem#convert()` for details)\n\n```js\nconvert(m`24 inches`, foot);\n// =\u003e new Measurement(2, foot)\n```\n\n#### `system`\n\nThe `UnitSystem` created by `createUnitSystem`.\n\n### `conversion`\n\nA collection of converter creators. A converter is an object with `forward` and `backward` methods, meant for converting between two units.\n\nConverters shouldn't be used directly. Instead, define them when creating a unit, and `UnitSystem` will be able to automatically convert for you.\n\n```js\nconst { conversion } = require('unit-system');\n```\n\n#### `conversion.slopeIntercept(slope, intercept = 0)`\n\nGiven a `slope` and an optional `intercept`, produces a converter.\n\n_Also exported as: `multiplyBy`, `times`_\n\n```js\nconst celsiusToFahrenheit = conversion.slopeIntercept(9 / 5, 32);\n\ncelsiusToFahrenheit.forward(100) === 212;\ncelsiusToFahrenheit.backward(32) === 0;\n```\n\n#### `conversion.divideBy(divisor)`\n\nA special case of `multiplyBy`, useful when defining the reverse conversion is clearer.\n\n```js\nconst feetToInches = conversion.divideBy(12);\n\nfeetToInches.forward(3) === 36;\nfeetToInches.backward(12) === 1;\n```\n\n#### `conversion.twoPoint([x1, y1], [x2, y2])`\n\nGiven two example points on a line, produces a converter. Useful when a conversion can be more clearly expressed in terms of easily-understood examples.\n\n_Also exported as: `fromExamples`, `byExample`_\n\n```js\nconst freezing = [0, 32];\nconst boiling = [100, 212];\nconst celsiusToFahrenheit = conversion.twoPoint(freezing, boiling);\n\ncelsiusToFahrenheit.forward(100) === 212;\ncelsiusToFahrenheit.backward(32) === 0;\n```\n\n#### `conversion.addConstant(constant)`\n\nGiven a constant value, produces a converter. A special case of `slopeIntercept` where `slope` is always `1`.\n\n_Also exported as: `add`, `constant`_\n\n```js\nconst celsiusToKelvin = conversion.addConstant(273.15);\n\ncelsiusToKelvin.forward(0) === 273.15;\ncelsiusToKelvin.backward(-272.15) === 1;\n```\n\n### `new Unit(name)`\n\nThe base unit type.\n\n```js\nconst { Unit } = require('unit-system');\n\nconst inch = new Unit('inch');\n\ninch.name === 'inch';\n```\n\n### `new Measurement(number, unit)`\n\nA value type representing a number and its unit.\n\n```js\nconst { Measurement } = require('unit-system');\n\nconst oneInch = new Measurement(1, inch);\n\noneInch.value === 1;\noneInch.unit === inch;\n```\n\n### `new UnitSystem(units)`\n\nA collection of units. Internally tracks aliases for units (used by `m` to look up the corresponding unit) and converters.\n\n```js\nconst { UnitSystem } = require('unit-system');\n\nconst myUnitSystem = new UnitSystem([\n  [inch, { alias: 'inches' }],\n  [foot, { convert: { from: [inch, conversion.divideBy(12)] } }],\n]);\n\nmyUnitSystem.getUnitForAlias('inches') === inch;\n\nmyUnitSystem.convert(new Measurement(12, inch), foot);\n// =\u003e new Measurement(1, foot)\n```\n\n#### `.merge(...unitSystems)`\n\nTakes one or more other `UnitSystem`s and copies this unit into this one.\n\n```js\nconst mySystem = new UnitSystem([[new Unit('inch'), { alias: 'inches' }]]);\n\nconst systemA = new UnitSystem([[new Unit('foot')]]);\nconst systemB = new UnitSystem([[new Unit('yard')]]);\nconst systemC = new UnitSystem([[new Unit('mile')]]);\n\nmySystem.merge(systemA, systemB, systemC);\n```\n\n#### `.register(unit, { alias, convert })`\n\nRegisters the given unit within the system.\n\n```js\nconst inch = new Unit('inch');\nsystem.register(inch);\n```\n\nIf `alias` is provided, that unit can now be referenced by that alias.\n\n```js\nsystem.register(inch, { alias: 'inches' });\n```\n\nIf `convert` is provided, its properties `to` and `from` are used to register converters between two units.\n\n```js\nsystem.register(inch, {\n  convert: {\n    to: [centimeter, multiplyBy(2.54)],\n    from: [foot, divideBy(12)],\n  },\n});\n```\n\n#### `.registerAll(units)`\n\nLike the first argument to `new UnitSystem(units)`, registers all the given units.\n\n#### `.addConverter(startUnit, endUnit, converter)`\n\nAdds a converter for units that have already been registered.\n\n```js\nconst inch = new Unit('inch');\nconst foot = new Unit('foot');\nconst system = new UnitSystem([[inch], [foot]]);\nsystem.addConverter(inch, foot, divideBy(12));\n```\n\n#### `.getUnitForAlias(alias)`\n\nLooks up the corresponding unit for the given alias.\n\n```js\nsystem.getUnitForAlias('inches') === inch;\n```\n\n#### `.convert(measurement, unit|string)`\n\n`convert` will take the given measurement and attempt to convert it the desired unit. It may take multiple hops to make that happen.\n\nIf `unit` is a string, `convert` will assume it is an alias and will look up the corresponding unit.\n\nConsider a `UnitSystem` that defines kilometers, meters, centimeters, inches, feet, and miles:\n\n```js\nconst kilometer = createUnit('kilometer');\nconst meter = createUnit('meter', {\n  convert: {\n    from: [kilometer, conversion.multiplyBy(1000)],\n  },\n});\nconst centimeter = createUnit('centimeter', {\n  convert: {\n    from: [meter, conversion.multiplyBy(100)],\n  },\n});\n\nconst inch = createUnit('inch', {\n  convert: {\n    to: [centimeter, conversion.multiplyBy(2.54)],\n  },\n});\nconst foot = createUnit('foot', {\n  convert: {\n    from: [inch, conversion.divideBy(12)],\n  },\n});\nconst mile = createUnit('mile', {\n  alias: 'mile',\n  convert: {\n    to: [foot, conversion.multiplyBy(5280)],\n  },\n});\n```\n\nIt can convert miles to kilometers, even though a converter between those two was never explicitly declared:\n\n```js\nconst oneMileInKilometers = system.convert(m`1 mile`, kilometer);\noneMileInKilometers.value === 1.609344;\n```\n\nWhen a multi-step converter is created, it will be cached, to save on the lookup time.\n\n#### `.add(...measurements)`\n\n`add` will take the given measurements and attempt to add them together, converting them if needed.\n\nConsider a `UnitSystem` that defines centimeters, inches, and feet:\n\n```js\nconst centimeter = createUnit('centimeter');\nconst inch = createUnit('inch', {\n  alias: 'inches',\n  convert: {\n    to: [centimeter, conversion.multiplyBy(2.54)],\n  },\n});\nconst foot = createUnit('foot', {\n  alias: 'feet',\n  convert: {\n    from: [inch, conversion.divideBy(12)],\n  },\n});\n```\n\nIt can add up several values in each of those units, converting them to the same unit:\n\n```js\nconst eightFeet = system.add(\n  m`2 feet`,\n  m`18 inches`,\n  m`2 inches`,\n  m(15.24, centimeter),\n  m`10 inches`,\n  m`3 feet`\n);\neightFeet.value === 8;\neightFeet.unit === foot;\n```\n\n#### `.subtract(measurement1, measurement2)`\n\n`subtract` will take the two given measurements and attempt to subtract them, converting them if needed.\n\nConsider a `UnitSystem` that defines centimeters and inches:\n\n```js\nconst centimeter = createUnit('centimeter');\nconst inch = createUnit('inch', {\n  alias: 'inches',\n  convert: {\n    to: [centimeter, conversion.multiplyBy(2.54)],\n  },\n});\n```\n\nIt can subtract two values in either of those units, converting them to the same unit:\n\n```js\nconst eighteenInches = system.subtract(m`24 inches`, m(15.24, centimeter));\neighteenInches.value === 18;\neighteenInches.unit === inch;\n```\n\n`subtract` does not support operating on more than 2 measurements at a time.\n\n#### `.multiply(measurement, ...numbers)`\n\n`multiply` will take the a measurement and multiply it with one or more numbers. The order of arguments is not important. Only one measurement can be supplied.\n\n```js\nconst twelveInches = system.multiply(m`4 inches`, 3);\ntwelveInches.value === 12;\ntwelveInches.unit === inch;\n```\n\n#### `.divide(measurement, measurement|number)`\n\n`divide` will take a measurement and divide it by the second argument, returning either another measurement or a number, depending on the type of the second argument.\n\n```js\nconst fourInches = system.divide(m`12 inches`, 3);\nfourInches.value === 4;\nfourInches.unit === inch;\n```\n\n```js\nsystem.divide(m`18 inches`, m`6 inches`) === 3;\n```\n\nIt will also automatically convert units when dividing two measurements:\n\n```js\nsystem.divide(m`3 feet`, m`18 inches`) === 2;\n```\n\n#### `.equal(measurement, measurement)`\n\n`equal` will return `true` if the two measurements have the same value and unit (after conversion). Otherwise it returns `false`.\n\n```js\nsystem.equal(m`12 inches`, m`1 foot`) === true;\n```\n\n#### `.lessThan(measurement, measurement)`\n\n`lessThan` will return `true` if the first measurement is less than the second (after conversion). Otherwise it returns `false`.\n\n#### `.lessThanOrEqual(measurement, measurement)`\n\n`lessThanOrEqual` will return `true` if the first measurement is less than or equal to the second (after conversion). Otherwise it returns `false`.\n\n#### `.greaterThan(measurement, measurement)`\n\n`greaterThan` will return `true` if the first measurement is greater than the second (after conversion). Otherwise it returns `false`.\n\n#### `.greaterThanOrEqual(measurement, measurement)`\n\n`greaterThanOrEqual` will return `true` if the first measurement is greater than or equal to the second (after conversion). Otherwise it returns `false`.\n\n#### `.measure(value, unit)`\n\nShorthand function for creating new `Measurement` instances. If a unit is defined with an alias, that alias can be used instead of passing in the unit.\n\n```js\n// All of these are equivalent to `new Measurement(12, inch)`\nsystem.measure`12 inches`;\nsystem.measure`12inches`;\nsystem.measure`12 ${inch}`;\nsystem.measure`12`.inches;\nsystem.measure(12).inches;\nsystem.measure(12, inch);\n```\n\n`measure` is bound to `system` (its `this` cannot be changed), so it can be \"detached\" and used as a bare function (but still retain access to your unit system):\n\n```js\nconst m = system.measure;\nm`12 inches`;\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falanhussey%2Funit-system","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falanhussey%2Funit-system","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falanhussey%2Funit-system/lists"}