DEV Community

flycran
flycran

Posted on

smart-unit: The Elegant Unit Conversion Library JavaScript Developers Need

smart-unit: The Elegant Unit Conversion Library JavaScript Developers Need

Stop wrestling with rigid unit libraries. Format file sizes, lengths, time, and financial amounts with a single, intuitive API.


The Problem: Why Existing Solutions Fall Short

If you have ever tried to format file sizes in JavaScript, you know the pain. Most libraries force you into one of two uncomfortable positions:

  1. Too specific: Libraries like bytes or filesize only handle file sizes. Need to format frequency, length, or currency? Install another dependency.

  2. Too verbose: Generic conversion libraries require defining every conversion manually, creating bloated code for simple tasks.

// The old way: verbose and inflexible
const bytes = require('bytes');
const filesize = require('filesize');
// Still need something else for time, length, currency...
Enter fullscreen mode Exit fullscreen mode

What if you could define any unit chain once and get intelligent formatting with a clean, minimal API?


Meet smart-unit

smart-unit is a lightweight TypeScript-first library that handles unit conversion with automatic unit selection. It is designed for developers who want elegance without sacrificing power.

npm install smart-unit
Enter fullscreen mode Exit fullscreen mode

Core Concepts: Simple Yet Powerful

The genius of smart-unit lies in its declarative unit chain definition. You define your units and conversion ratios once, then let the library handle the rest.

File Size Formatting

import { SmartUnit } from 'smart-unit';

const fileSize = new SmartUnit(['B', 'KB', 'MB', 'GB', 'TB'], {
  baseDigit: 1024,
});

console.log(fileSize.format(1024));        // "1KB"
console.log(fileSize.format(1536));        // "1.5KB"
console.log(fileSize.format(1024 * 1024 * 100));  // "100MB"
console.log(fileSize.format(1024 * 1024 * 1024 * 5));  // "5GB"
Enter fullscreen mode Exit fullscreen mode

Notice how format(1536) automatically selects "1.5KB" instead of "1536B" or "0.0015MB". The library intelligently picks the most readable unit.

Length Units with Variable Ratios

Not all unit systems use consistent base numbers. The metric system for length varies:

const length = new SmartUnit(['mm', 10, 'cm', 100, 'm', 1000, 'km']);

console.log(length.format(1500));      // "1.5m"
console.log(length.format(1500000));   // "1.5km"
console.log(length.format(25));        // "2.5cm"
Enter fullscreen mode Exit fullscreen mode

By specifying individual ratios (10, 100, 1000), you can model any unit hierarchy accurately.


Bidirectional Conversion: Parse and Format

smart-unit is not just for display. It can parse formatted strings back to base values:

const time = new SmartUnit(['ms', 1000, 's', 60, 'm', 60, 'h']);

console.log(time.parse('90s'), 'ms');   // 90000 ms
console.log(time.parse('2.5h'), 'ms');  // 9000000 ms
console.log(time.parse('30m'), 'ms');   // 1800000 ms
Enter fullscreen mode Exit fullscreen mode

This bidirectional capability makes it perfect for configuration files, user inputs, and data serialization.


High-Precision Mode: Beyond JavaScript's Limits

JavaScript's number type has a safe integer limit of 2^53 - 1 (about 9 quadrillion). For financial calculations or scientific applications, this is a dealbreaker.

smart-unit integrates with decimal.js for arbitrary-precision arithmetic:

const bigLength = new SmartUnit(['pm', 1000, 'nm', 1000, 'μm', 1000, 'mm', 1000, 'm'], {
  useDecimal: true,
});

console.log(bigLength.format('1000'));      // "1nm"
console.log(bigLength.format('1000000'));   // "1μm"

// BigInt support - beyond JS safe integer limit
const bigNumber = 123456789012345678901234567890n;
console.log('Formatted:', bigLength.format(bigNumber));
Enter fullscreen mode Exit fullscreen mode

Financial Calculations

Currency and financial data often exceed safe integer limits while requiring precise decimal handling:

const currency = new SmartUnit(['', 'K', 'M', 'B', 'T'], {
  baseDigit: 1000,
  useDecimal: true,
  fractionDigits: 2,
});

console.log(currency.format('12345678901234567890'));  // "12345678.90T"
Enter fullscreen mode Exit fullscreen mode

The fractionDigits: 2 ensures consistent decimal places for monetary values.


Why smart-unit Wins

Feature bytes filesize smart-unit
File sizes
Custom units
Bidirectional
High precision
BigInt support
TypeScript Partial Partial ✅ First-class
Bundle size ~1KB ~2KB ~2KB

smart-unit gives you the footprint of a specialized library with the flexibility of a generic one.


Real-World Use Cases

Data Transfer Rate

const bitrate = new SmartUnit(['bps', 'Kbps', 'Mbps', 'Gbps'], {
  baseDigit: 1000,
  fractionDigits: 1,
});

bitrate.format(1500000);  // "1.5Mbps"
Enter fullscreen mode Exit fullscreen mode

Frequency

const freq = new SmartUnit(['Hz', 'kHz', 'MHz', 'GHz'], {
  baseDigit: 1000,
  fractionDigits: 2,
});

freq.format(2400000000);  // "2.40GHz"
Enter fullscreen mode Exit fullscreen mode

Storage Capacity with Custom Thresholds

const storage = new SmartUnit(['B', 'KB', 'MB', 'GB', 'TB'], {
  baseDigit: 1024,
  threshold: 0.9,  // Switch units at 90% of next unit
});
Enter fullscreen mode Exit fullscreen mode

TypeScript-First Design

smart-unit is written in TypeScript and provides full type safety:

import { SmartUnit } from 'smart-unit';
import type { Decimal } from 'decimal.js';

// Regular mode - returns number
const regular = new SmartUnit(['B', 'KB', 1024]);
const num: number = regular.parse('1KB');

// High-precision mode - returns Decimal
const precise = new SmartUnit(['B', 'KB', 1024], { useDecimal: true });
const dec: Decimal = precise.parse('1KB');
Enter fullscreen mode Exit fullscreen mode

Type inference works seamlessly, and the API surface is intentionally small to minimize cognitive load.


Getting Started

npm install smart-unit
Enter fullscreen mode Exit fullscreen mode
import { SmartUnit } from 'smart-unit';

// Define once, use everywhere
const size = new SmartUnit(['B', 'KB', 'MB', 'GB'], { baseDigit: 1024 });

size.format(1024 * 1024 * 100);  // "100MB"
size.parse('2.5GB');             // 2684354560
Enter fullscreen mode Exit fullscreen mode

Try It Now

Experiment with smart-unit directly in your browser on CodeSandbox.


Conclusion

smart-unit solves a universal problem with an elegant solution. Whether you are formatting file uploads, parsing user input, handling financial data, or building scientific applications, it provides the right balance of simplicity and power.

Key takeaways:

  • Define any unit chain with minimal syntax
  • Automatic optimal unit selection
  • Bidirectional conversion (format and parse)
  • High-precision mode with BigInt support
  • TypeScript-first with minimal bundle size

Give it a try in your next project. Your unit conversion code will thank you.


Links:

Top comments (0)