Skip to content

coroboros/location-timezone

Repository files navigation

@coroboros/location-timezone

@coroboros/location-timezone

Capital, country, city, ANSI state, and IANA timezone lookups for Node.js.

Curated UN country names, CIA Factbook official forms, ISO 3166-1 codes, ANSI FIPS state codes, IANA timezones, and ~40,000 city coordinates. One zipson-compressed package. O(1) lookups.

npm ci license stars coroboros.com

Contents

Requirements

  • Node.js >= 22 LTS. Use fnm for fast Rust-based version switching.
  • Any modern package manager: pnpm, npm, yarn, bun.

Install

pnpm add @coroboros/location-timezone
npm install @coroboros/location-timezone
yarn add @coroboros/location-timezone
bun add @coroboros/location-timezone

Usage

// ESM (recommended) — named imports
import {
  findCapitalOfCountryIso,
  findTimezoneByCityName,
  getCountries,
} from '@coroboros/location-timezone';

findCapitalOfCountryIso('JP');         // → { name: 'Tokyo', ... }
findTimezoneByCityName('Göteborg');    // → 'Europe/Stockholm'
getCountries();                        // → Country[]
// ESM — default merged object
import locationTimezone from '@coroboros/location-timezone';

locationTimezone.findCountryByIso('USA');
// CommonJS
const locationTimezone = require('@coroboros/location-timezone').default;

locationTimezone.findStateAnsiByUspsCode('NY');

Why this exists

Country, capital, city, ANSI state, and timezone data normally ships in separate npm packages with mismatched cross-references. @coroboros/location-timezone consolidates them into one zipson-compressed payload: UN country names, CIA Factbook official forms, ISO 3166-1 codes, ANSI FIPS state codes, IANA timezones, and ~40,000 cities with coordinates. Lookups resolve in O(1) via Map and Set indexes built once at module load. See bench/baseline.md for the head-to-head numbers vs the pre-optim linear-scan baseline.

Data

  • Country names and ISO 3166-1 alpha-2 / alpha-3 codes from the UN country list and the CIA World Factbook.
  • ANSI USA state codes — FIPS state code, GNISID, official USPS code.
  • IANA timezones from Intl.supportedValuesOf('timeZone') (run by the latest Node.js LTS).
  • City coordinates in decimal degrees.
  • Three non-ISO entries assigned internal codes: Northern Cyprus (XC/CYN), Kosovo (XK/KOS), Somaliland (XS/SOL).
  • Absent fields hold ''. No null. No undefined.
  • Payloads are compressed with zipson and parsed once at module load.

API

Types

Capital

A country's capital city.

Property Type Description
name string UTF-8 name. Empty string when the country has no capital.
nameAscii string ASCII transliteration.
latitude number Decimal degrees.
longitude number Decimal degrees.
province string
state string USPS code (US only). Empty string otherwise.
timezone string IANA timezone.
country? Country Back-reference. Always present at runtime on capitals returned by the API.
Coordinates

Bounding-box bounds for findLocationsByCoordinates. Pass at least one latitude bound and one longitude bound; missing bounds default to ±Infinity.

Property Type Default Description
latitudeFrom? number Number.NEGATIVE_INFINITY Southern latitude bound.
latitudeTo? number Number.POSITIVE_INFINITY Northern latitude bound.
longitudeFrom? number Number.NEGATIVE_INFINITY Western longitude bound.
longitudeTo? number Number.POSITIVE_INFINITY Eastern longitude bound.
Country

A country with ISO codes and IANA timezones.

Property Type Description
name string UN short form.
officialName string UN long form.
iso2 string ISO 3166-1 alpha-2.
iso3 string ISO 3166-1 alpha-3.
timezones ReadonlyArray<string> IANA timezones, sorted ascending.
capital? Capital Back-reference. Always present at runtime on countries returned by the API.
Location

A city with coordinates and its country.

Property Type Description
city string UTF-8 name.
cityAscii string ASCII transliteration.
country Country The country it belongs to.
latitude number Decimal degrees.
longitude number Decimal degrees.
province string
state string USPS code (US only). Empty string otherwise.
timezone string IANA timezone.
StateAnsi

A US state with ANSI identifiers.

Property Type Description
fipsCode string FIPS state code (2 digits).
gnisid string Geographic Names Information System Identifier (8 digits).
name string State name.
uspsCode string USPS two-letter code.

Capitals and countries

findCapitalOfCountryIso(code)

Find the capital of a country by its ISO 3166-1 alpha-2 or alpha-3 code. Case-insensitive.

