{"id":13990800,"url":"https://github.com/jscheiny/safe-units","last_synced_at":"2025-07-22T13:31:32.435Z","repository":{"id":32707441,"uuid":"132954211","full_name":"jscheiny/safe-units","owner":"jscheiny","description":"Type-safe TypeScript units of measure 👷📏","archived":false,"fork":false,"pushed_at":"2024-10-23T14:12:36.000Z","size":876,"stargazers_count":264,"open_issues_count":2,"forks_count":14,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-23T15:56:15.248Z","etag":null,"topics":["dimensional-analysis","typesafe","typescript","units","units-of-measure"],"latest_commit_sha":null,"homepage":"https://jscheiny.github.io/safe-units","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jscheiny.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-10T21:04:29.000Z","updated_at":"2024-10-23T14:12:41.000Z","dependencies_parsed_at":"2024-08-09T13:21:45.798Z","dependency_job_id":null,"html_url":"https://github.com/jscheiny/safe-units","commit_stats":{"total_commits":173,"total_committers":4,"mean_commits":43.25,"dds":"0.052023121387283267","last_synced_commit":"44af31bd52859918cbe31a955749f7f02c045cad"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jscheiny%2Fsafe-units","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jscheiny%2Fsafe-units/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jscheiny%2Fsafe-units/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jscheiny%2Fsafe-units/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jscheiny","download_url":"https://codeload.github.com/jscheiny/safe-units/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227099014,"owners_count":17730693,"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":["dimensional-analysis","typesafe","typescript","units","units-of-measure"],"created_at":"2024-08-09T13:03:16.042Z","updated_at":"2024-11-29T10:31:51.038Z","avatar_url":"https://github.com/jscheiny.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Safe Units\n\n[![NPM Version](https://img.shields.io/npm/v/safe-units.svg)](https://www.npmjs.com/package/safe-units) [![MIT License](https://img.shields.io/npm/l/safe-units.svg)](https://github.com/jscheiny/safe-units/blob/master/LICENSE)\n\nSafe Units is a type safe library for using units of measurement in TypeScript.  Safe Units provides an implementation of an SI based unit system but is flexible enough to allow users to create their own unit systems which can be independent or can interoperate with the built-in units. Users can also make unit systems for any numeric type they'd like not just the JavaScript `number` type. This library requires TypeScript 3.2 or higher.\n\n```ts\nimport { Length, Measure, meters, seconds, Time, Velocity } from \"safe-units\";\n\nconst length: Length = Measure.of(30, meters);\nconst time: Time = Measure.of(15, seconds);\nconst velocity: Velocity = length.over(time);\n\nconsole.log(length.toString()); // 30 m\nconsole.log(time.toString()); // 15 s\nconsole.log(velocity.toString()); // 2 m * s^-1\n\n// @ts-expect-error ERROR: A measure of m*s isn't assignable to a measure of m/s.\nconst error: Velocity = length.times(time);\n```\n\n## Features\n\n⭐\u0026nbsp; Compile-time unit arithmetic for typesafe dimensional analysis (with exponents between -5 and +5)!\n\n⭐\u0026nbsp; Large library of predefined units including SI (with prefixes), Imperial, and US customary units!\n\n⭐\u0026nbsp; Ability to add your own unit system that can work with built-in units!\n\n⭐\u0026nbsp; Long build times \u0026 cryptic error messages!\n\n## Prerequisites\n\nSafe units is written in TypeScript and should be consumed by TypeScript users to take full advantage of what it provides. In addition you will need the following:\n\n- [TypeScript](http://www.typescriptlang.org/) 3.2 or later\n- [Strict null checks](https://www.typescriptlang.org/docs/handbook/compiler-options.html) enabled for your project\n\n## Installation\n\n```\nnpm install safe-units\n```\n\nor \n\n```\nyarn add safe-units\n```\n\n## Examples\n\n### Unit Arithmetic\n\n```ts\nimport { bars, kilograms, Measure, meters, milli, seconds } from \"safe-units\";\n\nconst width = Measure.of(3, meters);\nconst height = Measure.of(4, meters);\nconst area = width.times(height).scale(0.5);\n\nconst mass = Measure.of(30, kilograms);\nconst mps2 = meters.per(seconds.squared());\nconst acceleration = Measure.of(9.8, mps2);\n\nconst force = mass.times(acceleration); // 294 N\nconst pressure = force.over(area); // 49 Pa\nconst maxPressure = Measure.of(0.5, milli(bars)); // 0.5 mbar\npressure.lt(maxPressure); // true\n\n```\n\n### Type Errors\n\n```ts\nimport { Force, hours, Length, Measure, meters, seconds, Time } from \"safe-units\";\n\nconst length: Length = Measure.of(10, meters);\nconst time: Time = Measure.of(10, seconds);\n\n// @ts-expect-error - Measures of different units cannot be added\nlength.plus(time);\n\n// @ts-expect-error - Measures of different units cannot be compared\nlength.eq(time);\n\n// @ts-expect-error - Measure of m/s is not assigneable to measure of kg*m/s^2\nconst force: Force = length.over(time);\n\n// @ts-expect-error - Cannot convert length measure to time measure\nlength.in(hours);\n\n```\n\n### Naming Units\n\n```ts\nimport { days, Measure, mega, micro, miles, speedOfLight, yards } from \"safe-units\";\n\nconst furlongs = Measure.of(220, yards, \"fur\");\n\nMeasure.of(8, furlongs).in(miles); // \"1 mi\"\nMeasure.of(1, miles).in(furlongs); // \"8 fur\"\n\nconst fortnights = Measure.of(14, days, \"ftn\");\nconst megafurlong = mega(furlongs);\nconst microfortnight = micro(fortnights);\nconst mfPerUFtn = megafurlong.per(microfortnight).withSymbol(\"Mfur/µftn\");\n\nspeedOfLight.in(mfPerUFtn); // \"1.8026174997852542 Mfur/µftn\"\n\n```\n\n### Deriving Quantities\n\n```ts\nimport { kilograms, liters, Mass, Measure, Volume } from \"safe-units\";\n\nconst VolumeDensity = Mass.over(Volume);\ntype VolumeDensity = typeof VolumeDensity;\n\nconst mass = Measure.of(30, kilograms);\nconst volume = Measure.of(3, liters);\n\nconst density: VolumeDensity = mass.over(volume);\n\nconsole.log(density.toString()); // 10 kg * m^-3\n\n```\n\n### Defining Unit Systems\n\n```ts\nimport { Measure, UnitSystem } from \"safe-units\";\n\nconst GameUnitSystem = UnitSystem.from({\n    frames: \"fr\",\n    time: \"s\",\n});\n\nconst frames = Measure.dimension(GameUnitSystem, \"frames\");\nconst seconds = Measure.dimension(GameUnitSystem, \"time\");\n\nconst Frames = frames;\ntype Frames = typeof frames;\n\nconst Time = seconds;\ntype Time = typeof seconds;\n\nconst FrameRate = Frames.over(Time);\ntype FrameRate = typeof FrameRate;\n\nconst fps: FrameRate = frames.per(seconds).withSymbol(\"fps\");\n\nconst minFrameRate = Measure.of(60, fps);\n\nconst measuredFrames = Measure.of(8000, frames);\nconst elapsedTime = Measure.of(120, seconds);\nconst measuredFps: FrameRate = measuredFrames.over(elapsedTime);\n\nif (measuredFps.lt(minFrameRate)) {\n    // Optimize\n}\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjscheiny%2Fsafe-units","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjscheiny%2Fsafe-units","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjscheiny%2Fsafe-units/lists"}