Quantify – Type-Safe Units of Measurement with an Elegant API

I’m excited to share a new package I’ve been working on: quantify ! It’s a type-safe units of measurement library for Dart, designed to make working with physical units safer, more readable, and efficient.

Motivation & Goals:

  • True Type Safety: I wanted to catch unit mismatch errors at compile-time, not runtime. No more accidentally adding meters to seconds!

  • Intuitive API: This project was also a bit of an API proof of concept for me. I really wanted to explore Dart’s extension methods to create a fluent and natural syntax. Think 10.m (for meters) or myLength.inKm. It was a fun experiment that I think paid off!

  • Performance: Unit conversions should be fast. quantify uses double for precision and ensures that most conversions are just a single multiplication, thanks to pre-calculated factors.

  • Operator Overloading: Performing arithmetic with quantities should feel natural, like distanceA + distanceB.

  • Easy String Representation: Getting a nicely formatted string with the value and unit symbol (e.g., “1.5 km”) should be straightforward and configurable.

What quantify offers (v0.1.0):
Since this initial version focuses on establishing the core API and type safety, the number of units is currently limited. Many more are planned for future releases

  • :white_check_mark: Type-Safe Quantities: Classes like Length, Time, Temperature, and Pressure ensure you’re working with the correct types.

  • Elegant Syntax:

final pathA = 1500.m; // Create with ease using short extensions
final pathB = 2.5.km;
double pathAInMiles = pathA.inMi; // Get value in another unit
Length pathBAsYards = pathB.asYd; // Get a new Quantity object
  • :locked: Immutable: Quantity objects are immutable for safer code.

  • :artist_palette: Highly Configurable toString():

print(pathA.toString(targetUnit: LengthUnit.kilometer, fractionDigits: 1));
// Output: "1.5 km"

// With non-breaking space and locale support (if you use 'intl')
print(pathA.toString(
  targetUnit: LengthUnit.yard,
  unitSymbolSeparator: '\u00A0', // Non-breaking space
  locale: 'de_DE', // For German number formatting
  fractionDigits: 0,
));
// Output: "1640 yd" (approx, German locale might show "1.640 yd" if grouping is active)
  • :plus: Arithmetic Operations:
final totalDistance = pathA + pathB; // pathB is auto-converted
print(totalDistance.toString(fractionDigits: 0)); // "4000 m"
  • ↔️ Comparisons & Sorting: Quantities are Comparable.

Get Started:

As this is an early version and an API exploration, your feedback is especially valuable. Bug reports, or feature requests (especially for new units!) are highly welcome. Please open an issue or a PR on GitHub.

Happy coding!
Philipp

1 Like

Hi everyone,

I’ve just released quantify v0.2.0 , and it’s a big step forward, especially in terms of unit coverage!

A huge thank you to everyone who showed interest in v0.1.0.

What’s New in v0.2.0?

Version 0.2.0 completes the foundation with all 7 SI base units now implemented.
(International System of Units: SI from French Système international d’unités)

  • All 7 SI Base Units Now Supported!

    • :white_check_mark: Mass: kg (kilogram), g, mg, t (tonne), lb, oz, st (stone), slug

    • :white_check_mark: Amount of Substance (Molar Amount): mol (mole), mmol, µmol, nmol, pmol, kmol

    • :white_check_mark: Electric Current: A (ampere), mA, µA, nA, kA

    • :white_check_mark: Luminous Intensity: cd (candela), mcd, kcd

    • These join the already existing:

      • :white_check_mark: Length: m, km, ft, mi, etc.
      • :white_check_mark: Time: s, min, h, d, etc.
      • :white_check_mark: Temperature: K, °C, °F
  • Core Principles:

    • Type Safety: Still a top priority. No accidental mixing of kilograms and amperes!

    • Intuitive API: The fluent syntax like 10.kg or myCurrent.inMilliamperes is now available for all new base units.

    • Performance & Immutability: These remain core tenets.

    • Configurable toString(): Works seamlessly with all new units.

I’m excited about the library’s progress! Your feedback, bug reports, feature requests (especially for new derived units!), and contributions are always welcome. Please open an issue or PR on GitHub.