Parameters

Option Type Default Description
code string (required) Country ISO code (alpha-2 or alpha-3).

ReturnsCapital | undefined. The matching capital, or undefined when code does not resolve.

Examples

findCapitalOfCountryIso('JP');   // → { name: 'Tokyo', ... }
findCapitalOfCountryIso('jpn');  // → { name: 'Tokyo', ... }
findCapitalOfCountryIso('XX');   // → undefined
findCapitalOfCountryName(name)

Find the capital of a country by short or official name. Case-insensitive.

Parameters

Option Type Default Description
name string (required) Country name (UN short form or official form).

ReturnsCapital | undefined. The matching capital, or undefined when name does not resolve.

Examples

findCapitalOfCountryName('Japan');                            // → { name: 'Tokyo', ... }
findCapitalOfCountryName('British Indian Ocean Territory');   // → { name: 'Diego Garcia', ... }
findCapitalOfCountryName('The British Indian Ocean Territory'); // same — official form
findCountryByCapitalName(name)

Find a country by its capital name (UTF-8 or ASCII). Case-insensitive.

Parameters

Option Type Default Description
name string (required) Capital name (Capital.name or Capital.nameAscii).

ReturnsCountry | undefined. The matching country, or undefined when name does not resolve.

Examples

findCountryByCapitalName('Tokyo');         // → { name: 'Japan', ... }
findCountryByCapitalName('Diego Garcia');  // → { name: 'British Indian Ocean Territory', ... }
findCountryByCapitalName('');              // → undefined
findCountryByIso(code)

Find a country by ISO 3166-1 alpha-2 or alpha-3 code. Case-insensitive.

Parameters

Option Type Default Description
code string (required) Country ISO code (alpha-2 or alpha-3).

ReturnsCountry | undefined. The matching country, or undefined when code does not resolve.

Examples

findCountryByIso('BF');   // → { name: 'Burkina Faso', iso2: 'BF', iso3: 'BFA', ... }
findCountryByIso('BFA');  // → { name: 'Burkina Faso', ... }
findCountryByIso('cL');   // → { name: 'Chile', ... } — case-insensitive
findCountryByName(name)

Find a country by short or official name. Case-insensitive.

Parameters

Option Type Default Description
name string (required) Country name (Country.name or Country.officialName).

ReturnsCountry | undefined. The matching country, or undefined when name does not resolve.

Examples

findCountryByName('Costa Rica');                              // → { name: 'Costa Rica', ... }
findCountryByName('The Republic of Costa Rica');              // same — official form
findCountryByName('The Territory of Cocos (Keeling) Islands'); // → official form match
getCapitals()

All country capitals, sorted by country name ascending.

ReturnsReadonlyArray<Capital>. Frozen — do not mutate.

Examples

const capitals = getCapitals();
capitals.length;                  // → number of countries
capitals.find(c => c.name === 'Tokyo')?.country?.iso2;  // → 'JP'
getCountries()

All countries, sorted by country name ascending.

ReturnsReadonlyArray<Country>. Frozen — do not mutate.

Examples

const countries = getCountries();
countries.length;                                                   // → ~250
countries.filter(c => c.timezones.length > 1).length;               // multi-timezone countries
countries.find(c => c.iso2 === 'US')?.officialName;                 // → 'The United States of America'
getCountryIso2CodeByIso3(iso3)

Get the ISO 3166-1 alpha-2 code paired with an alpha-3 code. Case-insensitive.

Parameters

Option Type Default Description
iso3 string (required) Alpha-3 code.

Returnsstring | undefined. The paired alpha-2 code, or undefined when iso3 is unknown.

Examples

getCountryIso2CodeByIso3('THA');  // → 'TH'
getCountryIso2CodeByIso3('USA');  // → 'US'
getCountryIso2CodeByIso3('XXX');  // → undefined
getCountryIso2Codes()

All ISO 3166-1 alpha-2 codes, sorted ascending.

ReturnsReadonlyArray<string>. Frozen — do not mutate.

Examples

const codes = getCountryIso2Codes();
codes.length;        // → ~250
codes.includes('JP'); // → true
codes[0];            // → 'AD'
getCountryIso3CodeByIso2(iso2)

Get the ISO 3166-1 alpha-3 code paired with an alpha-2 code. Case-insensitive.

Parameters

Option Type Default Description
iso2 string (required) Alpha-2 code.

Returnsstring | undefined. The paired alpha-3 code, or undefined when iso2 is unknown.

