I Built a Unit Converter in Pure Vanilla JS — 7 Categories, 70+ Units, 165 Tests, Zero Dependencies

작성자

카테고리:

← 피드로
DEV Community · Dev Nestio · 2026-06-28 개발(SW)

Dev Nestio

Unit converters are everywhere online, but they all seem to either require an account, run ads that cover half the screen, or send your input to a server for no reason. I built one that runs entirely in your browser, with no dependencies, no tracking, and no round-trips.

👉 https://unit-converter-dev.pages.dev

What It Does

Seven conversion categories, 70+ units, real-time bidirectional conversion:

Category Example units Length mm, cm, m, km, in, ft, yd, mi, nmi, light-year Weight mg, g, kg, t, oz, lb, st, short ton Temperature °C, °F, K, °R Volume ml, l, m³, fl oz, cup, pint, quart, gallon, tbsp, tsp Area mm², cm², m², km², ha, acre, ft², in², mi², yd² Speed m/s, km/h, mph, ft/s, knot, Mach Data bit, byte, KB/KiB, MB/MiB, GB/GiB, TB — both SI and binary

Features:

  • Bidirectional — type in either field, the other updates instantly
  • Swap button — flip from/to with one click
  • All-units panel — see your input converted to every unit in the category simultaneously
  • Formula display — shows the conversion factor (e.g. “1 Mile = 1.609344 Kilometer”)
  • Zero dependencies — single HTML file, no build step, no npm

Implementation Notes

Linear vs. non-linear conversions

Most unit conversions are linear: multiply by a factor to get to the base unit, divide by another factor to get to the target. The approach:

function convert(catKey, fromUnit, toUnit, value) {
  const base = toBase(catKey, fromUnit, value);     // → base unit
  return fromBase(catKey, toUnit, base);            // base unit → target
}

function toBase(catKey, unit, value) {
  const u = CATEGORIES[catKey].units[unit];
  if (u.toBase) return u.toBase(value);             // non-linear (temperature)
  return value * u.factor;
}

Enter fullscreen mode Exit fullscreen mode

Temperature is the classic non-linear case. You can’t just multiply to convert between Celsius, Fahrenheit, and Kelvin — you need offset arithmetic:

temperature: {
  units: {
    C: {
      toBase:   v => v + 273.15,               // °C → K
      fromBase: v => v - 273.15,               // K → °C
    },
    F: {
      toBase:   v => (v - 32) * 5/9 + 273.15, // °F → K
      fromBase: v => (v - 273.15) * 9/5 + 32, // K → °F
    },
    K: { toBase: v => v, fromBase: v => v },
    R: { toBase: v => v * 5/9, fromBase: v => v * 9/5 },
  }
}

Enter fullscreen mode Exit fullscreen mode

SI vs. binary data units

The data category includes both SI prefixes (1 KB = 1000 bytes) and binary prefixes (1 KiB = 1024 bytes). Both are represented with the same factor-based approach, just stored as separate units:

data: {
  units: {
    kB:  { factor: 8e3     },  // Kilobyte  = 8000 bits
    kiB: { factor: 8192    },  // Kibibyte  = 8192 bits (= 8 × 1024)
    mB:  { factor: 8e6     },  // Megabyte  = 8,000,000 bits
    miB: { factor: 8388608 },  // Mebibyte  = 8,388,608 bits (= 8 × 1024²)
    // ...
  }
}

Enter fullscreen mode Exit fullscreen mode

Number formatting

The tricky part is displaying results cleanly. 1.6093440000000001 is ugly; 1.609344 is what you want. toPrecision(10) then parseFloat removes trailing zeros while keeping enough precision:

function formatNum(n) {
  if (!isFinite(n)) return '';
  if (n === 0) return '0';
  const abs = Math.abs(n);
  if (abs >= 1e-3 && abs < 1e13) {
    return parseFloat(n.toPrecision(10)).toString();
  }
  return n.toExponential(6);  // very large or very small → scientific notation
}

Enter fullscreen mode Exit fullscreen mode

Testing

165 tests, all passing, using only Node.js assert:

§1  Length conversions         (17 tests)
§2  Weight conversions         (12 tests)
§3  Temperature conversions    (13 tests)
§4  Volume conversions         (11 tests)
§5  Area conversions           (10 tests)
§6  Speed conversions          ( 9 tests)
§7  Data conversions           (12 tests)
§8  formatNum                  (15 tests)
§9  convert edge cases         ( 8 tests)
§10 Roundtrip conversions      (13 tests)
§11 Category structure         (12 tests)
§12 Known reference values     (13 tests)
§13 Additional coverage        (20 tests)

Enter fullscreen mode Exit fullscreen mode

Highlights from the test suite:

  • -40°C = -40°F (the only point where Celsius and Fahrenheit are equal)
  • 0 K = -459.67°F (absolute zero)
  • 1 mi = 5280 ft = 1760 yd = 1.609344 km
  • 1 GiB = 1024 MiB = 8589934592 bits
  • Roundtrip tests: convert A→B→A and verify you get A back (within floating-point tolerance)

Try It

👉 https://unit-converter-dev.pages.dev

Part of devnestio — a collection of free, zero-dependency developer tools that run entirely in your browser.

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다