countries-and-timezones vs countries-list vs country-data vs world-countries
Selecting Country Data Libraries for Frontend Applications
countries-and-timezonescountries-listcountry-dataworld-countriesSimilar Packages:

Selecting Country Data Libraries for Frontend Applications

These four packages provide static data about countries, including ISO codes, currencies, flags, and timezones. They are used to populate dropdowns, validate forms, or display location information in web apps. countries-and-timezones focuses on timezone mapping, while country-data and countries-list are older general-purpose datasets. world-countries offers a raw JSON collection of country details. Choosing the right one depends on whether you need active maintenance, timezone support, or just simple ISO codes.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
countries-and-timezones558,488272316 kB15a year agoMIT
countries-list01,308274 kB9a month agoMIT
country-data0518-359 years agoMIT
world-countries06,19220.6 MB13a year ago-

Country Data Libraries: Maintenance, API, and Feature Comparison

When building forms, dashboards, or internationalization features, you need reliable country data. The choices range from legacy datasets to actively maintained libraries. Let's compare how countries-and-timezones, countries-list, country-data, and world-countries handle real-world tasks.

🗓️ Maintenance and Data Freshness

Country codes and currencies change over time. Using stale data can cause validation errors or display wrong flags.

countries-and-timezones is actively maintained.

  • Updates reflect changes in timezone rules and country definitions.
  • Safe for long-term projects.
// countries-and-timezones
import c from 'countries-and-timezones';
// Data is fetched via function to ensure latest load
const countries = c.getCountries(); 

countries-list has not seen updates in years.

  • Data is static and frozen at last release.
  • Risk of missing new country codes or currency changes.
// countries-list
import { countries } from 'countries-list';
// Direct import of static object
const country = countries.US; 

country-data is effectively unmaintained.

  • Last update was many years ago.
  • Should not be used in new production apps.
// country-data
import { countries } from 'country-data';
// Static import, likely outdated ISO codes
const country = countries.all.find(c => c.alpha2 === 'US'); 

world-countries provides a raw data dump.

  • Updates depend on community pull requests to the JSON file.
  • Good for static sites, but you must manually update the package.
// world-countries
import countries from 'world-countries';
// Array of objects, needs manual filtering
const country = countries.find(c => c.cca2 === 'US'); 

📦 API Shape and Import Style

How you access the data affects your code structure. Some use functions, others use direct objects or arrays.

countries-and-timezones uses accessor functions.

  • Helps encapsulate data loading.
  • Returns arrays you can map over easily.
// countries-and-timezones
import c from 'countries-and-timezones';
const list = c.getCountries().map(c => ({ label: c.name, value: c.code }));

countries-list exports a keyed object.

  • Fast lookup by country code.
  • Harder to iterate if you need a list.
// countries-list
import { countries } from 'countries-list';
const list = Object.values(countries).map(c => ({ label: c.name, value: c.code }));

country-data exports arrays and objects.

  • Mixed API shape can be confusing.
  • Requires filtering to find specific countries.
// country-data
import { countries } from 'country-data';
const list = countries.all.map(c => ({ label: c.name, value: c.alpha2 }));

world-countries exports a plain array.

  • Standard array methods work immediately.
  • No wrapper logic to learn.
// world-countries
import countries from 'world-countries';
const list = countries.map(c => ({ label: c.name.common, value: c.cca2 }));

🌍 Timezone Support

This is the biggest differentiator. Most country libraries ignore timezones, but some apps need them.

countries-and-timezones includes timezone data built-in.

  • You can link a country to its timezones directly.
  • Saves installing a separate timezone library.
// countries-and-timezones
import c from 'countries-and-timezones';
const timezones = c.getTimezones();
const countryForTz = c.getCountryForTimezone('America/New_York');

countries-list has no timezone support.

  • You must install a separate package for timezones.
  • More bundle size and integration work.
// countries-list
import { countries } from 'countries-list';
// No timezone method available
// Must use external lib like 'timezone-list'

country-data has no timezone support.

  • Focused only on basic country info.
  • Requires external dependencies for time logic.
// country-data
import { countries } from 'country-data';
// No timezone method available
// Must use external lib like 'moment-timezone'

world-countries has no timezone support.

  • Pure country data only.
  • You need to merge timezone data yourself.
// world-countries
import countries from 'world-countries';
// No timezone method available
// Must manually merge with timezone dataset

🏷️ Data Completeness: Flags, Currency, and Codes

Different apps need different fields. Some packages include flags, others do not.

countries-and-timezones includes codes and timezones.

  • Flags are not always included by default.
  • Focus is on logic rather than UI assets.
// countries-and-timezones
import c from 'countries-and-timezones';
const { code, name, timezones } = c.getCountries()[0];
// Flag emoji might need separate handling