Examples

getCountryIso3CodeByIso2('TH');  // → 'THA'
getCountryIso3CodeByIso2('US');  // → 'USA'
getCountryIso3CodeByIso2('XX');  // → undefined
getCountryIso3Codes()

All ISO 3166-1 alpha-3 codes, sorted ascending.

ReturnsReadonlyArray<string>. Frozen — do not mutate.

Examples

const codes = getCountryIso3Codes();
codes.length;         // → ~250
codes.includes('JPN'); // → true
codes[0];             // → 'AFG'
isValidCountryIso(code)

Validate an ISO 3166-1 alpha-2 or alpha-3 code. Case-sensitive — codes must be uppercase. The find* helpers on this page accept any case.

Parameters

Option Type Default Description
code string (required) ISO code, uppercase.

Returns{ valid: boolean; iso2: boolean; iso3: boolean }. valid is true when code resolves; iso2 / iso3 discriminates the form.

Examples

isValidCountryIso('JP');  // → { valid: true,  iso2: true,  iso3: false }
isValidCountryIso('JPN'); // → { valid: true,  iso2: false, iso3: true  }
isValidCountryIso('jp');  // → { valid: false, iso2: false, iso3: false } — lowercase rejected
isValidCountryIso('XX');  // → { valid: false, iso2: false, iso3: false }

Locations

findLocationsByCoordinates(coordinates)

Find locations within a bounding box. At least one latitude bound and one longitude bound must be set; missing bounds default to ±Infinity.

Parameters

Option Type Default Description
coordinates Coordinates (required) Bounding-box bounds. See the type for each field.

ReturnsReadonlyArray<Location>. Locations within the box, or [] when neither latitude bound or neither longitude bound is set.

Examples

findLocationsByCoordinates({ latitudeFrom: 0, longitudeFrom: 0 });
// → Location[] — north-east of the equator and the prime meridian

findLocationsByCoordinates({ latitudeFrom: -55, latitudeTo: 1, longitudeFrom: -8, longitudeTo: 5 });
// → Location[] inside the box

findLocationsByCoordinates({});                             // → []
findLocationsByCountryIso(code)

Find locations by country ISO 3166-1 alpha-2 or alpha-3 code. Case-insensitive.

Parameters

Option Type Default Description
code string (required) Country ISO code (alpha-2 or alpha-3).

ReturnsReadonlyArray<Location>. Locations in the country, or [] when code does not resolve.

Examples

findLocationsByCountryIso('JP');   // → Location[] — Japanese cities
findLocationsByCountryIso('JPN');  // same — alpha-3 works
findLocationsByCountryIso('XX');   // → []
findLocationsByCountryName(name, partialMatch?)

Find locations by country short or official name. Case-insensitive.

Parameters

Option Type Default Description
name string (required) Country name (Country.name or Country.officialName).
partialMatch? boolean false When true, matches names that contain name as a substring.

ReturnsReadonlyArray<Location>. Matching locations, or [] when nothing matches.

Examples

findLocationsByCountryName('Timor-Leste');                          // → Location[]
findLocationsByCountryName('The Democratic Republic of Timor-Leste'); // same — official form
findLocationsByCountryName('timor', true);                          // → Location[] — partial match
findLocationsByCountryName('timor', false);                         // → []
findLocationsByProvince(name, partialMatch?)

Find locations by province. Case-insensitive. Province data is not exhaustively verified — see Limitations.

Parameters

Option Type Default Description
name string (required) Province name. Pass '' to find locations with no province.
partialMatch? boolean false When true, matches provinces that contain name as a substring.

ReturnsReadonlyArray<Location>. Matching locations, or [] when nothing matches.

Examples

findLocationsByProvince('Tristan da Cunha');     // → Location[]
findLocationsByProvince('Damascus');             // → Location[]
findLocationsByProvince('tokel', true);          // → Location[] — partial: 'Tokelau'
findLocationsByState(name, partialMatch?)

Find locations by USPS state name or code (US only). Case-insensitive.

Parameters

Option Type Default Description
name string (required) USPS code or state field. Pass '' to find non-US locations.
partialMatch? boolean false When true, matches state fields that contain name as a substring.

ReturnsReadonlyArray<Location>. Matching locations, or [] when nothing matches.

Examples

findLocationsByState('NY');         // → Location[] — New York
findLocationsByState('ny');         // same — case-insensitive
findLocationsByState('x', true);    // → Location[] — partial: 'TX'
getLocations()

