これらのライブラリは、Web アプリケーションで国名、ISO コード、タイムゾーン、通貨などの地理的データを扱うためのnpm パッケージです。i18n-iso-countries は多言語対応に強く、countries-and-timezones はタイムゾーンとの紐付けに特化しています。一方、country-list や countries-list はシンプルなリスト提供を目的とし、country-data は電話コードや通貨など豊富なメタデータを含みます。iso-3166-1 は標準規格そのものに焦点を当てています。これらを適切に選択することで、フォームの国選択プルダウン、ユーザープロファイルの地域設定、ログのタイムゾーン処理などを効率的に実装できます。
フロントエンド開発において、国名選択プルダウン、ユーザーの地域設定、ログのタイムゾーン処理などは頻出する要件です。しかし、国に関するデータは単なる名前リストではなく、ISO コード、タイムゾーン、通貨、電話コードなど多岐にわたります。今回は、代表的な 6 つのパッケージ(countries-and-timezones、countries-list、country-data、country-list、i18n-iso-countries、iso-3166-1)を比較し、それぞれの適切な使いどころを明確にします。
パッケージによって、データへのアクセス方法が異なります。静的なオブジェクトをエクスポートするものと、関数を呼び出してデータを取得するものに分かれます。
countries-and-timezones は、静的なオブジェクトをエクスポートします。
countries オブジェクトから直接データにアクセスできます。// countries-and-timezones
import cctz from 'countries-and-timezones';
const country = cctz.countries['JP'];
console.log(country.name); // "Japan"
console.log(country.timezones); // ["Asia/Tokyo"]
countries-list も同様に静的なオブジェクトを提供します。
// countries-list
import { countries } from 'countries-list';
const country = countries['JP'];
console.log(country.name); // "Japan"
console.log(country.currency); // "JPY"
country-data は、配列形式でデータをエクスポートします。
all 配列からフィルタリングして使用するスタイルです。// country-data
import data from 'country-data';
const japan = data.countries.all.find(c => c.alpha2 === 'JP');
console.log(japan.name); // "Japan"
console.log(japan.countryCallingCodes); // ["+81"]
country-list は、変換関数を提供するスタイルです。
// country-list
import { getCode, getName } from 'country-list';
const code = getCode('Japan'); // "JP"
const name = getName('JP'); // "Japan"
i18n-iso-countries は、言語を指定して名前を取得する関数を提供します。
// i18n-iso-countries
import countries from 'i18n-iso-countries';
import ja from 'i18n-iso-countries/langs/ja.json';
countries.registerLocale(ja);
console.log(countries.getName('JP', 'ja')); // "日本"
iso-3166-1 は、リストと検索関数の両方を提供します。
// iso-3166-1
import { alpha2, alpha3 } from 'iso-3166-1';
const country = alpha2.get('JP');
console.log(country.name); // "Japan"
console.log(country.alpha3); // "JPN"
グローバルなアプリケーションでは、国名をユーザーの言語で表示する必要があります。この対応状況はパッケージ間で大きな差があります。
i18n-iso-countries は、多言語対応に最も優れています。
// i18n-iso-countries
import en from 'i18n-iso-countries/langs/en.json';
import fr from 'i18n-iso-countries/langs/fr.json';
countries.registerLocale(en);
countries.registerLocale(fr);
console.log(countries.getName('DE', 'en')); // "Germany"
console.log(countries.getName('DE', 'fr')); // "Allemagne"
countries-and-timezones は、英語名が基本です。
// countries-and-timezones
const country = cctz.countries['DE'];
console.log(country.name); // "Germany" (英語のみ)
// 他言語にするには独自の実装が必要
countries-list は、英語名が基本です。
// countries-list
const country = countries['DE'];
console.log(country.name); // "Germany" (英語のみ)
country-data は、英語名が基本です。
// country-data
const country = data.countries.all.find(c => c.alpha2 === 'DE');
console.log(country.name); // "Germany" (英語のみ)
country-list は、英語名が基本です。
// country-list
console.log(getName('DE')); // "Germany" (英語のみ)
iso-3166-1 は、英語名が基本です。
// iso-3166-1
const country = alpha2.get('DE');
console.log(country.name); // "Germany" (英語のみ)
国データと共にタイムゾーンを扱いたい場合、パッケージの選択がアーキテクチャに大きく影響します。
countries-and-timezones は、この分野で最も強力です。
// countries-and-timezones
const tz = cctz.countries['US'].timezones;
console.log(tz); // ["America/New_York", "America/Chicago", ...]
const city = cctz.getCityByTimezone('Asia/Tokyo');
console.log(city); // { name: "Tokyo", country: "JP" }
countries-list は、タイムゾーンデータを含みません。
luxon や date-fns-tz など別のライブラリと組み合わせる必要があります。// countries-list
const country = countries['US'];
console.log(country.timezones); // undefined (存在しない)
country-data は、タイムゾーンデータを含みません。
// country-data
const country = data.countries.all.find(c => c.alpha2 === 'US');
console.log(country.timezones); // undefined (存在しない)
country-list は、タイムゾーンデータを含みません。
// country-list
// タイムゾーン関連のメソッドは存在しません
i18n-iso-countries は、タイムゾーンデータを含みません。
// i18n-iso-countries
// タイムゾーン関連のメソッドは存在しません
iso-3166-1 は、タイムゾーンデータを含みません。
// iso-3166-1
// タイムゾーン関連のメソッドは存在しません
オープンソースパッケージを選ぶ際、メンテナンス状況は重要な判断基準です。一部のパッケージは更新が止まっているか、非推奨のアナウンスがあります。
country-data は、メンテナンスが停滞しています。
i18n-iso-countries などの活発なパッケージへの移行を推奨します。// country-data (非推奨のリスクあり)
// 新規プロジェクトでは使用を避けるべきです
import data from 'country-data';
countries-list と country-list は、シンプルなため更新頻度は低めです。
// countries-list / country-list
// 安定したシンプルなライブラリとして利用可能
import { countries } from 'countries-list';
i18n-iso-countries と countries-and-timezones は、活発にメンテナンスされています。
// i18n-iso-countries / countries-and-timezones
// 積極的にメンテナンスされているため推奨
import countries from 'i18n-iso-countries';
iso-3166-1 は、規格変更がない限り更新は少ないです。
// iso-3166-1
// 規格準拠が必要な特殊ケースで使用
import { alpha2 } from 'iso-3166-1';
実際のユースケースとして、国選択フォームと電話番号バリデーションを実装する場合の違いを見てみましょう。
i18n-iso-countries を使った多言語フォームの場合:
// i18n-iso-countries
const getCountryOptions = (lang) => {
return countries.getNames(lang).map(code => ({
value: code,
label: countries.getName(code, lang)
}));
};
// 使用例:日本語
const jaOptions = getCountryOptions('ja');
countries-and-timezones を使ったタイムゾーン連動フォームの場合:
// countries-and-timezones
const getTimezonesForCountry = (code) => {
return cctz.countries[code].timezones;
};
// 使用例:アメリカのタイムゾーン
const usTimezones = getTimezonesForCountry('US');
country-data を使った電話番号バリデーションの場合:
// country-data
const getPhoneCode = (alpha2) => {
const country = data.countries.all.find(c => c.alpha2 === alpha2);
return country ? country.countryCallingCodes[0] : null;
};
// 使用例:日本の国番號
const jpCode = getPhoneCode('JP'); // "+81"
countries-list / country-list / iso-3166-1 の場合:
// countries-list
const getCountryName = (code) => countries[code]?.name || '';
// country-list
const name = getName('JP');
// iso-3166-1
const country = alpha2.get('JP');
const name = country ? country.name : '';
| 要件 | 推奨パッケージ | 理由 |
|---|---|---|
| 多言語対応必須 | i18n-iso-countries | 60 以上の言語パックがあり、国際化に最適 |
| タイムゾーン連携 | countries-and-timezones | 国とタイムゾーンの紐付けデータが充実 |
| 電話コード・通貨 | country-data (※注意) | メタデータが豊富だが、保守状況に注意 |
| 軽量・シンプル | countries-list / country-list | 機能が絞られており、バンドルサイズが小さい |
| 規格準拠重視 | iso-3166-1 | ISO 標準データそのものを扱える |
| 新規プロジェクト | i18n-iso-countries | 保守が活発で、拡張性が高い |
国データライブラリの選択は、単に「国名が欲しい」だけでなく、プロジェクトの国際化戦略やデータ要件に依存します。
i18n-iso-countries は、現代の Web アプリケーションにおいて最もバランスの取れた選択肢です。多言語対応が標準となりつつある現在、このパッケージの柔軟性は大きなメリットになります。保守状況も良好で、長期的な視点でも安心できます。
countries-and-timezones は、タイムゾーン処理が重要なアプリケーション(スケジューラー、ログ分析、グローバルチームツールなど)で真価を発揮します。国コードからタイムゾーンを即座に解決できるため、実装コストを大幅に削減できます。
country-data は豊富なメタデータを持っていますが、メンテナンスの停滞が懸念されます。電話コードや通貨データがどうしても必要な場合は、公式の API や他の信頼できるデータソースとの併用を検討すべきです。
countries-list、country-list、iso-3166-1 は、特定のシンプルな要件や、規格準拠が求められる特殊なケースで有効です。しかし、汎用的なアプリケーションでは、より機能豊富なパッケージを選ぶ方が、将来的な拡張性を確保できます。
最終的には、プロジェクトの「国際化の必要性」と「必要なメタデータの範囲」を明確に定義した上で、適切なパッケージを選定することが重要です。
国とタイムゾーンの紐付けが必要な場合に選択します。ユーザーの所在地に基づいてタイムゾーンを自動推論したい場合や、国コードからタイムゾーン一覧を取得したいケースに最適です。他のパッケージに比べてタイムゾーンデータが充実しており、地理的な位置情報との連携が強いプロジェクトに向いています。
非常に軽量でシンプルな国名リストが必要な場合に選択します。ISO コードや詳細なメタデータが不要で、とにかく高速に国名配列が欲しいというシンプルな要件に適しています。機能が少ない分、バンドルサイズを最小限に抑えたい小規模プロジェクトや、カスタムデータ構造を自分で構築したい場合に有用です。
電話コード、通貨、国旗絵文字など、国に関する豊富なメタデータが必要な場合に選択します。フォーム入力での電話番号検証や、通貨表示のロジックを実装する際に便利です。ただし、メンテナンス状況に注意が必要で、長期プロジェクトでは代替案の検討も推奨されます。
ISO 3166-1 alpha-2 コードと国名のマッピングが主目的の場合に選択します。シンプルに国コードから国名を引きたい、またはその逆を行いたいという基本的なニーズに答えます。多言語対応やタイムゾーン機能は含まれないため、単一言語のシンプルなアプリケーションに適しています。
多言語対応(i18n)が必須のプロジェクトで選択します。60 以上の言語で国名を取得でき、国際化を重視するエンタープライズアプリケーションに最適です。ISO 標準への準拠度も高く、言語切り替え機能を持つサイトではほぼ一択となるパッケージです。
ISO 3166-1 規格そのもののデータ構造を厳密に扱いたい場合に選択します。国名よりもコード定義や規格準拠を重視するシステム連携や、データ検証ロジックの基盤として利用します。汎用性よりも標準規格との完全な一致を求める特殊なユースケースに向いています。
Minimalistic library to work with countries and timezones data. Updated with the IANA timezones database.
Install with npm or yarn:
npm install --save countries-and-timezones
Add the following script to your project (only ~9kb):
<!-- Latest version -->
<script
src="https://cdn.jsdelivr.net/gh/manuelmhtr/countries-and-timezones@latest/dist/index.min.js"
type="text/javascript"
></script>
<!-- Or specify a version -->
<script
src="https://cdn.jsdelivr.net/gh/manuelmhtr/countries-and-timezones@v3.8.0/dist/index.min.js"
type="text/javascript"
></script>
<!-- This will export a variable named "ct": -->
<script type="text/javascript">
var data = ct.getCountry("MX");
console.log(data);
</script>
.getCountry(id, options = {})Returns a country referenced by its id.
Accepts a parameter with options.
const ct = require("countries-and-timezones");
const country = ct.getCountry("DE");
console.log(country);
/*
Prints:
{
id: 'DE',
name: 'Germany',
timezones: [ 'Europe/Berlin', 'Europe/Zurich' ]
}
*/
.getTimezone(name)Returns a timezone referenced by its name.
const ct = require("countries-and-timezones");
const timezone = ct.getTimezone("America/Los_Angeles");
console.log(timezone);
/*
Prints:
{
name: 'America/Los_Angeles',
countries: [ 'US' ],
utcOffset: -480,
utcOffsetStr: '-08:00',
dstOffset: -420,
dstOffsetStr: '-07:00',
aliasOf: null
}
*/
.getAllCountries(options = {})Returns an object with the data of all countries.
Accepts a parameter with options.
const ct = require("countries-and-timezones");
const countries = ct.getAllCountries();
console.log(countries);
/*
Prints:
{
AD: {
id: 'AD',
name: 'Andorra',
timezones: [ 'Europe/Andorra' ]
},
AE: {
id: 'AE',
name: 'United Arab Emirates',
timezones: [ 'Asia/Dubai' ]
},
AF: {
id: 'AF',
name: 'Afghanistan',
timezones: [ 'Asia/Kabul' ]
},
AG: {
id: 'AG',
name: 'Antigua and Barbuda',
timezones: [ 'America/Puerto_Rico' ]
},
...
}
*/
.getAllTimezones(options = {})Returns an object with the data of all timezones.
Accepts a parameter with options.
const ct = require("countries-and-timezones");
const timezones = ct.getAllTimezones();
console.log(timezones);
/*
Prints:
{
"Africa/Abidjan": {
"name": "Africa/Abidjan",
"countries": [
"CI", "BF", "GH",
"GM", "GN", "ML",
"MR", "SH", "SL",
"SN", "TG"
],
"utcOffset": 0,
"utcOffsetStr": "+00:00",
"dstOffset": 0,
"dstOffsetStr": "+00:00",
"aliasOf": null
},
"Africa/Algiers": {
"name": "Africa/Algiers",
"countries": [
"DZ"
],
"utcOffset": 60,
"utcOffsetStr": "+01:00",
"dstOffset": 60,
"dstOffsetStr": "+01:00",
"aliasOf": null
},
"Africa/Bissau": {
"name": "Africa/Bissau",
"countries": [
"GW"
],
"utcOffset": 0,
"utcOffsetStr": "+00:00",
"dstOffset": 0,
"dstOffsetStr": "+00:00",
"aliasOf": null
},
...
}
*/
.getTimezonesForCountry(id, options = {})Returns an array with all the timezones of a country given its id.
Accepts a parameter with options.
const ct = require("countries-and-timezones");
const timezones = ct.getTimezonesForCountry("MX");
console.log(timezones);
/*
Prints:
[
{
"name": "America/Bahia_Banderas",
"countries": [ "MX" ],
"utcOffset": -360,
"utcOffsetStr": "-06:00",
"dstOffset": -300,
"dstOffsetStr": "-05:00",
"aliasOf": null
},
{
"name": "America/Cancun",
"countries": [ "MX" ],
"utcOffset": -300,
"utcOffsetStr": "-05:00",
"dstOffset": -300,
"dstOffsetStr": "-05:00",
"aliasOf": null
},
{
"name": "America/Chihuahua",
"countries": [ "MX" ],
"utcOffset": -420,
"utcOffsetStr": "-07:00",
"dstOffset": -360,
"dstOffsetStr": "-06:00",
"aliasOf": null
},
...
}
*/
.getCountriesForTimezone(name, options = {})Returns a list of the countries that uses a timezone given its name. When a timezone has multiple countries the first element is more relevant due to its geographical location.
Accepts a parameter with options.
const ct = require("countries-and-timezones");
const timezone = ct.getCountriesForTimezone("Europe/Zurich");
console.log(timezone);
/*
Prints:
[
{
"id": "CH",
"name": "Switzerland",
"timezones": [
"Europe/Zurich"
]
},
{
"id": "DE",
"name": "Germany",
"timezones": [
"Europe/Berlin",
"Europe/Zurich"
]
},
{
"id": "LI",
"name": "Liechtenstein",
"timezones": [
"Europe/Zurich"
]
}
]
*/
.getCountryForTimezone(name, options = {})Returns a the most relevant country (due to its geographical location) that uses a timezone given its name.
Accepts a parameter with options.
const ct = require("countries-and-timezones");
const timezone = ct.getCountryForTimezone("Europe/Zurich");
console.log(timezone);
/*
Prints:
{
"id": "CH",
"name": "Switzerland",
"timezones": [
"Europe/Zurich"
]
}
*/
optionsAvailable options for functions are:
| Parameter | Type | Description |
|---|---|---|
deprecated | Boolean | Indicates if the result should include deprecated timezones or not. By default no deprecated timezones are included. |
A country is defined by the following parameters:
| Parameter | Type | Description |
|---|---|---|
id | String | The country ISO 3166-1 code. |
name | String | Preferred name of the country. |
timezones | Array[String] | The list of timezones used in the country. |
{
id: 'MX',
name: 'Mexico',
timezones: [
'America/Bahia_Banderas',
'America/Cancun',
'America/Chihuahua',
'America/Hermosillo',
'America/Matamoros',
'America/Mazatlan',
'America/Merida',
'America/Mexico_City',
'America/Monterrey',
'America/Ojinaga',
'America/Tijuana'
]
}
A timezone is defined by the following parameters:
| Parameter | Type | Description |
|---|---|---|
name | String | The name of the timezone, from tz database. |
countries | [String] | A list of ISO 3166-1 codes of the countries where it's used. Etc/*, GMT and UTC timezones don't have associated countries. |
utcOffset | Number | The difference in minutes between the timezone and UTC. |
utcOffsetStr | String | The difference in hours and minutes between the timezone and UTC, expressed as string with format: ±[hh]:[mm]. |
dstOffset | Number | The difference in minutes between the timezone and UTC during daylight saving time (DST). When utcOffset and dstOffset are the same, means that the timezone does not observe a daylight saving time. |
dstOffsetStr | String | The difference in hours and minutes between the timezone and UTC during daylight saving time (DST, expressed as string with format: ±[hh]:[mm]. |
aliasOf | String | The name of a primary timezone in case this is an alias. null means this is a primary timezone. |
deprecated | Boolean | true when the timezone has been deprecated, otherwise this property is not returned. |
{
name: 'Asia/Tel_Aviv',
countries: [ 'IL' ],
utcOffset: 120,
utcOffsetStr: '+02:00',
dstOffset: 180,
dstOffsetStr: '+03:00',
aliasOf: 'Asia/Jerusalem',
deprecated: true
}
Consider sponsoring this project.
Meet Spott:
MIT