Physical quantities have dimensions. Meters measure length. Seconds measure time. You can't add them — it's physically meaningless. Yet most programs represent both as plain number, and the compiler can't help you catch the mistake.
unitsafe encodes dimensional information into TypeScript's type system. The compiler rejects invalid operations at build time, and the library provides ergonomic unit conversions with runtime metadata for display and formatting.
Why not just use plain numbers with naming conventions?
distanceMeters + timeSeconds compiles and runs silently, producing garbage
Naming conventions don't compose: what type should distanceMeters / timeSeconds have?
Off-by-one scale errors (forgetting to convert km to m) are invisible until production
unitsafe gives you:
Compile-time errors for dimension mismatches (add/sub/compare)
Automatic dimension composition for multiply/divide (m/s, m^2, kg*m/s^2)
Type-safe conversions between compatible units (km <-> m, s <-> ms, C <-> F)
Branded types that prevent accidental mixing of raw numbers with quantities
Tiny runtime — each quantity is a 4-property object; no classes, no prototypes
Physical quantities have dimensions. Meters measure length. Seconds measure time. You can't add them — it's physically meaningless. Yet most programs represent both as plain number, and the compiler can't help you catch the mistake.
unitsafe encodes dimensional information into TypeScript's type system. The compiler rejects invalid operations at build time, and the library provides ergonomic unit conversions with runtime metadata for display and formatting.
Why not just use plain numbers with naming conventions?
distanceMeters + timeSeconds compiles and runs silently, producing garbage Naming conventions don't compose: what type should distanceMeters / timeSeconds have? Off-by-one scale errors (forgetting to convert km to m) are invisible until production unitsafe gives you:
Compile-time errors for dimension mismatches (add/sub/compare) Automatic dimension composition for multiply/divide (m/s, m^2, kg*m/s^2) Type-safe conversions between compatible units (km <-> m, s <-> ms, C <-> F) Branded types that prevent accidental mixing of raw numbers with quantities Tiny runtime — each quantity is a 4-property object; no classes, no prototypes