All locations, sorted by city name ascending.

ReturnsReadonlyArray<Location>. Frozen — do not mutate.

Examples

const locations = getLocations();
locations.length;                                       // → ~40,000
locations.filter(l => l.country.iso2 === 'JP').length;  // Japanese cities

States ANSI

findStateAnsiByFipsCode(code)

Find a US state by its FIPS State Code ANSI.

Parameters

Option Type Default Description
code string (required) FIPS code (length 2).

ReturnsStateAnsi | undefined. The matching state, or undefined when code is not a known FIPS code.

Examples

findStateAnsiByFipsCode('05');   // → { name: 'Arkansas', uspsCode: 'AR', gnisid: '00068085', ... }
findStateAnsiByFipsCode('99');   // → undefined
findStateAnsiByFipsCode('');     // → undefined — length 2 required
findStateAnsiByGnisid(id)

Find a US state by its GNISID (Geographic Names Information System Identifier).

Parameters

Option Type Default Description
id string (required) GNISID (8 digits).

ReturnsStateAnsi | undefined. The matching state, or undefined when id is unknown.

Examples

findStateAnsiByGnisid('00068085');  // → { name: 'Arkansas', ... }
findStateAnsiByGnisid('99999999');  // → undefined
findStateAnsiByName(name)

Find a US state by name. Case-insensitive.

Parameters

Option Type Default Description
name string (required) State name.

ReturnsStateAnsi | undefined. The matching state, or undefined when name does not resolve.

Examples

findStateAnsiByName('Arkansas');  // → { uspsCode: 'AR', fipsCode: '05', ... }
findStateAnsiByName('arkansas');  // same — case-insensitive
findStateAnsiByName('Atlantis');  // → undefined
findStateAnsiByUspsCode(code)

Find a US state by USPS code. Case-insensitive.

Parameters

Option Type Default Description
code string (required) USPS two-letter code.

ReturnsStateAnsi | undefined. The matching state, or undefined when code is not a known USPS code.

Examples

findStateAnsiByUspsCode('AR');   // → { name: 'Arkansas', fipsCode: '05', ... }
findStateAnsiByUspsCode('ar');   // same — case-insensitive
findStateAnsiByUspsCode('ZZ');   // → undefined
getStatesAnsi()

All US states (ANSI), sorted by name ascending.

ReturnsReadonlyArray<StateAnsi>. Frozen — do not mutate.

Examples

const states = getStatesAnsi();
states.length;                                  // → 56 (50 states + DC + territories)
states.find(s => s.uspsCode === 'CA')?.name;    // → 'California'

Timezones

findTimezoneByCapitalOfCountryIso(code)

IANA timezone for a country's capital, by ISO 3166-1 alpha-2 or alpha-3 code. Case-insensitive.

Parameters

Option Type Default Description
code string (required) Country ISO code (alpha-2 or alpha-3).

Returnsstring | undefined. The IANA timezone of the country's capital, or undefined when code does not resolve.

Examples

findTimezoneByCapitalOfCountryIso('JP');   // → 'Asia/Tokyo'
findTimezoneByCapitalOfCountryIso('FRA');  // → 'Europe/Paris'
findTimezoneByCapitalOfCountryIso('XX');   // → undefined
findTimezoneByCapitalOfCountryName(name)

IANA timezone for a country's capital, by country short or official name. Case-insensitive.

Parameters

Option Type Default Description
name string (required) Country name (Country.name or Country.officialName).

Returnsstring | undefined. The IANA timezone of the country's capital, or undefined when name does not resolve.

Examples

findTimezoneByCapitalOfCountryName('Japan');                    // → 'Asia/Tokyo'
findTimezoneByCapitalOfCountryName('The French Republic');      // → 'Europe/Paris'
findTimezoneByCapitalOfCountryName('Atlantis');                 // → undefined
findTimezoneByCityName(name)

IANA timezone for a city, by name (UTF-8 or ASCII). Case-insensitive.

Parameters

Option Type Default Description
name string (required) City name.

Returnsstring | undefined. The IANA timezone of the matching city, or undefined when name is empty or does not resolve.

Examples

findTimezoneByCityName('Tokyo');     // → 'Asia/Tokyo'
findTimezoneByCityName('Göteborg');  // → 'Europe/Stockholm'
findTimezoneByCityName('Goteborg');  // same — ASCII transliteration works too
findTimezoneByCityName('');          // → undefined
findTimezonesByCountryIso(code)

