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

country-codes-list

v3.1.1

Published

List of codes per country (languages, calling codes, currency codes, etc) with full TypeScript support.

Downloads

411,977

Readme

country-codes-list

Module with list of codes per country, including country codes, currency codes, and more.

[!WARNING] Release v3.0.0 introduces breaking changes: countryCallingCode no longer folds in national area codes, areaCodes is now a required string[], and several functions narrow their key parameter to string-valued properties. See the v2 → v3 migration guide.

Release v2.0.0 introduced breaking changes with full TypeScript support and automated testing/publishing.

[!NOTE] v3.1.1 fixes a bug where the public API could mutate the shared dataset. all() now returns a fresh array on every call (so all() === all() is no longer true), and sorting or mutating that array — or the one from customArray({ sortDataBy }) — no longer reorders or corrupts the data seen by filter, findOne, customList and every other consumer. If your code relied on reference equality between calls to all(), compare contents instead.

Features

  • 2 digit country code (ISO 3166-1 alpha-2): Obtained from Wikipedia
  • 3 digit country code (ISO 3166-1 alpha-3): Obtained from Wikipedia
  • Alternative country codes (altCodes): non-primary 2-letter codes that still identify a country in the wild — UK for the United Kingdom (whose ISO code is GB) and EL for Greece (whose ISO code is GR). Resolve any of them with findOneByCode
  • Country Name: Each name in english and in the local country language
  • Currency Code (ISO 4217): Obtained from Wikipedia
  • Currency Name (ISO 4217): Obtained from Wikipedia
  • TIN Code (Taxpayer Identification Number, also known as VAT in some countries): Obtained from Wikipedia
  • TIN Name: Obtained from Wikipedia
  • Official language code (usually from ISO 639-1, or ISO 639-3 otherwise)): Obtained from Open Street Map. Returns only the first official language code per country
  • Official language name: Each name in english and in the local country language
  • Country Calling Code: The phone calling code for the country. Obtained from Wikipedia. This is the ITU-T E.164 country code only (1-3 digits, no +, no spaces) — national area codes are never folded into it.
  • Area Codes: The national area codes that follow the calling code, as string[]. Partially populated — an empty array means "not recorded", not "this country has no area codes". Every member of the North American Numbering Plan carries its area code (Jamaica ["876", "658"], Barbados ["246"], …), so +1 is fully disambiguated except for the US, whose hundreds of area codes are out of scope here (Canada's are populated, a pre-existing exception). Other shared calling codes are not disambiguated: AU and CX both use 61, AX and FI both use 358, and GB, GG, IM and JE all use 44, each with an empty array.
  • Region: The Regional Classifications are from the International Telecommunications Union. Seen here

Installation

Install the package via npm:

npm install --save country-codes-list

Build & Test

To compile the package, run:

npm run build

The compiled output will be in the dist/ folder.

To run tests:

npm test

Installation

Install the NPM module

    npm install --save country-codes-list

Migration Guide (v1.x to v2.0)

Breaking Changes

  1. TypeScript Types: If you were using types:

    // Old (v1.x)
    import { CountryProperty } from "country-codes-list";
    const prop: CountryProperty = CountryProperty.countryCode;
    
    // New (v2.0)
    import type { CountryProperty } from "country-codes-list";
    const prop: CountryProperty = "countryCode";
  2. Module Imports: Now supports both CommonJS and ES modules:

    // CommonJS (still works)
    const countryCodes = require("country-codes-list");
    
    // ES Modules (new)
    import * as countryCodes from "country-codes-list";
  3. Stricter Types: Some functions now have stricter type checking:

    // This now requires valid country property keys
    countryCodes.filter("invalidKey", "value"); // TypeScript error

Migration Guide (v2.x to v3.0)

Breaking Changes

  1. countryCallingCode is now the ITU-T E.164 country code only — national area codes are no longer folded in. Several countries changed value, most notably the NANP members that used to carry their area code:

    // Old (v2.x)
    countryCodes.findOne("countryCode", "JM").countryCallingCode; // '876'
    
    // New (v3.0)
    countryCodes.findOne("countryCode", "JM").countryCallingCode; // '1'
    countryCodes.findOne("countryCode", "JM").areaCodes; // ['876', '658']

    If you relied on the old value to dial a full number, concatenate the calling code with an area code: `+${cc}${areaCodes[0]}`.

  2. areaCodes is now a required string[] (previously an optional any[]). It is partially populated — an empty array means "not recorded", not "no area codes". Every NANP member is populated; other shared calling codes (44, 358, 61) are not yet.

  3. Key parameters narrowed to CountryScalarProperty. filter, findOne, customList, customGroupedList and customArray's sortDataBy no longer accept array-valued properties (altCodes, areaCodes). This was already broken at runtime; it is now a compile-time error:

    // Old (v2.x): type-checked but returned garbage at runtime
    countryCodes.customList("altCodes", "{countryCode}");
    
    // New (v3.0): TypeScript error
    // To look up by an alternative code, use findOneByCode instead:
    countryCodes.findOneByCode("UK").countryCode; // 'GB'

Usage

This package can be used in both CommonJS (JavaScript) and TypeScript environments.

CommonJS

const countryCodes = require("country-codes-list");

const myCountryCodesObject = countryCodes.customList(
  "countryCode",
  "[{countryCode}] {countryNameEn}: +{countryCallingCode}"
);

console.log(myCountryCodesObject);

TypeScript

import * as countryCodes from "country-codes-list";

const myCountryCodesObject = countryCodes.customList(
  "countryCode",
  "[{countryCode}] {countryNameEn}: +{countryCallingCode}"
);
console.log(myCountryCodesObject);

API Details – findOneByCode Method

Resolves a 2- or 3-letter country code to a country, case-insensitively, matching the official ISO 3166-1 alpha-2 and alpha-3 codes and the alternative codes in altCodes.

Use it when the code comes from somewhere you don't control — a browser or OS locale, an EU VAT number, an upstream API, a legacy database — where UK shows up as often as GB:

const countryCodes = require("country-codes-list");

countryCodes.findOneByCode("UK").countryCode; // 'GB'
countryCodes.findOneByCode("gbr").countryCode; // 'GB'
countryCodes.findOneByCode("EL").countryCode; // 'GR'
countryCodes.findOneByCode("ZZ"); // undefined

Input is trimmed and must be 2 or 3 ASCII letters; anything else returns undefined. The validation happens before uppercasing on purpose — Unicode case mapping turns "ß" into "SS" and "ı" into "I", so validating afterwards would let junk input resolve to real countries.

Note that altCodes and areaCodes hold arrays, so they can't be used as lookup or list keys. filter, findOne and customList accept only string-valued properties (the exported CountryScalarProperty type); reach for findOneByCode to search altCodes.

UK is exceptionally reserved in ISO 3166-1 at the United Kingdom's request; EL is the European Commission's code for Greece. Neither replaces the official code — findOne("countryCode", "UK") still returns undefined, and countryCode remains GB/GR.

API Details – customList Method

  • The first parameter is the key used for the returned object's property.
  • The second parameter is a string with placeholders (in {placeholder} format) replaced by corresponding country properties.

The available placeholders are:

  • countryNameEn
  • countryNameLocal
  • countryCode
  • currencyCode
  • currencyNameEn
  • tinType
  • tinName
  • officialLanguageCode
  • officialLanguageNameEn
  • officialLanguageNameLocal
  • countryCallingCode
  • region
  • globalSouth

[!IMPORTANT] The key must be unique across countries. countryCode and countryCodeAlpha3 are; countryCallingCode, currencyCode, region and officialLanguageCode are not. Keying on a non-unique property makes countries overwrite each other and only the last one survives — use customGroupedList instead.

Example

const countryCodes = require("country-codes-list");

const myCountryCodesObject = countryCodes.customList(
  "countryCode",
  "[{countryCode}] {countryNameEn}: +{countryCallingCode}"
);

This will return an object like this one:

{
    'AD': '[AD] Andorra: +376',
    'AE': '[AE] United Arab Emirates: +971',
    'AF': '[AF] Afghanistan: +93',
    'AG': '[AG] Antigua and Barbuda: +1',
    'AI': '[AI] Anguilla: +1',
    'AL': '[AL] Albania: +355',
    'AM': '[AM] Armenia: +374',
    'AO': '[AO] Angola: +244',
    'AQ': '[AQ] Antarctica: +',
    'AR': '[AR] Argentina: +54',
    'AS': '[AS] American Samoa: +1',
    'AT': '[AT] Austria: +43',
    'AU': '[AU] Australia: +61',
    'AW': '[AW] Aruba: +297',
    ...
}

API Details – customGroupedList Method

Same signature as customList, but each key maps to an array of every matching country instead of just the last one. Use it whenever several countries share the key — the United States, Canada and the Caribbean all answer to +1, and the whole euro zone shares EUR.

const countryCodes = require("country-codes-list");

// customList: one country per calling code — the other 25 are lost
countryCodes.customList("countryCallingCode", "{countryCode}")["1"];
// => 'UM'

// customGroupedList: all of them
countryCodes.customGroupedList("countryCallingCode", "{countryCode}")["1"];
// => ['AG', 'AI', 'AS', 'BB', 'BM', 'CA', 'DM', 'GD', 'GU', 'JM', 'KN', 'LC',
//     'MS', 'PR', 'SX', 'TT', 'US', 'VC', 'VG', 'VI', 'DO', 'BS', 'KY', 'MP',
//     'TC', 'UM']

It takes the same third { filter } option:

countryCodes.customGroupedList("region", "{countryNameEn}", {
  filter: (country) => country.currencyCode === "EUR",
});

This will return an object like this one — keyed by region, with an array of country names per group:

{
    'Europe': ['Andorra', 'Austria', 'Åland Islands', 'Belgium', ...],
    'South/Latin America': ['Saint Barthélemy', 'French Guiana', 'Guadeloupe', ...],
    'North America': ['Saint Pierre and Miquelon'],
    'Asia & Pacific': ['Réunion'],
    'Africa': ['Mayotte'],
    'Indian Ocean': ['French Southern and Antarctic Lands'],
}

Keys that no country matched are simply absent, so the return type is Partial<Record<string, string[]>> — check before use:

const byRegion = countryCodes.customGroupedList("region", "{countryCode}", {
  filter: (country) => country.countryCode === "AR",
});
byRegion["Europe"]; // undefined — no European country passed the filter
byRegion["Europe"]?.length ?? 0; // 0