Best Exchange Rate API for Node.js and JavaScript (2026)
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/sdk — View on GitHub
- Data source: Reuters/Refinitiv and interbank feeds
- Update frequency: Every 60 seconds (real-time)
- Currencies: 160+ including majors, minors, and exotics
- Rate type: Mid-market (no bank markup)
- Free tier: Available — no credit card required
- TypeScript: Built-in type definitions, no @types package needed
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`); - Free tier: 1,000 requests/month, USD base only
- Update frequency: Hourly on free, more frequent on paid
- Limitation: Free plan locked to USD as base currency
- npm package: Community only, no TypeScript types
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); - Free tier: 100 requests/month, EUR base only
- Update frequency: Daily
- Limitation: No HTTPS on free tier, EUR base only, no SDK
- npm package: None
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}`);
}); - Free tier: 300 requests/month
- Update frequency: Daily on free tier
- npm package: Official (@everapi/currencyapi-js)
- Limitation: Historical data requires paid plan, low free request limit
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}`);
}); - Free tier: Unlimited (no API key)
- Update frequency: Daily (ECB publishes at 16:00 CET)
- Currencies: ~30 (ECB reference rates only)
- Limitation: No exotic currencies, no real-time data, no weekend updates
- npm package: None
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}`); - Free tier: 1,500 requests/month
- Update frequency: Daily
- npm package: None
- Limitation: No real-time rates, historical data requires paid plan
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 (
<form action={handleConvert}>
<input name="from" defaultValue="USD" placeholder="From" />
<input name="to" defaultValue="EUR" placeholder="To" />
<input name="amount" type="number" defaultValue="100" />
<button type="submit" disabled={loading}>
{loading ? 'Converting...' : 'Convert'}
</button>
{result !== null && <p>Result: {result}</p>}
</form>
);
} 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:
- Official npm package:
npm install @allratestoday/sdk— maintained by the AllRatesToday team with regular updates and proper semver. - Full TypeScript support: Built-in type definitions ship with the package. No separate
@typesinstallation needed. Types are accurate and comprehensive. - ESM and CommonJS: Works with both module systems. Import with
importorrequire()without configuration issues. - Real-time rates: Updated every 60 seconds from Reuters/Refinitiv and interbank feeds. Every other free API on this list provides daily rates at best (except Open Exchange Rates with hourly on free).
- Mid-market rates: The true interbank rate with no markup, the same data shown on Google Finance and used by financial institutions.
- 160+ currencies: Full coverage of majors, minors, and exotic pairs. Frankfurter only covers ~30 ECB currencies.
- Works everywhere: Node.js, Deno, Bun, Cloudflare Workers, Vercel Edge Functions, browser. The REST API works with native
fetchin any JavaScript runtime. - Historical data on free tier: Most competitors lock historical rates behind paid plans.
- No credit card required: Sign up and start building immediately.
Quick Reference
- Install:
npm install @allratestoday/sdk - Get rates:
GET /api/v1/rates?source=USD&target=EUR - Historical:
GET /api/historical-rates?source=USD&target=EUR&from=2026-01-01&to=2026-05-24 - Auth:
Authorization: Bearer YOUR_API_KEY - npm: @allratestoday/sdk
- GitHub: allratestoday/exchange-rates-api
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.