countries-list includes flags and currency.

  • Good for UI dropdowns showing flags.
  • Currency data is basic.
// countries-list
import { countries } from 'countries-list';
const { name, currency, flag } = countries.US;
// Flag is emoji string

country-data includes extensive metadata.

  • Has currency symbols and names.
  • Data is old, so currency info might be wrong.
// country-data
import { countries } from 'country-data';
const { currencyCodes, name } = countries.US;
// Currency codes may be outdated

world-countries includes comprehensive ISO data.

  • Has multiple name variants and flags.
  • Best for strict ISO compliance.
// world-countries
import countries from 'world-countries';
const { cca2, name, flags } = countries.find(c => c.cca2 === 'US');
// Flags include SVG and PNG paths

📊 Summary Table

Featurecountries-and-timezonescountries-listcountry-dataworld-countries
Maintenance✅ Active❌ Stale❌ Unmaintained⚠️ Community
Timezones✅ Built-in❌ None❌ None❌ None
API StyleFunctionsObjectMixedArray
Flags⚠️ Limited✅ Emoji❌ None✅ Paths/Emoji
Best ForTimezone LogicSimple ListsLegacy AppsStatic Data

💡 Final Recommendation

countries-and-timezones is the top pick for modern apps — especially if you deal with scheduling or global users. It balances maintenance with useful features.

world-countries is great if you want raw data without library overhead. It works well for static sites or build-time generation.

countries-list is okay for very simple dropdowns, but be aware the data is old.

country-data should be avoided in new work. It is outdated and lacks the reliability needed for production systems.

Final Thought: Always check when the package was last updated before installing. Country data changes — your library should too.

How to Choose: countries-and-timezones vs countries-list vs country-data vs world-countries

  • countries-and-timezones:

    Choose countries-and-timezones if your app relies heavily on timezone logic, such as scheduling or converting times across regions. It is actively maintained and provides reliable mappings between countries and their timezones. This is the best option for modern apps needing up-to-date timezone rules.

  • countries-list:

    Choose countries-list if you need a lightweight, simple list of countries with basic properties like name and code. It is suitable for static dropdowns where data freshness is not critical. Avoid this for projects requiring currency or timezone details, as it lacks depth.

  • country-data:

    Avoid country-data for new projects because it is no longer maintained and data is outdated. Only use this if you are legacy-maintaining an old system that already depends on it. For any new work, pick a modern alternative to ensure ISO codes and currencies are current.

  • world-countries:

    Choose world-countries if you want full control over the data structure and prefer importing raw JSON. It is useful for build-time processing or when you need to bundle specific country attributes without extra library logic. Best for static sites where data does not change often.

README for countries-and-timezones

countries-and-timezones

GitHub Actions Status NPM Downloads License: MIT

Minimalistic library to work with countries and timezones data. Updated with the IANA timezones database.

Usage

NodeJS

Install with npm or yarn:

npm install --save countries-and-timezones

Browser

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>

API

.getCountry(id, options = {})

Returns a country referenced by its id.

Accepts a parameter with options.

Example

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.

Example

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.

Example

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.

Example

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.

Example

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.

Example

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.

Example

const ct = require("countries-and-timezones");

const timezone = ct.getCountryForTimezone("Europe/Zurich");
console.log(timezone);

/*
Prints:

{
  "id": "CH",
  "name": "Switzerland",
  "timezones": [
    "Europe/Zurich"
  ]
}

*/

options

Available options for functions are:

ParameterTypeDescription
deprecatedBooleanIndicates if the result should include deprecated timezones or not. By default no deprecated timezones are included.

Data models

Country

A country is defined by the following parameters:

ParameterTypeDescription
idStringThe country ISO 3166-1 code.
nameStringPreferred name of the country.
timezonesArray[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'
  ]
}

Timezone

A timezone is defined by the following parameters:

ParameterTypeDescription
nameStringThe 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.
utcOffsetNumberThe difference in minutes between the timezone and UTC.
utcOffsetStrStringThe difference in hours and minutes between the timezone and UTC, expressed as string with format: ±[hh]:[mm].
dstOffsetNumberThe 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.
dstOffsetStrStringThe difference in hours and minutes between the timezone and UTC during daylight saving time (DST, expressed as string with format: ±[hh]:[mm].
aliasOfStringThe name of a primary timezone in case this is an alias. null means this is a primary timezone.
deprecatedBooleantrue 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
}

Related projects

Support

Consider sponsoring this project.

Working on something more complex?

Meet Spott:

  • Search any city, country or administrative division in the world. By full strings or autocompletion.
  • Find a place by an IP address.
  • Access to more than 240,000 geographical places. In more than 20 languages.

Spott API for cities, countries and administrative divisions

License

MIT