Calculator
Unit Converter
Convert any unit — length, weight, temperature, area, volume, speed, data, time. Live results for all units.
Developer Reference
Core Algorithm & Standalone Script
Standalone, zero-dependency JavaScript implementation powering this tool. Free to inspect, copy, and build upon.
const CATEGORIES = {
length: {
label: 'Length',
units: [
{ key: 'mm', label: 'Millimeter', symbol: 'mm', factor: 0.001 },
{ key: 'cm', label: 'Centimeter', symbol: 'cm', factor: 0.01 },
{ key: 'm', label: 'Meter', symbol: 'm', factor: 1 },
{ key: 'km', label: 'Kilometer', symbol: 'km', factor: 1000 },
{ key: 'in', label: 'Inch', symbol: 'in', factor: 0.0254 },
{ key: 'ft', label: 'Foot', symbol: 'ft', factor: 0.3048 },
{ key: 'yd', label: 'Yard', symbol: 'yd', factor: 0.9144 },
{ key: 'mi', label: 'Mile', symbol: 'mi', factor: 1609.344 },
]
},
weight: {
label: 'Weight',
units: [
{ key: 'mg', label: 'Milligram', symbol: 'mg', factor: 0.000001 },
{ key: 'g', label: 'Gram', symbol: 'g', factor: 0.001 },
{ key: 'kg', label: 'Kilogram', symbol: 'kg', factor: 1 },
{ key: 't', label: 'Tonne', symbol: 't', factor: 1000 },
{ key: 'oz', label: 'Ounce', symbol: 'oz', factor: 0.0283495 },
{ key: 'lb', label: 'Pound', symbol: 'lb', factor: 0.453592 },
{ key: 'st', label: 'Stone', symbol: 'st', factor: 6.35029 },
]
},
temperature: {
label: 'Temperature',
special: true,
units: [
{ key: 'C', label: 'Celsius', symbol: '°C' },
{ key: 'F', label: 'Fahrenheit', symbol: '°F' },
{ key: 'K', label: 'Kelvin', symbol: 'K' },
]
},
area: {
label: 'Area',
units: [
{ key: 'mm2', label: 'mm²', symbol: 'mm²', factor: 0.000001 },
{ key: 'cm2', label: 'cm²', symbol: 'cm²', factor: 0.0001 },
{ key: 'm2', label: 'm²', symbol: 'm²', factor: 1 },
{ key: 'km2', label: 'km²', symbol: 'km²', factor: 1e6 },
{ key: 'in2', label: 'inch²', symbol: 'in²', factor: 0.00064516 },
{ key: 'ft2', label: 'foot²', symbol: 'ft²', factor: 0.092903 },
{ key: 'ac', label: 'Acre', symbol: 'ac', factor: 4046.86 },
{ key: 'ha', label: 'Hectare', symbol: 'ha', factor: 10000 },
]
},
volume: {
label: 'Volume',
units: [
{ key: 'ml', label: 'Milliliter', symbol: 'ml', factor: 0.001 },
{ key: 'L', label: 'Liter', symbol: 'L', factor: 1 },
{ key: 'm3', label: 'm³', symbol: 'm³', factor: 1000 },
{ key: 'tsp', label: 'Teaspoon', symbol: 'tsp', factor: 0.00492892 },
{ key: 'tbsp', label: 'Tablespoon', symbol: 'tbsp', factor: 0.0147868 },
{ key: 'cup', label: 'Cup', symbol: 'cup', factor: 0.236588 },
{ key: 'pt', label: 'Pint', symbol: 'pt', factor: 0.473176 },
{ key: 'qt', label: 'Quart', symbol: 'qt', factor: 0.946353 },
{ key: 'gal', label: 'Gallon', symbol: 'gal', factor: 3.78541 },
]
},
speed: {
label: 'Speed',
units: [
{ key: 'ms', label: 'm/s', symbol: 'm/s', factor: 1 },
{ key: 'kmh', label: 'km/h', symbol: 'km/h', factor: 0.277778 },
{ key: 'mph', label: 'mph', symbol: 'mph', factor: 0.44704 },
{ key: 'kn', label: 'Knot', symbol: 'kn', factor: 0.514444 },
]
},
data: {
label: 'Data',
units: [
{ key: 'bit', label: 'Bit', symbol: 'bit', factor: 1 },
{ key: 'B', label: 'Byte', symbol: 'B', factor: 8 },
{ key: 'KB', label: 'Kilobyte', symbol: 'KB', factor: 8192 },
{ key: 'MB', label: 'Megabyte', symbol: 'MB', factor: 8388608 },
{ key: 'GB', label: 'Gigabyte', symbol: 'GB', factor: 8589934592 },
{ key: 'TB', label: 'Terabyte', symbol: 'TB', factor: 8796093022208 },
{ key: 'PB', label: 'Petabyte', symbol: 'PB', factor: 9007199254740992 },
]
},
time: {
label: 'Time',
units: [
{ key: 'ms', label: 'Millisecond', symbol: 'ms', factor: 0.001 },
{ key: 's', label: 'Second', symbol: 's', factor: 1 },
{ key: 'min', label: 'Minute', symbol: 'min', factor: 60 },
{ key: 'hr', label: 'Hour', symbol: 'hr', factor: 3600 },
{ key: 'day', label: 'Day', symbol: 'day', factor: 86400 },
{ key: 'wk', label: 'Week', symbol: 'wk', factor: 604800 },
{ key: 'mo', label: 'Month', symbol: 'mo', factor: 2629746 },
{ key: 'yr', label: 'Year', symbol: 'yr', factor: 31556952 },
]
},
};
// Temperature conversions — all via Celsius as pivot
function toC(val, from) {
if (from === 'C') return val;
if (from === 'F') return (val - 32) * 5 / 9;
if (from === 'K') return val - 273.15;
}
function fromC(c, to) {
if (to === 'C') return c;
if (to === 'F') return c * 9 / 5 + 32;
if (to === 'K') return c + 273.15;
}
let currentCat = 'length';
let currentFrom = 'm';
function buildFromSelect(cat) {
const sel = document.getElementById('fromUnit');
sel.innerHTML = CATEGORIES[cat].units.map(u =>
`<option value="${u.key}">${u.label} (${u.symbol})</option>`
).join('');
// restore previous selection if it exists in new category
const unit = CATEGORIES[cat].units.find(u => u.key === currentFrom);
if (unit) sel.value = currentFrom;
else sel.value = CATEGORIES[cat].units[0].key;
currentFrom = sel.value;
}
function formatNum(n) {
if (!isFinite(n)) return '—';
const abs = Math.abs(n);
if (abs === 0) return '0';
if (abs >= 1e15) return n.toExponential(4);
if (abs >= 1000) return +n.toFixed(4) + '';
if (abs >= 1) return +n.toFixed(6) + '';
return +n.toPrecision(6) + '';
}
function renderResults() {
const val = parseFloat(document.getElementById('valueInput').value);
const cat = CATEGORIES[currentCat];
const fromKey = document.getElementById('fromUnit').value;
const grid = document.getElementById('resultsGrid');
if (isNaN(val)) {
grid.innerHTML = '<div style="color:var(--muted);font-size:13px;">Enter a number to convert.</div>';
return;
}
grid.innerHTML = cat.units.map(u => {
let result;
if (cat.special) {
// temperature
const pivotC = toC(val, fromKey);
result = fromC(pivotC, u.key);
} else {
const fromUnit = cat.units.find(x => x.key === fromKey);
const inBase = val * fromUnit.factor;
result = inBase / u.factor;
}
const isFrom = u.key === fromKey;
const displayVal = formatNum(result);
return `
<div class="unit-card ${isFrom ? 'highlighted' : ''}">
<button class="copy-btn-sm" onclick="copyVal(this, '${displayVal}')">copy</button>
<div class="unit-name">${u.label}</div>
<div class="unit-value ${isFrom ? 'accent' : ''}">${displayVal}</div>
<div class="unit-symbol">${u.symbol}</div>
</div>
`;
}).join('');
}
function copyVal(btn, val) {
navigator.clipboard.writeText(val).then(() => {
btn.textContent = 'copied!';
setTimeout(() => btn.textContent = 'copy', 2000);
});
}
document.getElementById('categoryTabs').addEventListener('click', e => {
const tab = e.target.closest('.tab');
if (!tab) return;
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
tab.classList.add('active');
currentCat = tab.dataset.cat;
buildFromSelect(currentCat);
renderResults();
});
document.getElementById('fromUnit').addEventListener('change', e => {
currentFrom = e.target.value;
renderResults();
});
document.getElementById('valueInput').addEventListener('input', renderResults);
// Init
buildFromSelect(currentCat);
renderResults();