@countrystatecity/countries

中文文档
3.0.1发布于 2026/11/03ODbL-1.0TypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 14.3万

Official countries, states, and cities database with iOS/Safari support and minimal bundle size

原始使用文档
文档目录21 节
  1. Upgrading to 3.0.0
  2. Earlier migration: 2.0.0
  3. ✨ Features
  4. Why This Package?
  5. 📦 Installation
  6. 🚀 Quick Start
  7. Local package or live API?
  8. 📖 API Reference
  9. Core Functions
  10. Utility Functions
  11. 🔧 TypeScript Types
  12. 📊 Bundle Size
  13. 🧪 Testing
  14. 🔄 CI/CD & Automation
  15. Continuous Integration
  16. Automated Publishing
  17. 📄 License
  18. 🤝 Contributing
  19. 📦 Package Ecosystem
  20. Environment Guide
  21. 🔗 Links

@countrystatecity/countries

npm CI npm downloads npm downloads

Official countries, states, and cities database with iOS/Safari support and minimal bundle size.

Environment: 🖥️ Server-side only (Node.js, Next.js API routes, Express, etc.)

Upgrading to 3.0.0

This version uses v5.2.0-export.1. Review the upstream v5 migration notes before updating stored IDs: some records were retired or had their identities repaired. City state links can now be null. Country-wide city loaders include these records. Preserve the supplied NOTICE-*.txt files with redistributed data. See the package migration guide.

Earlier migration: 2.0.0

Data now comes from upstream v4.0-export.50. The v3.2 → v4.0 transition removed 4,486 city ids (duplicates, US counties moved to a separate counties dataset, and non-places), reassigned 7,527 cities to different states, and added 27 states while retiring 6. Stored ids and per-state results can change; US counties are no longer returned as cities. Later export corrections are included in this snapshot.

Before upgrading stored city/state ids, use removed_ids_v3.2_to_v4.0.csv attached to the upstream v4.0 release. It identifies merged ids and their survivors, counties moved to new ids, and retired states and their successors. Match the record, outcome, and new_table columns before using new_id; a county id is not a city id. Refresh stored state associations against this snapshot.

City type uses standard terms (municipality, city, town, village, locality, section) for migrated countries; other countries can retain earlier terms such as adm1/adm2. This package intentionally projects a subset of upstream fields: type_local, county_id, level, and parent_id are omitted from city/state records, and no counties dataset is shipped. City translations remain empty objects; country translations are included. Use upstream exports when you need official local terms, county links, or hierarchy traversal.

✨ Features

  • 🌍 Complete Data: 250+ countries, 5,000+ states, 150,000+ cities
  • 📱 iOS Compatible: No stack overflow errors on Safari/iOS browsers
  • 🚀 Minimal Bundle: <10KB initial load, lazy-load everything else
  • 🔄 Lazy Loading: Dynamic imports for optimal performance
  • 🌐 Translations: 18+ languages supported
  • ⏰ Timezone Data: Full timezone information per location
  • 📝 TypeScript: Full type definitions included
  • 🔧 Tree-Shakeable: Only bundle what you use

Why This Package?

The popular country-state-city package (162K weekly downloads) has critical issues:

  • 🔴 8MB bundle size (includes ALL data)
  • 🔴 iOS Safari crashes with stack overflow errors
  • 🔴 Unmaintained for 2+ years
  • 🔴 Static imports force entire bundle

This package solves each of those problems:

  • ✅ Minimal bundle (<10KB initial)
  • ✅ Dynamic imports & lazy loading
  • ✅ iOS/Safari compatible
  • ✅ Always updated from authoritative database
  • ✅ Tree-shakeable & code-splittable

📦 Installation

npm install @countrystatecity/countries
# or
yarn add @countrystatecity/countries
# or
pnpm add @countrystatecity/countries

⚠️ Server-Side Only: This package requires Node.js file system access and cannot be used in browser environments. For frontend use, install @countrystatecity/countries-browser instead — same API, works in React/Vue/Svelte/Vite.

🚀 Quick Start

import { getCountries, getStatesOfCountry, getCitiesOfState } from '@countrystatecity/countries';

// Get all countries (lightweight - ~5KB)
const countries = await getCountries();
console.log(countries[0]);
// { id: 1, name: "United States", iso2: "US", emoji: "🇺🇸", ... }

// Get all states in a country (~10-100KB depending on country)
const states = await getStatesOfCountry('US');
console.log(states[0]);
// { id: 1, name: "California", iso2: "CA", ... }

