countries-and-timezones、countries-list、country-data、world-countries は、いずれもアプリケーションで国名、通貨、タイムゾーン、電話番号などの地理情報を扱うための npm パッケージです。これらは、静的なデータセットを提供することで、外部 API に依存せずにフォームのドロップダウンリストやユーザープロファイルの表示を実装できるようにします。ただし、データの鮮度、メンテナンス状況、そして提供する情報の詳細さには大きな違いがあります。
フロントエンド開発において、ユーザーの国籍選択、タイムゾーン設定、通貨表示などは頻繁に発生する要件です。外部 API を毎回叩くのはパフォーマンスの無駄であり、ローカルで完結する静的データパッケージの利用が一般的です。しかし、npm には類似パッケージが溢れており、どれを選ぶべきか迷うことが多いでしょう。
ここでは、countries-and-timezones、countries-list、country-data、world-countries の 4 つを取り上げ、実務的な観点から技術的な違いを明確にします。
パッケージごとにデータの持ち方が異なります。これは、コンポーネント内でデータをどう展開するかに直接影響します。
countries-and-timezones
国とタイムゾーンが統合されたオブジェクトを提供します。国コードをキーに、関連するタイムゾーン配列を直接取得できます。
import c from 'countries-and-timezones';
// 国コードからタイムゾーンを取得
const timezones = c.getTimezonesForCountry('JP');
// 出力: ['Asia/Tokyo']
// 全ての国リストを取得
const countries = c.getCountries();
countries-list
シンプルな配列またはオブジェクトで国情報を返します。構造は平坦で、タイムゾーン情報は含まれていないことがほとんどです。
import { countries } from 'countries-list';
// 国リストをイテレート
Object.values(countries).forEach(country => {
console.log(country.name, country.iso2);
});
country-data
階層的なデータ構造を持ち、通貨や電話番号など詳細な情報を含みます。ただし、データの取得には特定のメソッドチェーンが必要です。
import countries from 'country-data';
// 国コードで検索
countries.countries['JP'].name;
// 通貨情報を取得
countries.countries['JP'].currencies;
world-countries
JSON データセットをそのままエクスポートする形式が多く、それをインポートして使用します。ラッパー関数よりもデータそのものを扱う感覚に近いです。
import countries from 'world-countries';
// 配列として直接アクセス
const japan = countries.find(c => c.cca2 === 'JP');
console.log(japan.name.common);
グローバルアプリケーションでは、国選択後に適切なタイムゾーンを表示する必要があります。ここで各パッケージの差が顕著になります。
countries-and-timezones
名前の通り、この機能がコアです。国コードからタイムゾーンへのマッピングが最初から用意されています。
import c from 'countries-and-timezones';
const tzList = c.getTimezonesForCountry('US');
// ['America/New_York', 'America/Chicago', ...]
countries-list
タイムゾーンデータは含まれていません。別途 moment-timezone などのライブラリと組み合わせる必要があり、実装コストが増加します。
import { countries } from 'countries-list';
// タイムゾーン取得機能は存在しない
// 別途実装が必要:const tz = moment.tz.guess();
country-data
国データにタイムゾーンが含まれている場合がありますが、配列形式での取得が面倒な場合があります。データ構造が古く、最新の IANA タイムゾーンデータベースと一致しないリスクがあります。
import countries from 'country-data';
// 直接タイムゾーン配列を取得する標準メソッドは乏しい
// 生データから抽出する必要がある場合が多い
world-countries
地理情報に焦点を当てており、タイムゾーン情報は含まれていないか、限定的です。地理座標(緯度・経度)などのデータは豊富ですが、タイムゾーン管理には向きません。
import countries from 'world-countries';
// 地理データは豊富だが、タイムゾーンリストは提供されない
const coords = countries.find(c => c.cca2 === 'JP').latlng;
オープンソースパッケージを選ぶ際、メンテナンスされているかはバグ修正やデータ更新の観点で最重要です。
countries-and-timezones
定期的に更新されており、新しい国名の変更やタイムゾーンの修正に対応しています。TypeScript の型定義もパッケージに含まれているか、別途充実しており、開発体験が良いです。
// TypeScript で型推論が効く
import c from 'countries-and-timezones';
const name: string = c.getCountry('JP').name; // ✅ 型安全
countries-list
更新頻度は低く、機能追加もほとんどありません。シンプルであることは利点ですが、国際情勢の変化(国名の正式名称変更など)への追従が遅れる可能性があります。
// 更新が止まっていると、新しい国コードに対応できない
// 例:国名変更などが反映されないリスク
country-data
⚠️ 非推奨のリスク大。多くのレポジトリで更新が止まっており、npm 上でも非推奨(deprecated)として警告される場合があります。新しいプロジェクトで採用すると、将来的な技術的負債になります。
// 警告:メンテナンスされていない可能性が高い
// 依存関係に問題が生じた場合、修正が困難
world-countries
コミュニティによって維持されている側面がありますが、更新のタイミングは一定ではありません。データソースが明確な場合(例えば UN や ISO 基準)は信頼できますが、パッケージごとの差異を確認する必要があります。
// データソースの確認が必要
// ISO 3166 基準などに準拠しているか README を確認
実際の開発現場では、要件に応じて使い分けます。
ユーザーに国とタイムゾーンを選ばせる場合、2 つのパッケージを組み合わせるのは非効率です。
countries-and-timezonesimport c from 'countries-and-timezones';
function RegistrationForm() {
const countries = c.getCountries();
// 国選択時にタイムゾーンも即座に取得可能
}
タイムゾーン不要で、とにかく軽量な国名リストだけが欲しい場合です。
countries-listimport { countries } from 'countries-list';
function CountrySelect() {
return Object.values(countries).map(c => (
<option value={c.iso2}>{c.name}</option>
));
}
既に country-data に依存しているコードベースのリファクタリング前です。
country-data// 既存のラッパー関数に依存している場合、即時変更はリスク大
import countries from 'country-data';
国境線や緯度経度データが必要な場合です。
world-countriesimport countries from 'world-countries';
// マップの初期位置などに使用
const center = countries.find(c => c.cca2 === 'FR').latlng;
| 特徴 | countries-and-timezones | countries-list | country-data | world-countries |
|---|---|---|---|---|
| 主要用途 | 国+タイムゾーン管理 | 簡易国リスト | 詳細国情報(通貨等) | 地理情報データ |
| タイムゾーン | ✅ 統合済み | ❌ 非対応 | ⚠️ 限定的 | ❌ 非対応 |
| メンテナンス | ✅ 活発 | ⚠️ 低頻度 | ❌ 停止リスク | 🟡 中程度 |
| TypeScript | ✅ 対応 | ⚠️ 外部定義 | ⚠️ 外部定義 | 🟡 対応 |
| 新規推奨度 | 🌟 高い | 🟡 普通 | ❌ 非推奨 | 🟡 特殊用途 |
迷ったら countries-and-timezones を選んでください。
フロントエンドアプリケーションにおいて、国データとタイムゾーンはセットで扱われることがほとんどです。これを別々のパッケージで管理するのは、コードの複雑化とデータ不整合のリスクを生みます。countries-and-timezones はその課題を解決し、かつ積極的にメンテナンスされています。
country-data は過去の遺産として扱い、新規プロジェクトでは避けるのが賢明です。countries-list や world-countries は、タイムゾーンが不要な場合や、地理座標データが明確に必要な場合など、特定のニッチな要件がある時にのみ検討しましょう。
データはアプリケーションの基盤です。更新が止まったデータソースに依存することは、将来的なバグやセキュリティ問題の元になります。信頼性の高いパッケージを選ぶことが、結果的に開発コストの削減につながります。
最新のデータと積極的なメンテナンスを重視する場合は countries-and-timezones が最適です。国データとタイムゾーンデータが統合されており、TypeScript 定義も充実しているため、モダンなフロントエンド開発において最も信頼性の高い選択肢となります。
非常にシンプルな国リストのみが必要で、タイムゾーンや通貨などの追加データが不要な場合に countries-list を検討できます。ただし、機能が限定的であり、複雑な要件には対応できないため、小規模なプロジェクト向けです。
country-data はかつて人気でしたが、現在はメンテナンスが停止している可能性が高いため、新しいプロジェクトでの使用は避けるべきです。既に導入されているレガシーシステムでのみ使用を検討し、新規採用の場合は代替パッケージへの移行を計画してください。
特定のデータフォーマットや軽量なセットを必要とする場合 world-countries が候補になりますが、コミュニティの規模と更新頻度は countries-and-timezones に劣ります。特殊な要件がない限り、より標準的なパッケージを選ぶのが無難です。
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