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.
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.
npm install country-baseimport { getCountryByIso2 } from "country-base";
const country = getCountryByIso2("us");
console.log(country?.name.common);
// United States
console.log(country?.cca2, country?.cca3);
// US USAimport { 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 Americaimport { 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"]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.
Types are included. No extra @types/* package is required.
import type { Country, CountryCodeIso2 } from "country-base";
import type { MultiCountryIndex } from "country-base/indexes/currency";- 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
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| 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 |
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.
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.
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.
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.