An open API service indexing awesome lists of open source software.

https://github.com/dr5hn/countrystatecity

Official Country State City - NPM Packages
https://github.com/dr5hn/countrystatecity

cities city countries country nodejs npm package state states

Last synced: 8 months ago
JSON representation

Official Country State City - NPM Packages

Awesome Lists containing this project

README

          

# @countrystatecity/* Package Ecosystem

[![CI](https://github.com/dr5hn/countrystatecity/workflows/CI/badge.svg)](https://github.com/dr5hn/countrystatecity/actions/workflows/ci.yml)
[![Data Update](https://github.com/dr5hn/countrystatecity/workflows/Update%20Data/badge.svg)](https://github.com/dr5hn/countrystatecity/actions/workflows/update-data.yml)

Official package ecosystem for countries, states, cities, and geographic data with iOS/Safari support and minimal bundle sizes.

## ๐Ÿ“ฆ Packages

### @countrystatecity/countries [![npm](https://img.shields.io/npm/v/@countrystatecity/countries)](https://www.npmjs.com/package/@countrystatecity/countries)

Complete countries, states, and cities database with lazy loading and iOS compatibility.

- **Location:** [`packages/countries`](./packages/countries)
- **Documentation:** [README](./packages/countries/README.md)
- **Bundle Size:** <10KB initial load
- **Data:** 250+ countries, 5,000+ states, 150,000+ cities
- **Environment:** ๐Ÿ–ฅ๏ธ **Server-side only** (Node.js, Next.js API routes, Express, etc.)
- **Status:** โœ… Implemented

```bash
npm install @countrystatecity/countries
```

> **โš ๏ธ Server-Side Only**: This package requires Node.js file system access. For browser/frontend use, see [@countrystatecity/countries-browser](#countrystatecitycountries-browser) (coming soon).

### @countrystatecity/timezones [![npm](https://img.shields.io/npm/v/@countrystatecity/timezones)](https://www.npmjs.com/package/@countrystatecity/timezones)

Comprehensive timezone data with conversion utilities and iOS compatibility.

- **Location:** [`packages/timezones`](./packages/timezones)
- **Documentation:** [README](./packages/timezones/README.md)
- **Bundle Size:** <20KB initial load
- **Data:** 392 IANA timezones, 223 countries, 131 abbreviations
- **Environment:** ๐Ÿ–ฅ๏ธ **Server-side only** (Node.js, Next.js API routes, Express, etc.)
- **Status:** โœ… Implemented

```bash
npm install @countrystatecity/timezones
```

### @countrystatecity/countries-browser

Browser-compatible version of the countries package for frontend/client-side usage.

- **Location:** TBD
- **Documentation:** [Specification](./specs/4-countries-browser-package-spec.md)
- **Bundle Size:** ~75KB gzipped for typical use
- **Data:** Same as server package (250+ countries, 5,000+ states, 150,000+ cities)
- **Environment:** ๐ŸŒ **Browser/Frontend** (React, Vue, Svelte, Vite, etc.)
- **Status:** ๐Ÿ“‹ Planned (see [Issue #17](https://github.com/dr5hn/countrystatecity/issues/17))

This package will provide fetch-based data loading for browser environments with the same API as the server package.

## ๐Ÿš€ Quick Start

> **๐Ÿ’ก Choose the right package for your environment:**
> - **Server-side** (Node.js, Next.js API routes, Express): Use `@countrystatecity/countries`
> - **Browser/Frontend** (React, Vue, Svelte, Vite): Use `@countrystatecity/countries-browser` (coming soon) or create API endpoints

### Countries, States, and Cities (Server-Side)

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

// Get all countries (lightweight - ~5KB)
const countries = await getCountries();

// Get states for a country
const states = await getStatesOfCountry('US');

// Get cities in a state
const cities = await getCitiesOfState('US', 'CA');
```

### Timezones

```typescript
import { getTimezones, getTimezonesByCountry, convertTime } from '@countrystatecity/timezones';

// Get all timezones
const timezones = await getTimezones();

// Get timezones for a country
const usTimezones = await getTimezonesByCountry('US');

// Convert time between timezones
const converted = await convertTime(
'2025-10-18 14:00',
'America/New_York',
'Asia/Tokyo'
);
```

## โœจ Key Features

- ๐Ÿ“ฑ **iOS Compatible**: No stack overflow errors on Safari/iOS browsers
- ๐Ÿš€ **Minimal Bundle**: <10KB initial load with lazy loading
- ๐Ÿ”„ **Dynamic Loading**: Uses dynamic imports for code-splitting
- ๐ŸŒ **Full Data**: Countries, states, cities with translations
- โฐ **Timezone Support**: Comprehensive timezone information
- ๐Ÿ“ **TypeScript**: Full type definitions included
- ๐Ÿ”ง **Tree-Shakeable**: Only bundle what you use

## ๐ŸŽฏ Why This Ecosystem?

### The Problem

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

- ๐Ÿ”ด 8MB bundle size (includes ALL data upfront)
- ๐Ÿ”ด iOS Safari crashes with stack overflow errors
- ๐Ÿ”ด Unmaintained for 2+ years
- ๐Ÿ”ด Static imports force entire bundle inclusion

### Our Solution

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

### Bundle Size Comparison

| Action | @countrystatecity/countries | country-state-city |
|--------|----------------------------|-------------------|
| Install & import | 5KB | 8MB |
| Load countries | +2KB | - |
| Load US states | +30KB | - |
| Load CA cities | +15KB | - |
| **Total for typical use** | **~50KB** | **8MB** |

**160x smaller bundle size!**

## ๐Ÿ“Š Package Comparison

### Server vs Browser Packages

| Feature | @countrystatecity/countries | @countrystatecity/countries-browser |
|---------|----------------------------|-------------------------------------|
| **Environment** | Node.js, Bun, Deno | Browser, Frontend |
| **Data Loading** | File system (`fs`) | Fetch API |
| **Dependencies** | Node.js built-ins | Zero |
| **Initial Bundle** | ~15KB | ~15KB + 130KB countries data |
| **Lazy Loading** | โœ… Via file system | โœ… Via HTTP requests |
| **TypeScript** | โœ… | โœ… |
| **Same API** | โœ… | โœ… |
| **Use Cases** | Next.js API routes, Express, serverless functions | React, Vue, Svelte, vanilla JS |
| **iOS Compatible** | โœ… | โœ… |
| **Caching** | OS file cache | HTTP cache + memory |
| **Status** | โœ… Available now | ๐Ÿ“‹ Planned |

### When to Use Each Package

**Use `@countrystatecity/countries` (Server) 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

**Use `@countrystatecity/countries-browser` (Browser) when:**
- โœ… Building client-side React/Vue/Svelte apps
- โœ… Using Vite for frontend development
- โœ… Need to load data in the browser directly
- โœ… Building single-page applications (SPAs)
- โœ… Running in browser environments only

**Current Workaround (until browser package is ready):**
Create API endpoints using the server package, then fetch from your frontend:

```typescript
// pages/api/countries.ts (Next.js API route)
import { getCountries } from '@countrystatecity/countries';

export default async function handler(req, res) {
const countries = await getCountries();
res.json(countries);
}

// components/CountrySelector.tsx (Frontend)
const countries = await fetch('/api/countries').then(r => r.json());
```

See [Vite Deployment Guide](./docs/VITE_DEPLOYMENT.md) for detailed patterns.

## ๐Ÿ—๏ธ Monorepo Structure

```
countrystatecity/
โ”œโ”€โ”€ .github/
โ”‚ โ””โ”€โ”€ workflows/ # CI/CD workflows
โ”‚ โ”œโ”€โ”€ ci.yml # Continuous Integration
โ”‚ โ”œโ”€โ”€ update-data.yml # Automated data updates
โ”‚ โ””โ”€โ”€ publish.yml # NPM publishing
โ”œโ”€โ”€ packages/
โ”‚ โ””โ”€โ”€ countries/ # @countrystatecity/countries package
โ”œโ”€โ”€ specs/ # Technical specifications
โ”œโ”€โ”€ package.json # Root package configuration
โ””โ”€โ”€ pnpm-workspace.yaml # Workspace configuration
```

## ๐Ÿ”„ CI/CD & Automation

### Continuous Integration
Every push and PR automatically:
- โœ… Runs type checking
- โœ… Executes 42 comprehensive tests
- โœ… Builds all packages
- โœ… Validates bundle sizes
- โœ… Tests iOS/Safari compatibility

### Automated Data Updates
Weekly automated updates (Sundays at 00:00 UTC):
- ๐Ÿ“ฅ Downloads latest data from [source repository](https://github.com/dr5hn/countries-states-cities-database)
- ๐Ÿ”„ Transforms into optimized split structure
- ๐Ÿงช Runs full test suite
- ๐Ÿ“ Creates PR for review if changes detected

**Manual trigger:** Go to [Actions](https://github.com/dr5hn/countrystatecity/actions/workflows/update-data.yml) โ†’ Run workflow

### 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

See [Workflow Documentation](./.github/workflows/README.md) for details.

## ๐Ÿ› ๏ธ Development

### Prerequisites

- Node.js >= 18.0.0
- pnpm >= 8.0.0

### Setup

```bash
# Install dependencies
pnpm install

# Build all packages
pnpm build

# Run tests
pnpm test

# Run tests in watch mode
cd packages/countries && pnpm test:watch
```

### Commands

```bash
# Build all packages
pnpm build

# Test all packages
pnpm test

# Clean build artifacts
pnpm clean
```

## ๐Ÿ“Š Testing

All packages include comprehensive tests:

- โœ… Unit tests
- โœ… Integration tests
- โœ… iOS/Safari compatibility tests

Current coverage: 42 tests passing

## ๐Ÿ“– Documentation

- [Monorepo Plan](./specs/1-monorepo-plan.md)
- [@countrystatecity/countries Spec](./specs/2-world-countries-npm-package-spec.md)
- [Package Ecosystem Spec](./specs/3-world-package-ecosystem-spec.md)

## ๐Ÿค Contributing

Contributions are welcome! Please:

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Submit a pull request

**For data-related issues** (incorrect country names, missing cities, wrong coordinates, etc.), please report them to the [Countries States Cities Database](https://github.com/dr5hn/countries-states-cities-database/issues) repository, which is the source of data for this package.

## ๐Ÿ“„ License

[ODbL-1.0](./LICENSE) ยฉ [dr5hn](https://github.com/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](https://github.com/dr5hn/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**: Credit the original sources
- **Share-Alike**: Distribute adaptations under the same license
- **Keep Open**: Don't use technical restrictions

## ๐Ÿ”— Links

- [GitHub Repository](https://github.com/dr5hn/countrystatecity)
- [Issues](https://github.com/dr5hn/countrystatecity/issues)
- [NPM Organization](https://www.npmjs.com/org/countrystatecity)