All IANA timezones for a country, by ISO 3166-1 alpha-2 or alpha-3 code. Case-insensitive.

Parameters

Option Type Default Description
code string (required) Country ISO code (alpha-2 or alpha-3).

ReturnsReadonlyArray<string>. The country's timezones, or [] when code does not resolve. Frozen — do not mutate.

Examples

findTimezonesByCountryIso('US');   // → ['America/Adak', 'America/Anchorage', ...]
findTimezonesByCountryIso('JPN');  // → ['Asia/Tokyo']
findTimezonesByCountryIso('XX');   // → []
findTimezonesByCountryName(name)

All IANA timezones for a country, by short or official name. Case-insensitive.

Parameters

Option Type Default Description
name string (required) Country name (Country.name or Country.officialName).

ReturnsReadonlyArray<string>. The country's timezones, or [] when name does not resolve. Frozen — do not mutate.

Examples

findTimezonesByCountryName('United States of America');         // → ['America/Adak', ...]
findTimezonesByCountryName('The United States of America');     // same — official form
findTimezonesByCountryName('Atlantis');                          // → []
getTimezones()

All IANA timezones (the subset returned by Intl.supportedValuesOf('timeZone') at data-build time), sorted ascending.

ReturnsReadonlyArray<string>. Frozen — do not mutate.

Examples

const timezones = getTimezones();
timezones.length;                       // → ~430
timezones.includes('Asia/Tokyo');       // → true
timezones[0];                           // → 'Africa/Abidjan'

Subpath exports

The main entry @coroboros/location-timezone bundles every domain. For finer-grained tree-shaking, import only the domain you need:

import { findStateAnsiByUspsCode } from '@coroboros/location-timezone/states-ansi';  // ~5 kB
import { findCountryByIso } from '@coroboros/location-timezone/countries';            // ~85 kB
import { findTimezoneByCityName } from '@coroboros/location-timezone/timezones';      // ~870 kB
import { findLocationsByCountryIso } from '@coroboros/location-timezone/locations';   // ~860 kB

Sizes include the chunked dependencies each subpath transitively pulls. The merged default object is only exposed on the main entry; subpaths expose named exports only.

Limitations

  • Province data is unreliablefindLocationsByProvince works on the field as-is but coverage and naming vary by country. Treat as best-effort.
  • isValidCountryIso is case-sensitive — pass uppercase. The find* helpers accept any case.
  • Non-ISO codes — Northern Cyprus (XC/CYN), Kosovo (XK/KOS), and Somaliland (XS/SOL) use synthesized codes outside ISO 3166-1.
  • Timezone set is snapshot — IANA timezones are captured once when the data is rebuilt; the runtime does not re-query Intl. Rebuild and republish on tz-database changes.
  • No reverse geocodingfindLocationsByCoordinates filters a bounding box; it does not return the nearest city.

Compared to alternatives

Feature i18n-iso-countries countries-list geo-tz city-timezones @coroboros/location-timezone
Country names with UN + CIA official forms no no no no yes
ISO 3166-1 alpha-2 / alpha-3 codes yes yes no yes yes
Capital data with coordinates + IANA timezone no no (name only) no no yes
US state codes — ANSI FIPS + USPS no no no USPS only yes
City data with coordinates no no no ~7,300 ~40,000
Timezone lookup by city name no no no (lat/lng only) yes (O(n) scan) yes (O(1) Map)
Cross-references resolved across domains no no n/a no yes
Runtime dependencies 1 0 4 0 1 (zipson)

The gap is single-package consolidation across all five domains. Country-only packages (i18n-iso-countries, countries-list) cover ISO codes and names, nothing else. geo-tz and tz-lookup solve a different input model: lat/lng polygon → timezone, useful when you only know coordinates. city-timezones is the closest peer in shape, resolving country and timezone from a city name. It carries ~7,300 cities with no capitals or state-FIPS codes, and runs every lookup through Array.filter. @coroboros/location-timezone carries all five domains: countries, capitals, ~40,000 cities, US states ANSI, IANA timezones. The library builds Map and Set indexes once at module load. Cross-references resolve at parse time, so findCapitalOfCountryIso('JP').country returns the same object as findCountryByIso('JP').

Contributing

Bug reports and PRs welcome.

  • Open an issue before submitting non-trivial PRs.
  • Commits follow Conventional Commits.
  • Run pnpm lint && pnpm typecheck && pnpm test before pushing.
  • Target the main branch.

License

MIT

About

Capital, country, city, ANSI state, and IANA timezone lookups for Node.js.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors