Home Documentation Playground Pricing API Status Blog About FAQ Support

Best Exchange Rate API for Node.js and JavaScript (2026)

Reviewed by Madhushan, Fintech Developer — May 2026
JavaScript code on monitor

JavaScript runs everywhere — browsers, Node.js servers, Cloudflare Workers, Deno, Bun, serverless functions. If you are building anything that touches money, prices, or international users, you need exchange rate data. And you need an API that fits naturally into the JavaScript and TypeScript ecosystem: an npm package you can install, proper types, and async/await support out of the box.

Most currency APIs fail this test. They offer a REST endpoint and leave you to write your own HTTP wrapper, handle errors, parse responses, and manage caching. Some have npm packages created by random community members that have not been updated in two years. Others lock essential features like historical rates or multiple base currencies behind expensive paid plans.

This article compares the 6 most popular exchange rate APIs for JavaScript and Node.js developers in 2026. We look at SDK quality, TypeScript support, free tier limits, update frequency, and real-world integration patterns. AllRatesToday comes out on top with its official npm package, full TypeScript support, real-time mid-market rates, and a generous free tier.

Side-by-Side Comparison

Here is how the top 6 exchange rate APIs compare for JavaScript and Node.js developers:

API JS/TS SDK npm Package Free Tier WebSocket Update Speed
AllRatesToday Official + Types @allratestoday/sdk Free, no CC Planned 60 seconds
Open Exchange Rates Community only open-exchange-rates 1,000 req/mo No Hourly
Fixer.io No None 100 req/mo No Daily
CurrencyAPI Official @everapi/currencyapi-js 300 req/mo No Daily
Frankfurter No None Unlimited No Daily (ECB)
ExchangeRate-API No None 1,500 req/mo No Daily

Key takeaway: AllRatesToday is the only API that offers an official npm package with built-in TypeScript types, real-time rates updated every 60 seconds, historical data on the free tier, and no credit card requirement for signup.

1. AllRatesToday — Best Overall for Node.js

AllRatesToday provides an official JavaScript/TypeScript SDK published on npm. It supports ESM and CommonJS, includes full type definitions, and works in Node.js, Deno, Bun, and modern browsers. The API delivers real-time mid-market rates from Reuters/Refinitiv for 160+ currencies.

Install the SDK

npm install @allratestoday/sdk

Or with yarn/pnpm:

yarn add @allratestoday/sdk
# or
pnpm add @allratestoday/sdk

Get a single exchange rate

import AllRatesToday from '@allratestoday/sdk';

const client = new AllRatesToday('YOUR_API_KEY');

// Fetch real-time USD to EUR rate
const rate = await client.getRate('USD', 'EUR');
console.log(`1 USD = ${rate} EUR`);

Convert an amount

const result = await client.convert('USD', 'EUR', 1000);
console.log(`$1,000 = €${result.result}`);
console.log(`Rate: ${result.rate}`);
console.log(`Time: ${result.time}`);

Fetch historical rates

const history = await client.getHistoricalRates('USD', 'EUR', '30d');

history.rates.forEach(point => {
  console.log(`${point.time}: ${point.rate}`);
});

Using fetch directly (no SDK)

If you prefer native fetch without installing a package:

const API_KEY = 'YOUR_API_KEY';

const response = await fetch(
  'https://allratestoday.com/api/v1/rates?source=USD&target=EUR',
  {
    headers: { 'Authorization': `Bearer ${API_KEY}` }
  }
);

const data = await response.json();
console.log(`1 USD = ${data.rate} EUR`);
console.log(`Updated: ${data.time}`);

TypeScript with full type safety

import AllRatesToday from '@allratestoday/sdk';

interface ConversionResult {
  source: string;
  target: string;
  amount: number;
  result: number;
  rate: number;
  time: string;
}

const client = new AllRatesToday('YOUR_API_KEY');

async function convertCurrency(
  from: string,
  to: string,
  amount: number
): Promise<ConversionResult> {
  const result = await client.convert(from, to, amount);
  return result as ConversionResult;
}

const conversion = await convertCurrency('USD', 'JPY', 5000);
console.log(`$5,000 = ¥${conversion.result.toLocaleString()}`);

npm: @allratestoday/sdkView on GitHub

2. Open Exchange Rates

Open Exchange Rates is one of the older currency APIs, launched in 2012. There is no official npm package. The community-maintained open-exchange-rates package exists but is not actively updated and lacks TypeScript types.

// No official SDK - using fetch
const APP_ID = 'YOUR_APP_ID';

const response = await fetch(
  `https://openexchangerates.org/api/latest.json?app_id=${APP_ID}&base=USD`
);

const data = await response.json();
const eurRate = data.rates.EUR;
console.log(`1 USD = ${eurRate} EUR`);

3. Fixer.io

Fixer was once a popular choice but has stagnated since its acquisition by APILayer. There is no npm package at all — you write raw HTTP calls. The free tier is severely limited at 100 requests per month with EUR-only base and HTTP-only (no HTTPS).

const API_KEY = 'YOUR_API_KEY';

// Note: free tier is HTTP only, not HTTPS
const response = await fetch(
  `http://data.fixer.io/api/latest?access_key=${API_KEY}&base=EUR&symbols=USD,GBP,JPY`
);

const data = await response.json();
console.log(data.rates);

4. CurrencyAPI

CurrencyAPI (currencyapi.com) offers an official npm package (@everapi/currencyapi-js), which is a notable advantage. However, the free tier caps at 300 requests per month and only provides daily rates.

// npm install @everapi/currencyapi-js
import CurrencyAPI from '@everapi/currencyapi-js';

const client = new CurrencyAPI('YOUR_API_KEY');

const result = await client.latest({
  base_currency: 'USD',
  currencies: 'EUR,GBP,JPY'
});

Object.entries(result.data).forEach(([code, info]) => {
  console.log(`USD/${code}: ${info.value}`);
});

5. Frankfurter

Frankfurter is a free, open-source API that serves European Central Bank (ECB) data. No API key is needed, which makes it great for prototyping. But it only covers about 30 currencies and updates once daily when the ECB publishes at 16:00 CET. There is no npm package.

// No API key needed, no SDK
const response = await fetch(
  'https://api.frankfurter.app/latest?from=USD&to=EUR,GBP,JPY'
);

const data = await response.json();
console.log(`Date: ${data.date}`);
Object.entries(data.rates).forEach(([currency, rate]) => {
  console.log(`USD/${currency}: ${rate}`);
});

6. ExchangeRate-API

ExchangeRate-API provides a straightforward REST interface with no SDK. The free tier is relatively generous at 1,500 requests per month, but you only get daily rates and no historical data.

const API_KEY = 'YOUR_API_KEY';

const response = await fetch(
  `https://v6.exchangerate-api.com/v6/${API_KEY}/latest/USD`
);

const data = await response.json();
console.log(`1 USD = ${data.conversion_rates.EUR} EUR`);
console.log(`Updated: ${data.time_last_update_utc}`);

Express.js Currency Conversion API

Build a production-ready currency conversion microservice with Express and AllRatesToday:

// npm install express @allratestoday/sdk
import express from 'express';
import AllRatesToday from '@allratestoday/sdk';

const app = express();
const client = new AllRatesToday(process.env.ALLRATESTODAY_API_KEY);

// Simple in-memory cache
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes

function getCachedRate(key) {
  const entry = cache.get(key);
  if (entry && Date.now() - entry.time < CACHE_TTL) {
    return entry.rate;
  }
  return null;
}

app.get('/api/rate/:from/:to', async (req, res) => {
  const { from, to } = req.params;
  const cacheKey = `${from}_${to}`;

  try {
    let rate = getCachedRate(cacheKey);
    if (!rate) {
      rate = await client.getRate(from, to);
      cache.set(cacheKey, { rate, time: Date.now() });
    }

    res.json({ from, to, rate, cached: !!getCachedRate(cacheKey) });
  } catch (error) {
    res.status(500).json({ error: 'Failed to fetch rate' });
  }
});

app.get('/api/convert', async (req, res) => {
  const { from, to, amount } = req.query;

  if (!from || !to || !amount) {
    return res.status(400).json({
      error: 'Missing required parameters: from, to, amount'
    });
  }

  try {
    const result = await client.convert(from, to, parseFloat(amount));
    res.json(result);
  } catch (error) {
    res.status(500).json({ error: 'Conversion failed' });
  }
});

app.listen(3000, () => {
  console.log('Currency API running on http://localhost:3000');
});

Test it:

curl http://localhost:3000/api/rate/USD/EUR
curl "http://localhost:3000/api/convert?from=USD&to=EUR&amount=500"

Next.js Server Action Example

Use AllRatesToday in a Next.js 14+ server action for server-side currency conversion:

// app/actions/currency.ts
'use server';

import AllRatesToday from '@allratestoday/sdk';

const client = new AllRatesToday(process.env.ALLRATESTODAY_API_KEY!);

export async function getExchangeRate(from: string, to: string) {
  const rate = await client.getRate(from, to);
  return { from, to, rate, timestamp: new Date().toISOString() };
}

export async function convertAmount(
  from: string,
  to: string,
  amount: number
) {
  const result = await client.convert(from, to, amount);
  return result;
}
// app/components/CurrencyConverter.tsx
'use client';

import { useState } from 'react';
import { convertAmount } from '../actions/currency';

export default function CurrencyConverter() {
  const [result, setResult] = useState<number | null>(null);
  const [loading, setLoading] = useState(false);

  async function handleConvert(formData: FormData) {
    setLoading(true);
    const from = formData.get('from') as string;
    const to = formData.get('to') as string;
    const amount = parseFloat(formData.get('amount') as string);

    const data = await convertAmount(from, to, amount);
    setResult(data.result);
    setLoading(false);
  }

  return (
    &lt;form action=&#123;handleConvert&#125;&gt;
      &lt;input name="from" defaultValue="USD" placeholder="From" /&gt;
      &lt;input name="to" defaultValue="EUR" placeholder="To" /&gt;
      &lt;input name="amount" type="number" defaultValue="100" /&gt;
      &lt;button type="submit" disabled=&#123;loading&#125;&gt;
        &#123;loading ? 'Converting...' : 'Convert'&#125;
      &lt;/button&gt;
      &#123;result !== null && &lt;p&gt;Result: &#123;result&#125;&lt;/p&gt;&#125;
    &lt;/form&gt;
  );
}

React Hook for Exchange Rates

A reusable React hook for fetching exchange rates on the client side:

import { useState, useEffect } from 'react';
import AllRatesToday from '@allratestoday/sdk';

const client = new AllRatesToday('YOUR_API_KEY');

export function useExchangeRate(from: string, to: string) {
  const [rate, setRate] = useState<number | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    let cancelled = false;
    setLoading(true);

    client.getRate(from, to)
      .then(r => {
        if (!cancelled) {
          setRate(r);
          setLoading(false);
        }
      })
      .catch(err => {
        if (!cancelled) {
          setError(err);
          setLoading(false);
        }
      });

    return () => { cancelled = true; };
  }, [from, to]);

  return { rate, loading, error };
}

// Usage in a component
function PriceTag({ amount, from, to }: {
  amount: number;
  from: string;
  to: string;
}) {
  const { rate, loading, error } = useExchangeRate(from, to);

  if (loading) return <span>Loading...</span>;
  if (error) return <span>Error fetching rate</span>;

  return <span>{(amount * rate!).toFixed(2)} {to}</span>;
}

Cloudflare Workers / Edge Runtime

AllRatesToday works in edge runtimes like Cloudflare Workers since you can use the native fetch API:

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const from = url.searchParams.get('from') || 'USD';
    const to = url.searchParams.get('to') || 'EUR';

    const response = await fetch(
      `https://allratestoday.com/api/v1/rates?source=${from}&target=${to}`,
      {
        headers: { 'Authorization': `Bearer ${env.ALLRATESTODAY_API_KEY}` }
      }
    );

    const data = await response.json();

    return new Response(JSON.stringify({
      from,
      to,
      rate: data.rate,
      time: data.time
    }), {
      headers: { 'Content-Type': 'application/json' }
    });
  }
};

Why AllRatesToday Wins for Node.js and JavaScript

After comparing all six APIs, here is why AllRatesToday is the best choice for JavaScript and Node.js developers:

Quick Reference

Start Building with Node.js and Real-Time Rates

Get your free API key in 30 seconds. Install the SDK with npm install @allratestoday/sdk and fetch real-time mid-market rates for 160+ currencies. Compare all options on our Exchange Rate API page.

Get Your Free API Key