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

fresh-currency-codes

v1.1.0

Published

TypeScript ISO 4217 currency lookup, auto-refreshed weekly from the SIX-Group XML.

Readme

fresh-currency-codes

A TypeScript-first lookup library for ISO 4217 currency data, auto-refreshed weekly from the canonical SIX-Group XML. Active and deprecated currencies, ISO-official country names, and a publishDate export so consumers can see exactly how fresh the data is.

[!NOTE] This library is inspired by freeall/currency-codes. The data shape, sourcing pipeline, and a few API contracts have been tightened; see Divergences below.

Performance

This library is significantly faster than the original currency-codes library. It uses O(1) Map indexes and cached list data, while still returning defensive copies for array-returning helpers to keep caller semantics safe. In the latest benchmark run, lookups were approximately 17–2456× faster than the original O(n) scan-based behavior.

Requirements

  • Node.js 22+
  • ESM-only published artifact (no CJS build) — see ADR-0008

CJS consumers on Node 22.12 or later can require() this package directly thanks to require(esm). On Node 22.0–22.11 use await import('fresh-currency-codes').

Installation

npm install fresh-currency-codes
yarn add fresh-currency-codes
pnpm add fresh-currency-codes
bun add fresh-currency-codes

Import

import * as cc from 'fresh-currency-codes'

Or named:

import { code, country, number, publishDate } from 'fresh-currency-codes'

Basic usage

Look up by code

cc.code('EUR')
// {
//   active: true,
//   code: 'EUR',
//   countries: [
//     'åland islands',
//     'andorra',
//     'austria',
//     'belgium',
//     'bulgaria',
//     'croatia',
//     'cyprus',
//     'estonia',
//     'european union',
//     'finland',
//     'france',
//     'french guiana',
//     'french southern territories (the)',
//     'germany',
//     'greece',
//     'guadeloupe',
//     'holy see (the)',
//     'ireland',
//     'italy',
//     'latvia',
//     'lithuania',
//     'luxembourg',
//     'malta',
//     'martinique',
//     'mayotte',
//     'monaco',
//     'montenegro',
//     'netherlands (the)',
//     'portugal',
//     'réunion',
//     'saint barthélemy',
//     'saint martin (french part)',
//     'saint pierre and miquelon',
//     'san marino',
//     'slovakia',
//     'slovenia',
//     'spain',
//   ],
//   currency: 'Euro',
//   digits: 2,
//   number: '978',
// }

Look up by ISO numeric code

number() takes a string — ISO numeric codes are zero-padded 3-digit values and the leading zero matters (see ADR-0006).

cc.number('978')
// {
//   active: true,
//   code: 'EUR',
//   countries: [ /* same list as above */ ],
//   currency: 'Euro',
//   digits: 2,
//   number: '978',
// }

Look up by country

Country names are the ISO-official label, lowercased verbatim (see ADR-0004) — not friendly aliases.

cc.country('colombia')
// [
//   {
//     active: true,
//     code: 'COP',
//     countries: ['colombia'],
//     currency: 'Colombian Peso',
//     digits: 2,
//     number: '170',
//   },
//   {
//     active: true,
//     code: 'COU',
//     countries: ['colombia'],
//     currency: 'Unidad de Valor Real',
//     digits: 2,
//     number: '970',
//   },
// ]

List all codes / numbers / countries

cc.codes()
// => ['AED', 'AFN', 'ALL', ...]

cc.numbers()
// => ['784', '971', '008', ...]

cc.countries()
// => ['united arab emirates (the)', 'afghanistan', 'albania', ...]

List all currency records

cc.currencies()
// [
//   {
//     active: true,
//     code: 'AED',
//     countries: ['united arab emirates (the)'],
//     currency: 'UAE Dirham',
//     digits: 2,
//     number: '784',
//   },
//   {
//     active: true,
//     code: 'AFN',
//     countries: ['afghanistan'],
//     currency: 'Afghani',
//     digits: 2,
//     number: '971',
//   },
//   // ...
// ]

Inspect when the data was last refreshed

