Freedom Sale
Independence Day Special — Unlock the AI Path 70% off our most popular AI course · Limited time offer
--Days
--Hrs
--Min
--Sec
Claim Your Discount
✦ Beginner ⏱ 30 min

💱 Build a Live Currency Converter Web App

🎯 What You'll Build

A live currency converter with real exchange rates, instant typing conversion, popular pairs rate card, and support for 150+ currencies — no API key needed.

📋 What You'll Need

1

Fetch live exchange rates

open.er-api.com offers a completely free endpoint with no API key required.

const BASE_URL = 'https://open.er-api.com/v6/latest/USD';

async function fetchRates() {
  try {
    const res  = await fetch(BASE_URL);
    const data = await res.json();

    if (data.result !== 'success') throw new Error('API error');

    const rates = data.rates;
    console.log(`Loaded ${Object.keys(rates).length} currencies`);
    console.log(`1 USD = ${rates.INR} INR`);
    console.log(`1 USD = ${rates.EUR} EUR`);
    return rates;

  } catch (err) {
    console.error('Failed to fetch rates:', err);
    return null;
  }
}

fetchRates().then(r => console.log(r));
2

Full currency converter web app

Select currencies from dropdowns, type an amount, and see the conversion instantly.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Currency Converter</title>
  <style>
    * { margin:0; padding:0; box-sizing:border-box; }
    body { font-family:'Segoe UI',sans-serif; background:#0f172a; color:#fff; min-height:100vh; display:flex; align-items:center; justify-content:center; padding:20px; }
    .card { background:#1e293b; border-radius:20px; padding:36px; max-width:440px; width:100%; }
    h1 { font-size:1.4rem; text-align:center; margin-bottom:24px; }
    .row { display:flex; gap:10px; margin-bottom:16px; }
    .col { flex:1; display:flex; flex-direction:column; gap:6px; }
    label { font-size:0.75rem; color:#94a3b8; font-weight:600; text-transform:uppercase; letter-spacing:0.05em; }
    input, select { padding:12px 14px; background:#0f172a; border:1px solid #334155; color:#fff; border-radius:10px; font-size:0.95rem; width:100%; }
    input:focus, select:focus { outline:none; border-color:#3b82f6; }
    .swap-btn { background:#334155; border:none; color:#94a3b8; font-size:1.3rem; padding:10px; border-radius:10px; cursor:pointer; margin-top:18px; flex-shrink:0; }
    .swap-btn:hover { background:#3b82f6; color:#fff; }
    .rate-info { text-align:center; color:#64748b; font-size:0.82rem; margin-top:12px; }
    .popular { margin-top:28px; }
    .popular h3 { font-size:0.8rem; color:#64748b; text-transform:uppercase; letter-spacing:0.06em; margin-bottom:12px; }
    .pairs-grid { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
    .pair { background:#0f172a; border-radius:10px; padding:12px 14px; }
    .pair .pair-label { font-size:0.75rem; color:#64748b; margin-bottom:2px; }
    .pair .pair-rate  { font-weight:700; font-size:0.95rem; }
  </style>
</head>
<body>

<?php require_once __DIR__ . '/../promo_banner.php'; ?>

<div class="card">
  <h1>💱 Currency Converter</h1>
  <div class="row">
    <div class="col"><label>Amount</label><input type="number" id="amount" value="1" min="0" oninput="convert()"></div>
    <div class="col"><label>From</label><select id="from" onchange="convert()"></select></div>
    <button class="swap-btn" onclick="swapCurrencies()" title="Swap">&#8644;</button>
    <div class="col"><label>To</label><select id="to" onchange="convert()"></select></div>
  </div>
  <input type="text" id="result" readonly placeholder="Result..." style="font-size:1.3rem;font-weight:700;text-align:center;margin-bottom:8px">
  <div class="rate-info" id="rateInfo">Loading rates...</div>
  <div class="popular">
    <h3>Popular pairs (1 USD =)</h3>
    <div class="pairs-grid" id="popularGrid"></div>
  </div>
</div>
<script src="app.js"></script>
</body>
</html>
3

JavaScript logic

Fetch rates, populate selects, convert on input, and show popular pairs.

// app.js
const POPULAR = ['EUR','GBP','INR','JPY','CAD','AUD','CHF','CNY'];
let rates = {};

async function init() {
  try {
    const res  = await fetch('https://open.er-api.com/v6/latest/USD');
    const data = await res.json();
    rates = data.rates;
    populateSelects();
    showPopularPairs();
    convert();
  } catch {
    document.getElementById('rateInfo').textContent = 'Failed to load rates. Check your connection.';
  }
}

function populateSelects() {
  const currencies = Object.keys(rates).sort();
  ['from','to'].forEach((id, i) => {
    const sel = document.getElementById(id);
    currencies.forEach(c => {
      const opt = document.createElement('option');
      opt.value = opt.textContent = c;
      if ((i === 0 && c === 'USD') || (i === 1 && c === 'EUR')) opt.selected = true;
      sel.appendChild(opt);
    });
  });
}

function convert() {
  const amount   = parseFloat(document.getElementById('amount').value);
  const fromCurr = document.getElementById('from').value;
  const toCurr   = document.getElementById('to').value;
  if (isNaN(amount) || !rates[fromCurr] || !rates[toCurr]) return;
  const result = (amount / rates[fromCurr]) * rates[toCurr];
  document.getElementById('result').value = result.toFixed(4) + ' ' + toCurr;
  const rate = (rates[toCurr] / rates[fromCurr]).toFixed(6);
  document.getElementById('rateInfo').textContent = `1 ${fromCurr} = ${rate} ${toCurr}`;
}

function swapCurrencies() {
  const f = document.getElementById('from'); const t = document.getElementById('to');
  [f.value, t.value] = [t.value, f.value];
  convert();
}

function showPopularPairs() {
  const grid = document.getElementById('popularGrid');
  POPULAR.forEach(c => {
    const div = document.createElement('div'); div.className = 'pair';
    div.innerHTML = `<div class="pair-label">USD/${c}</div><div class="pair-rate">${rates[c]?.toFixed(4) || '–'}</div>`;
    grid.appendChild(div);
  });
}

init();
💡 Tip: The open.er-api.com free endpoint updates rates once per day. For real-time rates (updated every minute), use the paid tier or a forex data provider. For most personal finance apps, daily rates are perfectly fine.

🎉 You Did It!

A live, fully functional currency converter with real exchange rates in under 100 lines — no server, no API key, no fees. The same convert() function pattern works in any app that needs unit conversion.

Found something wrong?

Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.