// Get all cities in a state (~5-200KB depending on state)
const cities = await getCitiesOfState('US', 'CA');
console.log(cities[0]);
// { id: 1, name: "Los Angeles", latitude: "34.05", ... }

Local package or live API?

This package ships a free, offline-capable snapshot of the data — that's still the right choice when the app must work offline, a periodic snapshot is enough, or you just need simple lookups/dropdowns.

The CountryStateCity API is worth adding alongside it when you need:

  • Freshness — data that updates without publishing a new package version.
  • Search — fuzzy, typo-tolerant, server-side search (csc.search.fuzzy(...)), not just exact-match local lookups.
  • Scale & support — configurable rate limits and support beyond a bundled snapshot.

Start free with 3,000 requests per month. Compare plans or get an API key.

npm install @countrystatecity/sdk
// Before
import { getCountries, getStatesOfCountry, getCitiesOfState } from '@countrystatecity/countries';

const countries = await getCountries();
const states = await getStatesOfCountry('US');
const cities = await getCitiesOfState('US', 'CA');
// After
import { createCSCClient } from '@countrystatecity/sdk';

const csc = createCSCClient({ apiKey: process.env.CSC_API_KEY! });

const { data: countries } = await csc.countries.list();
const { data: states } = await csc.states.list({ country: 'US' });
const { data: cities } = await csc.cities.list({ country: 'US', state: 'CA' });

See the full migration guide for error handling, retries, and more.

📖 API Reference

Core Functions

getCountries()

Get lightweight list of all countries (basic info only).

  • Returns: Promise<ICountry[]>
  • Bundle Impact: ~5KB

getCountryByCode(countryCode: string)

Get full country metadata including timezones and translations.

  • Parameters: countryCode - ISO2 code (e.g., 'US')
  • Returns: Promise<ICountryMeta | null>
  • Bundle Impact: ~5KB per country

getStatesOfCountry(countryCode: string)

Get all states/provinces for a country.

  • Parameters: countryCode - ISO2 code
  • Returns: Promise<IState[]>
  • Bundle Impact: ~10-100KB depending on country

getStateByCode(countryCode: string, stateCode: string)

Get specific state details.

  • Parameters: countryCode, stateCode
  • Returns: Promise<IState | null>

getCitiesOfState(countryCode: string, stateCode: string)

Get all cities in a specific state.

  • Parameters: countryCode, stateCode
  • Returns: Promise<ICity[]>
  • Bundle Impact: ~5-200KB depending on state

getAllCitiesOfCountry(countryCode: string)

Get ALL cities in an entire country.

  • Warning: Large data size, use sparingly
  • Returns: Promise<ICity[]>

getAllCitiesInWorld()

Get every city globally.

  • Warning: MASSIVE data (8MB+), rarely needed
  • Returns: Promise<ICity[]>

getRegions()

Get list of all regions (continents).

  • Returns: Promise<IRegion[]>
  • Bundle Impact: ~3KB

getSubregions()

Get list of all subregions.

  • Returns: Promise<ISubregion[]>
  • Bundle Impact: ~13KB

Utility Functions

isValidCountryCode(countryCode: string)

Check if country code exists.

  • Returns: Promise<boolean>

isValidStateCode(countryCode: string, stateCode: string)

Check if state code exists in a country.

  • Returns: Promise<boolean>

searchCitiesByName(countryCode: string, stateCode: string, searchTerm: string)

Search cities by partial name match.

  • Returns: Promise<ICity[]>

getCountryNameByCode(countryCode: string)

Get country name from code.

  • Returns: Promise<string | null>

getStateNameByCode(countryCode: string, stateCode: string)

Get state name from code.

  • Returns: Promise<string | null>

getTimezoneForCity(countryCode: string, stateCode: string, cityName: string)

Get timezone for specific city.

  • Returns: Promise<string | null>

getCountryTimezones(countryCode: string)

Get all timezones for a country.

  • Returns: Promise<string[]>

getSubregionsOfRegion(regionId: number)

Get all subregions belonging to a region.

  • Returns: Promise<ISubregion[]>

getCountriesByRegion(region: string | number)

Get all countries in a region, by name (case-insensitive, e.g. 'Europe') or region ID.

  • Returns: Promise<ICountry[]>

getCountriesBySubregion(subregion: string | number)

Get all countries in a subregion, by name (case-insensitive, e.g. 'South America') or subregion ID.

  • Returns: Promise<ICountry[]>

🔧 TypeScript Types