console.log(cc.publishDate)
// => '2026-01-01'

Including deprecated currencies

Deprecated currencies are filtered out by default. Opt in with { includeDeprecated: true } on any of the lookup methods.

cc.code('ZWL')
// => undefined

cc.code('ZWL', { includeDeprecated: true })
// {
//   active: false,
//   code: 'ZWL',
//   countries: ['zimbabwe'],
//   currency: 'Zimbabwe Dollar',
//   digits: 2,
//   number: '932',
// }

The same option works on number(), country(), codes(), numbers(), countries(), and currencies().

digits: null semantics

ISO publishes N.A. for currencies that have no minor unit at all (gold, IMF SDRs, the bond-market funds units). We surface this as digits: null — semantically distinct from digits: 0, which means a defined zero minor units (e.g. JPY). See ADR-0003.

cc.code('XAU')
// {
//   active: true,
//   code: 'XAU',
//   countries: ['zz08_gold'],
//   currency: 'Gold',
//   digits: null,
//   number: '959',
// }

Consumers must handle the null case explicitly — flattening it to 0 silently corrupts records like XAU.

Freshness

The point of this fork is that the dataset stays current without anyone remembering to bump it.

  • Weekly auto-refresh via GitHub Actions, sourced exclusively from the SIX-Group XML (list-one.xml).
  • Sanity-guarded on every refresh: at least 100 active currencies, no more than 10 removals in a single run, and publishDate must not regress. A guard failure aborts the refresh and leaves the previous dataset intact.
  • Auto-published on merge — when a refresh PR (or any version-bumping PR) merges into main, the publish workflow ships the new version to npm. See ADR-0007.

The publishDate export is the canonical freshness signal — it mirrors the Pblshd field of the SIX-Group XML, not the npm publish date.

Stability contract

From 1.0.0, this package follows semver — but for a deliberately living dataset. The 1.x guarantee covers the public API and the data shape (the CurrencyCodeRecord structure, function signatures, and digits: null semantics), not the data values. Currency additions and deprecations are expected weekly churn shipped as patch releases; they are not breaking changes. A 2.0.0 is reserved for human-gated changes to the API or data shape. See ADR-0010.

If you need a frozen snapshot of the data — e.g. for reproducible builds or to insulate against a currency being deprecated upstream — pin an exact version (fresh-currency-codes: "1.2.3") rather than a range (^1.0.0).

Changelog

Release notes for every version live on the GitHub Releases page. Automated data refreshes carry their added/deprecated counts; manual API changes carry hand-written notes.

Divergences from currency-codes

| Behaviour | freeall/currency-codes | fresh-currency-codes | | --- | --- | --- | | number() parameter | string or number | string only (preserves leading zeros — see ADR-0006) | | number field on records | number | string (e.g. '008' for ALL) | | Country names | curated friendly aliases | ISO-official label, lowercased verbatim (e.g. 'united kingdom of great britain and northern ireland (the)' — see ADR-0004) | | digits for N.A. entries | number (often coerced to 0) | number \| null, with null for entries that have no minor unit at all (see ADR-0003) | | Deprecated currencies | filtered out, no opt-in | opt-in via { includeDeprecated: true } | | Freshness signal | none | publishDate export mirroring the SIX-Group XML | | Data sourcing | hand-curated | auto-refreshed weekly from the SIX-Group XML — no hand-curated entries | | Performance | O(n) array scans for all lookups | O(1) Map lookups and precomputed arrays — up to 50–2500× faster | | Runtime dependencies | Yes | none (zero runtime deps) |

Updating the data manually

The dataset refreshes automatically every week, so this is rarely needed. To pull a snapshot locally:

bun run iso

This fetches the latest list-one.xml from SIX-Group and rewrites src/data.json.

Project structure

  • CONTEXT.md — domain glossary (Currency, Code, Number, Country, Digits, Publish date, Active, Deprecated, SIX-Group list).
  • docs/adr/ — architectural decision records (ADRs 0001–0010).

License

MIT © Arnaud de Surirey — see LICENSE.