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-base

v1.0.3

Published

Pre-indexed country data for high-load JavaScript and TypeScript projects.

Readme

country-base

Pre-indexed country data for high-load JavaScript and TypeScript projects.

The package avoids repeated Array.find() scans. Countries are stored by ISO-2 code, and every secondary lookup is shipped as a separate importable index.

What is country-base?

country-base is a zero-dependency TypeScript/JavaScript library for fast country lookups.

It provides ready-to-use country data indexed by ISO-2 code, plus optional prebuilt indexes for ISO-3, country names, phone codes, currencies, subregions, and languages.

Best for high-load projects, APIs, validation layers, forms, checkout flows, analytics pipelines, and any code path where repeated Array.find() lookups are too wasteful.

Install

npm install country-base

Basic Usage

import { getCountryByIso2 } from "country-base";

const country = getCountryByIso2("us");

console.log(country?.name.common);
// United States

console.log(country?.cca2, country?.cca3);
// US USA

All Countries

import { countries } from "country-base";

console.log(countries.length);
// 250

for (const country of countries) {
  console.log(country.cca2, country.name.common);
}
// AD Andorra
// AE United Arab Emirates
// AF Afghanistan
// ...

countries is a ready-to-use shared array, so it does not rebuild on every use.

The root import loads the full country dataset keyed by ISO-2 and exposes the shared all-countries array. Secondary lookup indexes are loaded only when you import their country-base/indexes/* entrypoints.

import { iso3 } from "country-base/indexes/iso3";
import { countriesByIso2 } from "country-base/data";

const iso2 = iso3.USA;
const country = iso2 ? countriesByIso2[iso2] : undefined;

console.log(iso2);
// US

console.log(country?.name.official);
// United States of America

Separate Indexes

import { nameSimple } from "country-base/indexes/name-simple";
import { phone } from "country-base/indexes/phone";
import { currency } from "country-base/indexes/currency";
import { normalizeKey } from "country-base";

const byName = nameSimple[normalizeKey("United States")];
const byPhone = phone["+1"];
const byCurrency = currency.USD;

console.log(byName);
// ["US"]

console.log(byPhone);
// ["AG", "AI", "AS", "BB", "BM", "BS", "CA", "DM", "DO", "GD", "GU", "JM", "KN", "KY", "LC", "MP", "MS", "PR", "SX", "TC", "TT", "US", "VC", "VG", "VI"]

console.log(byCurrency);
// ["AS", "BQ", "BS", "EC", "GU", "IO", "KH", "MH", "MP", "PA", "PR", "PW", "SV", "TC", "TL", "UM", "US", "VG", "VI", "ZW"]

Country Object Excerpt

Shortened excerpt from getCountryByIso2("US"):

const country = {
  altSpellings: ["US", "USA", "United States of America"],
  area: 9372610,
  borders: ["CAN", "MEX"],
  capital: ["Washington D.C."],
  cca2: "US",
  cca3: "USA",
  ccn3: "840",
  cioc: "USA",
  currencies: {
    USD: {
      name: "United States dollar",
      symbol: "$"
    }
  },
  demonyms: {
    eng: {
      f: "American",
      m: "American"
    },
    fra: {
      f: "Américaine",
      m: "Américain"
    }
  },
  flag: "🇺🇸",
  idd: {
    root: "+1",
    suffixes: [
      "201",
      "202",
      "203",
      "205"
      // ...more NANP area codes
    ]
  },
  independent: true,
  landlocked: false,
  languages: {
    eng: "English"
  },
  latlng: [38, -97],
  name: {
    common: "United States",
    native: {
      eng: {
        common: "United States",
        official: "United States of America"
      }
    },
    official: "United States of America"
  },
  region: "Americas",
  status: "officially-assigned",
  subregion: "North America",
  tld: [".us"],
  translations: {
    deu: {
      common: "Vereinigte Staaten",
      official: "Vereinigte Staaten von Amerika"
    },
    fra: {
      common: "États-Unis",
      official: "Les états-unis d'Amérique"
    },
    rus: {
      common: "Соединённые Штаты Америки",
      official: "Соединенные Штаты Америки"
    },
    zho: {
      common: "美国",
      official: "美利坚合众国"
    }
    // Also includes: ara, bre, ces, est, fin, hrv, hun, ita, jpn,
    // kor, nld, per, pol, por, slk, spa, srp, swe, tur, urd
  },
  unMember: true,
  unRegionalGroup: "Western European and Others Group"
};

Available indexes:

| Import | Key format | Value | |---|---|---| | country-base/indexes/iso2 | ISO-2 code, for example US | CountryCodeIso2 | | country-base/indexes/iso3 | ISO-3 code, for example USA | CountryCodeIso2 | | country-base/indexes/name-full | normalizeKey(...) result | CountryCodeIso2[] | | country-base/indexes/name-simple | normalizeKey(...) result | CountryCodeIso2[] | | country-base/indexes/phone | exact calling code with or without + | CountryCodeIso2[] | | country-base/indexes/currency | currency code, for example USD | CountryCodeIso2[] | | country-base/indexes/subregion | normalizeKey(...) result | CountryCodeIso2[] | | country-base/indexes/language-code | language code, for example eng | CountryCodeIso2[] | | country-base/indexes/language-name | normalizeKey(...) result | CountryCodeIso2[] |

country-base/indexes imports all indexes at once.

Countries without a subregion value are not included in the subregion index.

TypeScript

Types are included. No extra @types/* package is required.

import type { Country, CountryCodeIso2 } from "country-base";
import type { MultiCountryIndex } from "country-base/indexes/currency";

Key Features

  • ISO-2 country lookup in O(1)
  • Prebuilt indexes for ISO-3, names, phone codes, currencies, subregions, and languages
  • Separate index imports so unused lookup maps are not loaded
  • TypeScript-first API with bundled types
  • Works in Node.js and package-aware runtimes/bundlers, including Bun, Deno via npm:, and browser bundlers
  • ESM and CommonJS support
  • Zero runtime dependencies

Performance

country-base uses object-map lookups instead of repeated full-array scans. The Array.find() row below is a baseline for raw array datasets, not the internal implementation of country-base.

| Scenario | Example | Strategy | Complexity | |---|---|---:|---:| | country-base ISO-2 lookup | getCountryByIso2("US") | Object map | O(1) | | Raw array dataset lookup | countries.find((c) => c.cca2 === "US") | Full-array scan | O(n) | | country-base currency lookup | currency.USD | Prebuilt index | O(1) map access |

Benchmarks were run on Node.js 24, Apple M2, May 2026.

| Scenario | Result | |---|---:| | country-base ISO-2 object-map lookup | 40,143,970 ops/sec | | Baseline manual Array.find() lookup | 4,498,170 ops/sec | | country-base currency prebuilt-index lookup | 133,276,618 ops/sec |

Run locally:

npm run build
npm run benchmark

Compared to Alternatives

| Package style | ISO-2 lookup | Secondary lookups | TypeScript | Bundle strategy | |---|---:|---:|---:|---| | country-base | O(1) object map | Prebuilt indexes | Yes | Separate importable indexes | | Raw country array packages | Usually Array.find() / manual scan | Usually manual filtering | Varies | Usually full dataset | | Country/state/city datasets | Varies | Often optimized for hierarchy, not country-only lookup | Varies | Larger data surface |

country-base vs countries-list

Use country-base when you need fast ISO-2 lookups and prebuilt secondary indexes for names, phone codes, currencies, subregions, and languages.

Use countries-list when you prefer its specific data shape or already depend on its exported country records.

country-base vs world-countries

Use country-base when lookup speed and TypeScript-friendly indexed access are the priority.

Use world-countries when you need a raw country dataset in its format and do not need prebuilt lookup maps.

country-base vs country-state-city

Use country-base when you only need country-level metadata.

Use country-state-city when you need states, provinces, and cities in addition to countries.

When should I use country-base?

Use country-base when you need:

  • O(1) ISO-2 country lookup
  • Separate importable indexes instead of loading every lookup map at once
  • TypeScript types bundled with the package
  • Country-level metadata for APIs, forms, checkout flows, validation, analytics, or high-load services

Use another dataset when you need city-level data, administrative subdivisions, or a different raw data schema.