npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@unirate/remix

v0.1.0

Published

Remix / React Router 7 integration for the UniRate currency-exchange API. Server-side loader utilities, a proxy resource-route handler that keeps your API key server-side, and createUniRate() factory for use in loaders and actions. Zero runtime deps.

Downloads

20

Readme

@unirate/remix

Remix / React Router 7 integration for the UniRate API — free currency exchange rates, historical data, and VAT rates.

Provides createUniRate() for use in loaders and actions, ready-made loader factories (createRateLoader, createConvertLoader, createCurrenciesLoader), and a proxy resource-route handler that keeps your API key server-side. Zero runtime dependencies.

Install

npm install @unirate/remix

Quick start

In any loader

// app/routes/pricing.ts
import { createUniRate } from "@unirate/remix/server";

const unirate = createUniRate(); // reads UNIRATE_API_KEY from env

export async function loader() {
  const rate = await unirate.getRate("USD", "EUR");
  const currencies = await unirate.listCurrencies();
  return { rate, currencies };
}

Loader factories

// app/routes/rates.ts
import { createRateLoader } from "@unirate/remix/loaders";

// Reads `from` and `to` from ?from=USD&to=EUR
export const loader = createRateLoader({ defaultFrom: "USD" });

// In your component: const { rate, from, to } = useLoaderData<typeof loader>();
// app/routes/convert.ts
import { createConvertLoader } from "@unirate/remix/loaders";

// Reads ?from=USD&to=EUR&amount=100
export const loader = createConvertLoader();
// app/routes/currencies.ts
import { createCurrenciesLoader } from "@unirate/remix/loaders";

export const loader = createCurrenciesLoader();
// Returns { currencies: ["USD", "EUR", ...] }

Proxy resource route (keeps API key server-side)

// app/routes/api.unirate.ts
import { createUniRateProxyLoader } from "@unirate/remix/handler";

export const loader = createUniRateProxyLoader();
// Client calls: /api/unirate?path=/api/rates&from=USD&to=EUR
// api_key is injected server-side; never exposed to the client

API

createUniRate(opts?)

Returns a UniRate instance for use in server-only code (loaders, actions).

import { createUniRate } from "@unirate/remix/server";

const unirate = createUniRate({
  apiKey: process.env.UNIRATE_API_KEY, // default: read from env
  baseUrl: "https://api.unirateapi.com", // default
  timeoutMs: 30_000, // default
});

// Methods
await unirate.getRate("USD", "EUR");        // → 0.92
await unirate.getRate("USD");               // → { EUR: 0.92, GBP: 0.79, ... }
await unirate.convert("USD", "EUR", 100);   // → 92.34
await unirate.listCurrencies();             // → ["USD", "EUR", "GBP", ...]
await unirate.getVatRates();                // → { total_countries, vat_rates: {...} }
await unirate.getVatRates("DE");            // → { country: "DE", vat_data: {...} }
await unirate.getHistoricalRate("2025-01-01", "USD", "EUR"); // → 0.88 (Pro)
await unirate.getTimeSeries("2025-01-01", "2025-01-07");     // → { date: { EUR: 0.92 } } (Pro)
await unirate.getHistoricalLimits();        // → { total_currencies, currencies: {...} } (Pro)

Top-level helpers are also exported for convenience (read UNIRATE_API_KEY from env automatically):

import { getRate, convert, listCurrencies } from "@unirate/remix/server";

Loader factories

| Factory | Query params | Returns | |---|---|---| | createRateLoader(opts?) | ?from=USD&to=EUR | { rate, from, to } | | createConvertLoader(opts?) | ?from=USD&to=EUR&amount=100 | { result, from, to, amount } | | createCurrenciesLoader(opts?) | none | { currencies } |

All factories accept { apiKey?, baseUrl?, timeoutMs?, defaultFrom? }.

Proxy loader

import { createUniRateProxyLoader } from "@unirate/remix/handler";

const loader = createUniRateProxyLoader({
  apiKey: process.env.UNIRATE_API_KEY,    // default: read from env
  allowedPaths: ["/api/rates", "/api/convert"], // default: all UniRate paths
  timeoutMs: 30_000,
});

Allowed paths (default): /api/rates, /api/convert, /api/currencies, /api/vat/rates, /api/historical/rates, /api/historical/timeseries, /api/historical/limits.

Error handling

import { UniRateError, AuthenticationError, RateLimitError } from "@unirate/remix/client";

try {
  const rate = await unirate.getRate("USD", "EUR");
} catch (err) {
  if (err instanceof AuthenticationError) { /* invalid key */ }
  if (err instanceof RateLimitError) { /* slow down */ }
  if (err instanceof UniRateError) {
    console.error(err.status, err.message);
  }
}

Error classes: UniRateError (base) · AuthenticationError (401) · ProRequiredError (403) · InvalidCurrencyError (404) · RateLimitError (429) · InvalidRequestError (400).

Free vs Pro tier

Free tier: /api/rates, /api/convert, /api/currencies, /api/vat/rates. Historical endpoints require a Pro subscription.

Related packages

UniRate API client libraries: Python · Node.js · Go · Rust · Ruby · PHP · Java · Swift · .NET

Framework integrations: Next.js · Nuxt · SvelteKit · Astro · NestJS · Strapi · Remix (this package)

PHP ecosystem: Laravel Money · WordPress · Symfony Bundle

Data & AI: LangChain Python · FastAPI · Flask · Django REST · dbt · Airflow

Other: MCP server · CLI · Directus · Medusa · Home Assistant

License

MIT © Unirate Team