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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@westrem/currency.info

v0.1.2

Published

currency.info is a collection of information about actively used currencies around the world

Downloads

7

Readme

currency.info

currency.info is a collection of information about actively used currencies around the world.

It can help you if you need to:

  • show a list/select of supported currencies
  • format a number as a currency value
  • convert monetary value in minor units to major units and vice versa

Installation

You can use npm or yarn package manager to install currency.info as dependency

npm i @westrem/currency.info
yarn add @westrem/currency.info

Usage

currency.info provides two list-like structures that contain all currencies while also exporting every individual currency on its own.

// Named imports
import { currenciesMap, currenciesList, JPY } from '@westrem/currency.info';

// Default import is the map structure
import currenciesMap from '@westrem/currency.info';

// Single currency import
import { EUR } from '@westrem/currency.info'; // from main package
import { USD } from '@westrem/currency.info/USD' // from dedicated file

// map
currenciesMap['EUR'].symbol === "€";

// list
currenciesList.map(currency => {
  if (currency.isoCode === "EUR") {...}
});

// single currency
EUR.symbol === "€";
USD.symbol === "$";
JPY.symbol === "¥";

Types

currency.info is fully typed. Each currency is of the following type:

// Example for EUR currency
interface Currency {
  /**
   * Human readable name of the currency
   * @example Euro
   */
  displayName: string;
  
  /**
   * ISO 4217 numeric code for the currency
   * @example 978
   */
  numericCode: number;

  /**
   * Tells how many, if any, fraction digits the currency usually uses when formatting a monetary value
   * @example 2
   */
  defaultFractionDigits: number;

  /**
   * Tells the relation between minor and major units for a currency - aka how many minor units is one major unit divided into
   * @example 100
   * @example 1
   * @example 1000
   */
  subUnit: number;

  /**
   * Tells whether there should be a space between the numeric value and symbol when formatting a monetary value
   */
  symbolSpaced: boolean;

  /**
   * Tells whether the symbol should be before or after the numeric value when formatting a monetary value
   */
  symbolPosition: "after" | "before";

  /**
   * Symbol for the currency, can be multiple letters
   * @example €
   * @example JOD
   */
  symbol: string;

  /**
   * ISO 4217 code for the currency
   * @example EUR
   */
  isoCode: "EUR" | "USD" | ...; // notice that ISO code is not a general string type but explicit code
};

The currenciesMap is defined as follows:

type CurrencyISOCode = "EUR" | "USD" | ...;
const currenciesMap: { [key in CurrencyISOCode]: Currency } = { ... };

The keys for the currenciesMap are explicit and can be suggested by your IDE and type-checked by compiler.

Finally, the currenciesList is defined as follows:

const currenciesList: Currency[] = Object.values(currenciesMap);

Both CurrencyISOCode type and Currency interface are exported and you can import them and use in your code.

Currencies 101

currency.info provides information about 154 currencies. Some good-to-knows:

  • not every currency has a one-letter symbol like $ or - some symbols are longer, e.g. for Czech crowns and/or can contain special characters
  • some currencies don't have a dedicated symbol at all, and they use their ISO Code as symbol
  • not every currency is divided into 100 minor units (e.g. cents or similar), some currencies are divided into 1000 subunits†† (e.g. Libyan Dinar) and some don't have subunits at all††† - aka subUnit === 1 (e.g. Japanese Yen)
  • for currencies that are used in multiple countries, the symbolPosition may vary based on locale - this packages does NOT take this into consideration and provides the most used positioning or the generally recommended one, e.g. EUR sign usage

Money 101

When working with monetary value it's a best practice is to always work with minor units (integers) and switch to major units only upon visual formatting of the value.

Meaning, any values stored in database or similar should be in minor units. Similarly, variables in code should contain the value in minor units.

This can prevent bugs related to rounding and float number representation limitations in various programming languages.

Code examples

Select with all currencies

// TypeScript JSX
import { currenciesList } from '@westrem/currency.info';

