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/svelte

v0.1.0

Published

Svelte store integration for the UniRate currency-exchange API. createUniRate() returns reactive readable stores — rate, conversion, currencies, vatRates — each carrying { data, error, loading } with a refresh(). Zero runtime deps.

Readme

@unirate/svelte

Plain Svelte store integration for the UniRate currency exchange API.

createUniRate() gives you reactive readable stores — rate, rates, conversion, currencies, vatRates — each carrying { data, error, loading } with a refresh() method. Works with Svelte 4 and Svelte 5. Zero runtime dependencies (native fetch + svelte/store).

Framework-agnostic: this is the plain-Svelte-stores package. If you're on SvelteKit and want server load helpers, a geo hook, and an API-route proxy, use @unirate/sveltekit instead.

Install

npm install @unirate/svelte svelte

Quick start

# .env — get a free key at https://unirateapi.com
UNIRATE_API_KEY=your-api-key-here
<script>
  import { createUniRate } from '@unirate/svelte';

  const uni = createUniRate({ apiKey: import.meta.env.VITE_UNIRATE_API_KEY });

  const rate = uni.rate('USD', 'EUR');
  const price = uni.conversion('USD', 'EUR', 99.99);
  const codes = uni.currencies();
</script>

{#if $rate.loading}
  Loading…
{:else if $rate.error}
  {$rate.error.message}
{:else}
  <p>1 USD = {$rate.data} EUR</p>
{/if}

<button on:click={rate.refresh}>Refresh</button>

Never ship a real API key to the browser in production. Proxy UniRate through your own backend and point the client's baseUrl at your proxy, or fetch on the server and pass values down.

API

createUniRate(options)

Builds one UniRateClient and returns store constructors bound to it.

const uni = createUniRate({
  apiKey: 'your-key',      // required
  baseUrl?: string,        // default https://api.unirateapi.com
  fetch?: typeof fetch,    // inject a custom fetch (e.g. SvelteKit's load fetch)
  timeoutMs?: number,      // default 30000
  userAgent?: string,
});

Returns:

| Member | Returns | Notes | |---|---|---| | uni.client | UniRateClient | The underlying imperative client. | | uni.rate(from, to) | QueryStore<number> | Single exchange rate. | | uni.rates(from) | QueryStore<Record<string, number>> | All rates for from. | | uni.conversion(from, to, amount) | QueryStore<number> | amount of from in to. | | uni.currencies() | QueryStore<string[]> | Supported currency codes. | | uni.vatRates() | QueryStore<VATRatesAll> | All countries. | | uni.vatRates(country) | QueryStore<VATRateOne> | One country (ISO-3166 alpha-2). |

QueryStore<T>

A Svelte readable of:

interface QueryState<T> {
  data: T | undefined;      // settled value, or undefined until first success
  error: Error | undefined; // last error, or undefined while healthy
  loading: boolean;         // true until the first request settles; true again during refresh()
}

plus:

store.refresh(); // abort any in-flight request and re-fetch (no-op with no subscribers)

The request fires lazily on the first subscription and is torn down when the last subscriber leaves — the standard Svelte store lifecycle. An in-flight request is aborted whenever refresh() runs again or the store stops, so a stale response can never overwrite a newer one. During a refresh() the previously settled data stays put while loading flips to true.

Imperative client

Everything is also available directly on uni.client (or import UniRateClient and construct it yourself):

import { UniRateClient } from '@unirate/svelte/client';

const client = new UniRateClient({ apiKey: 'your-key' });
const rate = await client.getRate('USD', 'EUR');        // number
const map = await client.getRate('USD');                // Record<string, number>
const eur = await client.convert('EUR', 100, 'USD');    // number
const codes = await client.listCurrencies();            // string[]
const vat = await client.getVatRates('DE');             // { country, vat_data }

Historical/timeseries methods exist for parity but require a UniRate Pro subscription and return 403 (ProRequiredError) on the free tier.

Error handling

Errors are mapped to typed subclasses of UniRateError, surfaced through store.error (or thrown by the client):

| HTTP | Error | | |---|---|---| | 400 | InvalidRequestError | Invalid request parameters | | 401 | AuthenticationError | Missing or invalid API key | | 403 | ProRequiredError | Endpoint requires a Pro subscription | | 404 | InvalidCurrencyError | Currency not found or no data available | | 429 | RateLimitError | Rate limit exceeded | | 503 / other | UniRateError | carries .status and .body | | network | UniRateError | wraps the underlying transport error |

{#if $rate.error}
  {#if $rate.error.name === 'RateLimitError'}
    Slow down — try again in a moment.
  {:else}
    {$rate.error.message}
  {/if}
{/if}

Building

This package is pure TypeScript stores — there are no .svelte component files to compile — so it builds with plain tsc:

npm run build     # tsc -p tsconfig.build.json → dist/ (ESM + .d.ts)

Related

License

MIT © Unirate Team