Skip to main content

Command Palette

Search for a command to run...

Unit conversion without a library: length, weight, and temperature in JavaScript

Updated
•4 min read•View as Markdown

Converting units seems trivial until you need to do it correctly. Multiply by a factor? That works for length — meters to feet, kilometers to miles — but temperature needs an offset, not just a multiplier. And weight has the added complication that "pound" means different things in different contexts (avoirdupois vs. troy).

Here is how to build a unit converter that handles all three correctly, and what the edge cases actually are.

Length and weight: multiply by a factor

For units within the same system, conversion is just multiplication. The trick is to pick a canonical unit (say, meters for length, kilograms for weight) and convert everything through it:

// Length: canonical unit = meters
const LENGTH_TO_METERS = {
  mm: 0.001,
  cm: 0.01,
  m: 1,
  km: 1000,
  in: 0.0254,
  ft: 0.3048,
  yd: 0.9144,
  mi: 1609.344,
};

function convertLength(value, from, to) {
  const meters = value * LENGTH_TO_METERS[from];
  return meters / LENGTH_TO_METERS[to];
}

// Weight: canonical unit = kilograms
const WEIGHT_TO_KILOGRAMS = {
  mg: 0.000001,
  g: 0.001,
  kg: 1,
  t: 1000,
  oz: 0.0283495,
  lb: 0.453592,
};

function convertWeight(value, from, to) {
  const kilograms = value * WEIGHT_TO_KILOGRAMS[from];
  return kilograms / WEIGHT_TO_KILOGRAMS[to];
}

The canonical-unit pattern means you only need N conversion factors for N units, not N×N pairwise factors. Adding a new unit is one line.

Note what is not in that table: no stone, no troy pound, no grain. A converter can only offer the units it actually carries — which is worth checking before you trust one with a recipe or a shipment.

Temperature: it's not just multiplication

Temperature is the one that breaks the "just multiply" approach. Celsius and Fahrenheit have different zero points, so you need an offset:

function celsiusToFahrenheit(c) {
  return c * 9/5 + 32;
}

function fahrenheitToCelsius(f) {
  return (f - 32) * 5/9;
}

function celsiusToKelvin(c) {
  return c + 273.15;
}

function kelvinToCelsius(k) {
  return k - 273.15;
}

The general pattern: convert to a canonical unit (Celsius), then convert from canonical to the target. But unlike length and weight, the conversion involves both multiplication and addition.

One implementation detail worth stealing: instead of writing a pair of functions per direction, store a factor and an offset per unit and run everything through a single formula:

const TEMPERATURE = {
  c: { factor: 1, offset: 0 },
  f: { factor: 5 / 9, offset: -32 },
  k: { factor: 1, offset: -273.15 },
};

const toCelsius = (v, id) => (v + TEMPERATURE[id].offset) * TEMPERATURE[id].factor;
const fromCelsius = (c, id) => c / TEMPERATURE[id].factor - TEMPERATURE[id].offset;

fromCelsius(toCelsius(0, 'c'), 'f'); // 32

That is the same table shape as length and weight, plus one optional field. Adding Kelvin did not mean writing another pair of functions.

Two tests for any unit converter

Before you trust a tool:

  1. 0°C → °F should give 32. If you get 0, the tool is multiplying without adding the offset.

  2. 1 mile → km should give 1.609344. If you get 1.61 or 1.6, the tool is rounding too aggressively.

If a converter fails either of these, it has a bug.

Rounding: the silent killer

Unit conversions produce floating-point numbers, and floating-point numbers have precision issues. 0.1 + 0.2 is not 0.3 in JavaScript. So when you convert 1 meter to feet, you might get 3.280839895013123 instead of 3.28084.

The fix: round. Those trailing digits are an artifact of the arithmetic, not extra precision.

I round every result in one place — Math.round(result * 1e6) / 1e6 — rather than carrying a table of per-category precisions. Same rounding, real outputs from that formula:

  • 1 metre → feet: 3.28084

  • 1 mile → kilometres: 1.609344

  • 0 °F → Celsius: -17.777778

One rule is easier to reason about and easier to test than four. A converter that shows you 15 decimals is not more accurate — it is just showing you the floating-point noise.

What I shipped

I put these conversions behind one page on ToolStack: the Unit Converter, six categories, each with its own canonical unit:

  • Length (metre) — mm, cm, m, km, in, ft, yd, mi

  • Weight (kilogram) — mg, g, kg, t, oz, lb

  • Temperature (Celsius) — °C, °F, K

  • Volume (litre) — ml, l, US gal, UK gal, qt, pt, cup, floz

  • Area (m²) — mm², cm², m², km², in², ft², acre, ha

  • Speed (m/s) — m/s, km/h, mph, knot

All 32 tools run entirely in the browser — no uploads, no sign-up, 7 languages.

Disclosure: GA4 page-level analytics is enabled; input values never leave the tab.

https://tools.mindutil.com/