const CurrenciesSelect = () => (
    <select>
      {currenciesList.map(currency => (
        <option value={currency.isoCode}>
          {currency.displayName} ({currency.symbol})
        </option>
      ))}
    </select>
  );

Formatting monetary values

JavaScript/TypeScript

JavaScript has a great build-in utility for formatting monetary values: Intl.NumberFormat. It works very well hand-in-hand with currency.info:

// TypeScript

import { currenciesMap, CurrencyISOCode } from '@westrem/currency.info';

const formatMoney = (
  valueInMinorUnits: number, 
  currencyISOCode: CurrencyISOCode, 
  locale: string = 'en-US'
) =>
  Intl.NumberFormat(locale, {
    currency: currencyISOCode,
    currencyDisplay: 'narrowSymbol',
    style: 'currency',
    minimumFractionDigits: currenciesMap[currencyISOCode].defaultFractionDigits,
    maximumFractionDigits: currenciesMap[currencyISOCode].defaultFractionDigits,
  }).format(valueInMinorUnits / currenciesMap[currencyISOCode].subUnit)
;

formatMoney(1234, 'USD'); // $12.34
formatMoney(567, 'JPY'); // ¥567
formatMoney(8900, 'JOD'); // JOD 8.900
formatMoney(1234, 'EUR'); // €12.34 ← dot as decimal separator, symbol before, without space
formatMoney(1234, 'EUR', 'sk-SK'); // 12,34 € ← comma as decimal separator, symbol after, with space

If you want to force symbol position, for example because you are rendering values in a tabular context, you can do following:

// TypeScript

import { currenciesMap, CurrencyISOCode } from '@westrem/currency.info';

const formatMoneyTabular = (
  valueInMinorUnits: number, 
  currencyISOCode: CurrencyISOCode, 
  locale: string = 'en-US'
) => {
  const numeric = Intl.NumberFormat(locale, {
    currency: currencyISOCode,
    style: 'decimal',
    minimumFractionDigits: currenciesMap[currencyISOCode].defaultFractionDigits,
    maximumFractionDigits: currenciesMap[currencyISOCode].defaultFractionDigits,
  }).format(valueInMinorUnits / currenciesMap[currencyISOCode].subUnit)
  
  return `${CurrencyISOCode} ${numeric}`;
};

formatMoneyTabular(1234, 'USD'); // USD 12.34
formatMoneyTabular(567, 'JPY'); // JPY 567
formatMoneyTabular(8900, 'JOD'); // JOD 8.900
formatMoneyTabular(1234, 'EUR'); // EUR 12.34 ← dot as decimal separator
formatMoneyTabular(1234, 'EUR', 'sk-SK'); // EUR 12,34 ← comma as decimal separator

Notice how locale in the examples above serves two purposes:

  1. it determines what characters are used as decimal and thousands separators (both formatMoney and formatMoneyTabular)
  2. it determines where the currency symbol is positioned (formatMoney only)

If for any reason you can't use Intl.NumberFormat you can use the symbolSpaced and symbolPosition properties of each currency to aid you with your formatting needs.


  • Examples of currencies that existed but are not actively in use anymore: LTL - Lithuanian Litas, LVL - Latvian Lats: both replaced by EUR
  • †† Following currencies have subUnit value of 1000: BHD, IQD, JOD, KWD, LYD, OMR, TND
  • ††† Following currencies have subUnit value of 1 (aka they don't have a subunit): CLP, CVE, DJF, IDR, JPY, KHR, VND, VUV

Acknowledgements

  • Base data for currencies is taken from https://github.com/vimeo/py-money which itself took data from https://github.com/sebastianbergmann/money
  • Symbol position and symbol spacing is sourced also from https://fastspring.com/blog/how-to-format-30-currencies-from-countries-all-over-the-world/
  • Symbols are sourced from https://en.wikipedia.org/wiki/List_of_circulating_currencies
  • Some of the data above have been tweaked and updated to match current world affairs while I worked at https://primer.io