import type { ICountry, ICountryMeta, IState, ICity, IRegion, ISubregion, ITimezone } from '@countrystatecity/countries';

📊 Bundle Size

Action@countrystatecity/countriescountry-state-city
Install & import5KB8MB
Load countries+2KB-
Load US states+30KB-
Load CA cities+15KB-
Total for typical use~50KB8MB

160x smaller bundle size!

🧪 Testing

# Run all tests
npm test

# Run iOS compatibility tests specifically
npm run test:ios

# Watch mode
npm run test:watch

All packages include comprehensive tests:

  • ✅ Unit tests
  • ✅ Integration tests
  • ✅ iOS/Safari compatibility tests

🔄 CI/CD & Automation

Continuous Integration

Every push and PR automatically:

  • ✅ Runs type checking
  • ✅ Executes comprehensive tests
  • ✅ Builds the package
  • ✅ Validates bundle sizes
  • ✅ Tests iOS/Safari compatibility

Automated Publishing

Automated publishing to NPM on version changes:

  • 🔍 Detects version bumps in package.json
  • 📦 Builds and tests before publishing
  • 🚀 Publishes to NPM registry
  • 🏷️ Creates GitHub release with changelog

📄 License

ODbL-1.0 © dr5hn

This package and its data are licensed under the Open Database License (ODbL) v1.0. The data is sourced from the Countries States Cities Database which is also licensed under ODbL-1.0.

You are free to share, create, and adapt this database as long as you attribute the original sources, distribute adaptations under the same license, and don't use technical restrictions to lock down the data.

🤝 Contributing

Contributions are welcome! Please open an issue or PR.

For data-related issues (incorrect country names, missing cities, wrong coordinates, etc.), please report them to the Countries States Cities Database repository, which is the source of data for this package.

📦 Package Ecosystem

This package is part of the @countrystatecity package ecosystem:

  • @countrystatecity/countries (This package) — Server-side countries, states, and cities database. Environment: Node.js, Next.js API routes, Express. Bundle: <10KB initial load.

  • @countrystatecity/countries-browser — Browser-native version with jsDelivr CDN and lazy loading. Environment: React, Vue, Svelte, Vite, any browser. Same API as this package — zero config, just import and use.

  • @countrystatecity/timezones — Comprehensive timezone data with conversion utilities. Environment: Server-side only. Bundle: <20KB initial load.

Environment Guide

Use this package (@countrystatecity/countries) when:

  • ✅ Building API endpoints or backends
  • ✅ Using Next.js App Router server components
  • ✅ Running in Node.js, serverless functions (Vercel, AWS Lambda)
  • ✅ You have file system access
  • ✅ Building command-line tools

For browser/frontend use:

Use @countrystatecity/countries-browser — same API, works directly in React, Vue, Svelte, Vite:

npm install @countrystatecity/countries-browser
import { getCountries, getStatesOfCountry, getCitiesOfState } from '@countrystatecity/countries-browser';

const countries = await getCountries();
const states = await getStatesOfCountry('US');
const cities = await getCitiesOfState('US', 'CA');

版本与发布记录

@countrystatecity/countries 共发布 13 个版本,首次发布于 2025/10/07;过去 12 个月发布了 8 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.0.1latest2026/11/037 天前
3.0.02026/10/2912 天前
2.0.02026/10/1328 天前
1.0.92026/08/083 个月前
1.0.82026/08/083 个月前
1.0.72026/06/114 个月前

关于 @countrystatecity/countries 的常见问题

@countrystatecity/countries 是什么?

Official countries, states, and cities database with iOS/Safari support and minimal bundle size

如何安装 @countrystatecity/countries?

在项目目录运行 npm install @countrystatecity/countries,或使用 pnpm add / yarn add / bun add。

@countrystatecity/countries 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@countrystatecity/countries 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@countrystatecity/countries 可以商用吗?

@countrystatecity/countries 使用 ODbL-1.0 许可。声明的许可为 ODbL-1.0,请阅读许可原文确认使用条件。以上为概括,不构成法律意见,请以许可原文为准。

@countrystatecity/countries 的下载量有多少?

根据 npm 官方下载统计,@countrystatecity/countries 在 2026/10/11 – 2026/11/09 这 30 天内被下载 142,712 次,日均约 4,757 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@countrystatecity/countries 还在维护吗?

最新版本 3.0.1 发布于 2026/11/03(7 天前);至今共发布 13 个版本,其中过去 12 个月发布了 8 个;首次发布于 2025/10/07。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。