countries-list、country-data、country-list、i18n-iso-countries、iso-3166-1 は、すべて国や地域に関するデータを扱う npm パッケージですが、それぞれ設計思想と提供機能が異なります。countries-list は ISO 規格に準拠した国コードと基本情報を軽量に提供します。country-data は国旗絵文字や通貨など豊富なメタデータを含みますが、メンテナンス状況に注意が必要です。country-list はシンプルな国名とコードの対応に特化しています。i18n-iso-countries は多言語対応に強く、50 言語以上の翻訳を提供します。iso-3166-1 は ISO 3166-1 規格そのものに焦点を当て、厳密な規格準拠を重視します。
フロントエンド開発において、国や地域のデータを扱う機会は頻繁にあります。フォームの国選択ドロップダウン、配送先住所、国際決済、多言語対応など、様々な場面で国データが必要です。しかし、npm には複数の国データパッケージが存在し、どれを選ぶべきか迷うことがあります。
本稿では、countries-list、country-data、country-list、i18n-iso-countries、iso-3166-1 の 5 つのパッケージを、実際の開発現場の視点から比較します。
各パッケージは異なるデータ構造を採用しており、これが使い勝手に大きく影響します。
countries-list はオブジェクト形式で国コードをキーにデータを取得できます。
import { countries } from 'countries-list';
// 国コードでアクセス
const japan = countries['JP'];
console.log(japan.name); // "Japan"
console.log(japan.capital); // "Tokyo"
console.log(japan.currency); // "JPY"
country-data は配列形式で、filter や find を使った検索が前提です。
import countries from 'country-data';
// 配列から検索
const japan = countries.countries.all.find(c => c.alpha2 === 'JP');
console.log(japan.name); // "Japan"
console.log(japan.emojiFlag); // "🇯🇵"
console.log(japan.currencyCode); // "JPY"
country-list はシンプルな配列形式で、国名とコードの対応に特化しています。
import countries from 'country-list';
// コードから国名を取得
const name = countries.getName('JP'); // "Japan"
// 国名からコードを取得
const code = countries.getCode('Japan'); // "JP"
// 全リスト取得
const allCountries = countries.getNames(); // ["Afghanistan", "Albania", ...]
i18n-iso-countries は多言語対応が特徴で、言語コードを指定して翻訳を取得できます。
import countries from 'i18n-iso-countries';
import jaLocale from 'i18n-iso-countries/langs/ja.json';
// 言語登録
countries.registerLocale(jaLocale);
// 日本語で国名取得
const name = countries.getName('JP', 'ja'); // "日本"
// 英語で国名取得
const nameEn = countries.getName('JP', 'en'); // "Japan"
// 全リスト取得(日本語)
const allNames = countries.getNames('ja'); // ["アフガニスタン", "アルバニア", ...]
iso-3166-1 は ISO 規格に厳密に準拠し、3 種類のコード(alpha-2、alpha-3、numeric)を扱えます。
import { alpha2, alpha3, numeric } from 'iso-3166-1';
// alpha-2 コードで検索
const country = alpha2.get('JP');
console.log(country.name); // "Japan"
console.log(country.alpha3); // "JPN"
console.log(country.numeric); // "392"
// alpha-3 から検索
const byAlpha3 = alpha3.get('JPN');
// numeric から検索
const byNumeric = numeric.get('392');
国際化プロジェクトでは、多言語対応が必須要件になることが多く、ここで各パッケージの差が明確になります。
countries-list の多言語対応は限定的で、主に英語表記に依存します。独自に翻訳データを管理する必要があります。
import { countries } from 'countries-list';
// 英語表記のみ提供
const name = countries['JP'].name; // "Japan"
// 独自翻訳マップが必要
const translations = {
'JP': { ja: '日本', ko: '일본', zh: '日本' }
};
country-data も同様に、多言語対応はパッケージ外で処理します。国旗絵文字は標準装備ですが、国名の翻訳は含まれません。
import countries from 'country-data';
// 国旗絵文字は利用可能
const flag = countries.countries.all.find(c => c.alpha2 === 'JP').emojiFlag; // "🇯🇵"
// 国名翻訳は別途管理が必要
country-list は多言語対応機能を提供していません。シンプルな名前 - コード対応に特化しているため、国際化には追加作業が必要です。
import countries from 'country-list';
// 英語名のみ
const name = countries.getName('JP'); // "Japan"
// 多言語対応は自前で実装
i18n-iso-countries は多言語対応が最大の強みです。50 言語以上の翻訳データが公式に提供されており、言語ファイルを読み込むだけで対応できます。
import countries from 'i18n-iso-countries';
import jaLocale from 'i18n-iso-countries/langs/ja.json';
import koLocale from 'i18n-iso-countries/langs/ko.json';
import zhLocale from 'i18n-iso-countries/langs/zh.json';
// 複数言語を登録
countries.registerLocale(jaLocale);
countries.registerLocale(koLocale);
countries.registerLocale(zhLocale);
// 言語を切り替えて取得
const nameJa = countries.getName('JP', 'ja'); // "日本"
const nameKo = countries.getName('JP', 'ko'); // "일본"
const nameZh = countries.getName('JP', 'zh'); // "日本"
iso-3166-1 は規格コードの管理に特化しており、多言語対応は提供していません。コード変換と検証が主な用途です。
import { alpha2 } from 'iso-3166-1';
// 国名ではなくコード管理に焦点
const country = alpha2.get('JP');
console.log(country.name); // "Japan" (英語のみ)
パッケージの長期的な使用を考えると、メンテナンス状況は重要な判断基準です。
countries-list は定期的に更新されており、ISO 規格の変更に追従しています。TypeScript 型定義も付属しており、型安全な開発が可能です。
import { countries, Country } from 'countries-list';
// TypeScript 型定義が利用可能
const japan: Country = countries['JP'];
// name: string, capital: string, currency: string, etc.
country-data は更新頻度が低く、npm ページで非推奨の示唆がある場合があります。新規プロジェクトでの使用は慎重に検討すべきです。既存プロジェクトの維持用途に限るのが安全です。
// 更新が停滞している可能性あり
// 新規プロジェクトでは代替パッケージの評価を推奨
import countries from 'country-data';
country-list はシンプルな機能に特化しているため、更新頻度は低めですが、安定しています。機能追加の予定は少なく、現状維持が方針です。
// 機能は最小限だが安定
import countries from 'country-list';
i18n-iso-countries は活発にメンテナンスされており、新しい言語の追加や既存翻訳の更新が定期的に行われています。国際化プロジェクトでの信頼性が高いです。
// 活発なメンテナンス
import countries from 'i18n-iso-countries';
// 言語ファイルも定期的に更新される
iso-3166-1 は ISO 規格自体が頻繁に変更されるものではないため、更新頻度は低めですが、規格準拠の信頼性は高いです。
// 規格準拠を重視
import { alpha2 } from 'iso-3166-1';
EC サイトの注文フォームで、ユーザーに配送先国を選択させる場合。
i18n-iso-countries が最適です。ユーザーの言語設定に応じて国名を表示できます。
import countries from 'i18n-iso-countries';
import jaLocale from 'i18n-iso-countries/langs/ja.json';
countries.registerLocale(jaLocale);
function CountrySelect({ userLocale }) {
const countryList = countries.getNames(userLocale);
return (
<select name="country">
{Object.entries(countryList).map(([code, name]) => (
<option key={code} value={code}>{name}</option>
))}
</select>
);
}
countries-list でも実装可能ですが、多言語対応が別途必要です。
import { countries } from 'countries-list';
function CountrySelect() {
return (
<select name="country">
{Object.entries(countries).map(([code, data]) => (
<option key={code} value={code}>{data.name}</option>
))}
</select>
);
}
国コードから国旗絵文字を表示したい場合。
country-data が最も簡単です。国旗絵文字が標準で含まれています。
import countries from 'country-data';
function CountryFlag({ countryCode }) {
const country = countries.countries.all.find(c => c.alpha2 === countryCode);
return <span>{country.emojiFlag}</span>; // "🇯🇵"
}
countries-list や他のパッケージでは、別途絵文字マッピングが必要です。
import { countries } from 'countries-list';
// 独自で絵文字マッピングが必要
const emojiMap = {
'JP': '🇯🇵',
'US': '🇺🇸',
// ...
};
function CountryFlag({ countryCode }) {
return <span>{emojiMap[countryCode]}</span>;
}
決済機能で、国コードから通貨コードを取得したい場合。
countries-list が通貨情報を標準で提供しています。
import { countries } from 'countries-list';
const currency = countries['JP'].currency; // "JPY"
const currencySymbol = countries['JP'].symbol; // "¥"
country-data も通貨情報を提供しますが、データ構造が異なります。
import countries from 'country-data';
const country = countries.countries.all.find(c => c.alpha2 === 'JP');
const currency = country.currencyCode; // "JPY"
i18n-iso-countries は通貨情報を直接提供していません。別途 i18n-iso-currencies などのパッケージとの併用が必要です。
import countries from 'i18n-iso-countries';
import currencies from 'i18n-iso-currencies';
// 国コードから直接通貨は取得不可
// 別途通貨パッケージが必要
ユーザー入力された国コードが有効か検証したい場合。
iso-3166-1 が最も適しています。規格コードの検証に特化しています。
import { alpha2, alpha3, numeric } from 'iso-3166-1';
// alpha-2 コードの検証
const isValid = alpha2.get('JP') !== undefined; // true
const isInvalid = alpha2.get('XX') !== undefined; // false
// alpha-2 から alpha-3 へ変換
const country = alpha2.get('JP');
const alpha3Code = country.alpha3; // "JPN"
// numeric から alpha-2 へ変換
const byNumeric = numeric.get('392');
const alpha2Code = byNumeric.alpha2; // "JP"
countries-list でも検証は可能ですが、規格準拠の保証は iso-3166-1 ほど明確ではありません。
import { countries } from 'countries-list';
const isValid = countries['JP'] !== undefined; // true
| 機能 | countries-list | country-data | country-list | i18n-iso-countries | iso-3166-1 |
|---|---|---|---|---|---|
| ISO alpha-2 | ✅ | ✅ | ✅ | ✅ | ✅ |
| ISO alpha-3 | ✅ | ✅ | ❌ | ✅ | ✅ |
| ISO numeric | ❌ | ✅ | ❌ | ❌ | ✅ |
| 多言語対応 | ❌ | ❌ | ❌ | ✅ (50+ 言語) | ❌ |
| 国旗絵文字 | ❌ | ✅ | ❌ | ❌ | ❌ |
| 通貨情報 | ✅ | ✅ | ❌ | ❌ | ❌ |
| 首都情報 | ✅ | ✅ | ❌ | ❌ | ❌ |
| 言語情報 | ✅ | ✅ | ❌ | ❌ | ❌ |
| TypeScript 型 | ✅ | ❌ | ❌ | ✅ | ✅ |
| 保守状況 | 活発 | 停滞気味 | 安定 | 活発 | 安定 |
5 つのパッケージには、以下の共通点があります。
すべてが ISO 3166-1 規格の alpha-2 コード(2 文字の国コード)を基準にしています。これにより、パッケージ間でデータの互換性があります。
// どのパッケージでも 'JP' は日本を指す
import { countries } from 'countries-list';
import countries2 from 'i18n-iso-countries';
const name1 = countries['JP'].name; // "Japan"
const name2 = countries2.getName('JP', 'en'); // "Japan"
すべてが静的データを提供しており、非同期処理や API リクエストは不要です。これにより、初期ロード時のパフォーマンス予測が容易です。
// すべて同期でアクセス可能
const data1 = countries['JP']; // countries-list
const data2 = countries.getName('JP'); // country-list
const data3 = countries.getName('JP', 'ja'); // i18n-iso-countries
国データは静的な巨大オブジェクトであるため、tree-shaking によるバンドルサイズ削減効果は限定的です。必要な国のみをインポートする機能を持つパッケージはほぼありません。
// どのパッケージも全データをインポートする必要がある
import { countries } from 'countries-list'; // 全 250 カ国分のデータ
プロジェクトの要件に応じて、以下のように選択するのが現実的です。
多言語 UI が必要なら i18n-iso-countries
ユーザーの言語設定に応じて国名を表示する必要がある場合、これが唯一の実用的な選択肢です。50 言語以上の翻訳が公式に提供されており、追加作業が最小限で済みます。
通貨や首都などのメタデータが必要なら countries-list
決済機能や配送設定で、通貨コードや首都情報が必要な場合、countries-list がバランス良く情報を提供しています。TypeScript 型定義も付属しており、開発体験が良いです。
国旗絵文字が欲しいなら country-data
国旗絵文字を簡単に使いたい場合、country-data が最も簡単です。ただし、メンテナンス状況に注意し、新規プロジェクトでは代替案(emoji-flag などの別パッケージとの併用)も検討します。
シンプルなコード - 名前対応だけで良いなら country-list
機能過多を避け、国名とコードの対応関係のみが必要な場合、country-list が最小限の依存で済みます。理解しやすく、カスタマイズ也容易です。
規格準拠とコード変換が重要なら iso-3166-1
金融システムや政府系プロジェクトなど、ISO 規格との厳密な整合性が求められる場合、iso-3166-1 が最も信頼できます。3 種類のコード間の変換もサポートしています。
国データパッケージの選択は、プロジェクトの国際化要件と必要なメタデータの種類で決まります。
i18n-iso-countries は多言語対応プロジェクトの第一選択肢です。countries-list はメタデータと型安全性のバランスが取れています。country-data は国旗絵文字が欲しい場合に有用ですが、保守性に注意が必要です。country-list は最小限の機能で十分な場合に適しています。iso-3166-1 は規格準拠が最優先の場合に選択します。
新規プロジェクトでは、i18n-iso-countries(多言語必要時)または countries-list(英語のみで十分時)のどちらかから始めるのが安全な選択です。既存プロジェクトの維持では、現在の使用パッケージの保守状況を確認し、必要に応じて移行を検討します。
国データは一度選定すると変更コストが高いため、プロジェクトの長期的な要件を考慮して慎重に選択することが重要です。
countries-list を選ぶべきなのは、ISO 準拠の国コードと基本情報(国名、首都、通貨、言語など)を軽量に扱いたい場合です。バンドルサイズを気にするプロジェクトや、サーバーサイドレンダリング環境での使用に適しています。多言語対応は限定的ですが、英語表記の信頼性が高いです。
country-list は国名と ISO コードの単純な対応関係のみが必要な場合に最適です。依存関係を最小限に抑えたいプロジェクトや、カスタムのデータ構造を自分で構築する場合に適しています。機能は最小限ですが、その分軽量で理解しやすいです。
iso-3166-1 は ISO 3166-1 規格そのものに厳密に準拠したい場合に選択します。規格コードの検証や、国際標準との整合性が重要な金融・政府系プロジェクトに適しています。機能は限定的ですが、規格準拠の信頼性が高いです。
country-data は国旗絵文字や通貨記号など豊富なメタデータを提供しますが、メンテナンスが停滞している可能性があります。レガシープロジェクトの維持や、特定のメタデータが不可欠な場合に検討します。新規プロジェクトでは他の活発なパッケージの評価を推奨します。
i18n-iso-countries を選ぶべきなのは、多言語対応が必須の国際化プロジェクトです。50 言語以上の翻訳をサポートし、ユーザーの言語設定に応じて国名を表示できます。フォームのドロップダウンや管理画面など、多言語 UI を必要とする場合に最も適しています。
Continents & countries: ISO 3166-1 alpha-2 code (with alpha-2 to alpha-3 set), name, ISO 639-1 languages, capital and ISO 4217 currency codes, native name, calling codes. Lists are available in JSON, CSV and SQL formats. Also, contains separate JSON files with additional country Emoji flags data.
Version 3 comes with some data structure changes. It was completely reworked under the hood with TypeScript, ESM exports and Turborepo file structure.
Everything is strongly typed so you can easily use data with auto-complete in your IDE.
Note: If your projects depend on the old structure, carefully specify required versions in your dependencies.
Package is available via:
bun add countries-listnpm install countries-listcomposer require annexare/countries-listModule exports continents, countries, languages and utility functions.
// Interfaces and types
import type {
ICountry,
ICountryData,
ILanguage,
TContinentCode,
TCountryCode,
TLanguageCode,
} from 'countries-list'
// Main data and utils
import { continents, countries, languages } from 'countries-list'
// Utils
import { getCountryCode, getCountryData, getCountryDataList, getEmojiFlag } from 'countries-list'
// Minimal data in JSON
import countries2to3 from 'countries-list/minimal/countries.2to3.min.json'
import countries3to2 from 'countries-list/minimal/countries.3to2.min.json'
import languageNames from 'countries-list/minimal/languages.native.min'
getCountryCode('Ukraine') // 'UA'
getCountryCode('Україна') // 'UA'
getCountryData('UA') // ICountryData
Built files are in the dist directory of this repository, and packages/countries directory contains source data.
Note: JS build contains ES modules, CommonJS and IIFE (for now)
cjs/index.jsmjs/index.jsindex.iife.jsconst continents = {
AF: 'Africa',
AN: 'Antarctica',
AS: 'Asia',
EU: 'Europe',
NA: 'North America',
OC: 'Oceania',
SA: 'South America',
}
const countries = {
// ...
UA: {
name: 'Ukraine',
native: 'Україна',
phone: [380],
continent: 'EU',
capital: 'Kyiv',
currency: ['UAH'],
languages: ['uk'],
},
// ...
}
const languages = {
// ...
uk: {
name: 'Ukrainian',
native: 'Українська',
},
ur: {
name: 'Urdu',
native: 'اردو',
rtl: 1,
},
// ...
}
Everything is generated from strongly typed files in packages/countries/src, including SQL file.
Everything in dist is generated,
so please make data related changes ONLY to files from packages/countries, commit them.
Use bun run build (or turbo build, turbo test) command to build/test generated files.
Prepared by Annexare Studio from different public sources. Feel free to use it as you need in your apps or send updates into this public repository. It's under MIT license.