dr5hn/countries-states-cities-database: A 153,765-City Dataset in Twelve Formats
🌍 Discover our global repository of countries, states, and cities! 🏙️ Get comprehensive data in JSON, SQL, PSQL, SQLSERVER, MONGODB, SQLITE, XML, YAML, and CSV formats. Access ISO2, ISO3 codes, country code, capital, native language, timezones (for countries), and more. #countries #states #cities
At a glance
- What is it?
- The repository publishes countries, states, cities and postcodes as JSON, SQL, PSQL, SQL Server, MongoDB, SQLite, XML, YAML and CSV exports, with a managed REST API and a browser export tool alongside it. The data is free under ODbL-1.0, but attribution is a licence condition, not a courtesy.
- Who is it for?
- Adopt this repository if you need a broad, format-flexible reference table for country, state and city pickers, and if you can carry the ODbL attribution requirement into your product. Do not adopt it if you need authoritative postal addressing per country, if your compliance team cannot accept a share-alike database licence, or if you cannot tolerate a dataset that is refreshed on a release cadence rather than continuously.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- dr5hn/countries-states-cities-database10,013 ★ · +172
| Repository | 2026-09-22 | 2026-11-14 |
|---|---|---|
| dr5hn/countries-states-cities-database | 9.8k | 10k |
172 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What the dataset actually contains, and who reaches for it
The README lists totals directly: 6 regions, 22 sub regions, 250 countries, 5,299 states or regions or municipalities, 153,765 cities or towns or districts, 725,993 postcodes across 116 countries, and 427 timezones with what it describes as 100 percent IANA coverage. The last updated date printed in the README is November 02, 2026, the same day as the v5.2.0 release.
The audience is narrow and practical. Anyone building an address form needs a country list, then a state list that depends on the chosen country, then a city list that depends on the state. The same shape appears in shipping calculators, tax jurisdiction tables, CRM dropdowns and analytics normalisation. Doing this by hand means maintaining thousands of rows that change when a country renames a province or a city splits.
What the dataset is not is an addressing authority. Postcodes cover 116 countries, so more than half the country rows have no postcode data behind them. If your requirement is validated delivery addresses, this repository is a starting vocabulary, not a verification service.
How the exports are organised and how a lookup flows
The repository is a data publication, not a runtime service. The top level holds one directory per output family: csv/, json/, psql/, sql/, sqlite/, sqlserver/, xml/, yml/, parquet/, duckdb/, geojson/, toon/ and prisma/. Each release attaches the same data as gzipped assets, so the directory tree and the release assets are two views of one build.
The hierarchy is three levels deep plus postcodes. A country row carries ISO2 and ISO3 codes and a numeric country code, a capital, a region and sub region, and timezones. A state row points at a country. A city row points at a state. Postcodes are a separate dataset covering only some countries. That means a cascading form is three lookups.
Two files at the top level explain modelling decisions rather than data. Going by their names, TYPE_FIELD.md and MULTI_LEVEL_TERRITORIES.md cover how the data is modelled, including territories that may not fit a three-level pyramid. If your product assumes exactly three levels, read MULTI_LEVEL_TERRITORIES.md before you write the schema.
Installing and running a first lookup
There is no install step for the data itself. You download a release asset, or you pull the directory you need. The README gives this example for the gzipped city export, which downloads the latest release asset and decompresses it in place.
curl -LO https://github.com/dr5hn/countries-states-cities-database/releases/latest/download/json-cities.json.gz
gunzip json-cities.json.gzAfter that you have json-cities.json in the working directory. The README's own description of the file set is that every format ships as a .gz asset on each GitHub Release, so the same pattern applies to the CSV and SQL variants by changing the asset name.
If you would rather not manage files, the README documents a managed REST API. The curl example it gives queries the cities of a state, and requires an API key in the X-CSCAPI-KEY header.
curl https://api.countrystatecity.in/v1/countries/IN/states/MH/cities \
-H "X-CSCAPI-KEY: $YOUR_API_KEY"For Python, the README points at an official client. It installs from PyPI and reads the key from an environment variable, then exposes a context manager with methods such as get_states_of_country.
pip install countrystatecity-api
export CSC_API_KEY="YOUR_API_KEY"from countrystatecity import CountryStateCity
with CountryStateCity() as client:
states = client.get_states_of_country("IN")
print([state["name"] for state in states[:3]])The README example only uses the state name field, so check the OpenAPI spec repository it links before you build a parser around the response. The same README also notes that the API has a free tier for prototyping and paid tiers for production, which is the line where an offline export and a hosted service stop being interchangeable.
Where the offline exports stop being enough
The first limitation is freshness. Data arrives in exports tied to releases, and the release history shows releases landing within days of each other: v5.1.0 on 2026-10-31, then v5.1.0-export.1 and v5.2.0 on 2026-11-02. The README's own last updated line is November 02, 2026. If your product needs a change reflected the day it happens, an export cannot do that; the README recommends the managed REST API for production.
The second limitation is postcode coverage. 725,993 postcodes across 116 countries means the postcode files are useful for some markets and empty for others. Treat the postcode dataset as partial until you have checked your own target countries in the file.
The third is structural. Countries that do not map cleanly onto country, state, city may need special handling; the repository carries MULTI_LEVEL_TERRITORIES.md, which by its name addresses them.
The fourth is licensing rather than data. ODbL-1.0 is a database licence with an attribution requirement, and the README states that plainly. Attribution is a condition of use, and the share-alike terms of an open database licence can affect how you redistribute a derived database. That is a question for your own legal review, not something the repository can settle for you.
How it compares with GeoNames and with the managed API tier
GeoNames is the closest widely used alternative and takes a different approach. It is a gazetteer: it records places with coordinates, feature classes and alternate names, and it lets you query by proximity or bounding box. This repository is an administrative hierarchy. It gives you the parent chain from country to state to city and the codes that go with it. If you need to answer which cities fall inside a radius, GeoNames is built for that. If you need to populate a three-level address form, the hierarchy here is already shaped for the job and GeoNames would require you to reconstruct the parent chain yourself.
The second comparison is internal. The README recommends the managed REST API and the export tool as the production path, and describes the API as actively maintained and billed for sustainability. The offline exports are versioned snapshots. The practical difference is operational: an export is a file you version, test and redeploy, while the API is a dependency with a key, a rate tier and an uptime you do not control. Neither is wrong, but mixing them without deciding which is the source of truth leads to two datasets that drift apart.
Maintenance cadence, licence obligations and what to verify
The repository is not archived, and the last push was on 2026-11-02. The release history shows releases as recent as 2026-11-02, so the dataset is being rebuilt rather than frozen. A downloaded export is a snapshot, so plan for the upgrade as a data migration you test, not a file swap.
The licence is ODbL-1.0. The README states attribution is required and links the LICENSE file. For an application that displays country and city names, the practical obligation is a visible credit, but the share-alike provisions apply to derived databases, and whether your particular use creates one is a legal question. Read the LICENSE file and the ODbL text rather than relying on a summary.
If you want the data without maintaining it, the README points at the API, the export tool at export.countrystatecity.in, and the OpenAPI spec at the csc-swagger repository. Those are the three places to look before you decide to vendor a snapshot.
Editorial conclusion
Adopt this repository if you need a broad, format-flexible reference table for country, state and city pickers, and if you can carry the ODbL attribution requirement into your product. Do not adopt it if you need authoritative postal addressing per country, if your compliance team cannot accept a share-alike database licence, or if you cannot tolerate a dataset that is refreshed on a release cadence rather than continuously. Before committing, download the gzipped export for your target format from the latest GitHub Release, check that the country and state rows you depend on are present in that specific file, and confirm whether the postcode coverage you need falls inside the 116 countries the README reports. The repository is not archived and the last push was on 2026-11-02, so the export cadence is the thing to measure against your own update window.
Frequently asked questions
Can I get a free list of countries, states and cities from dr5hn/countries-states-cities-database?
Yes. The repository publishes the full dataset as gzipped assets on each GitHub Release and as directories in the repository itself, covering 250 countries, 5,299 states and 153,765 cities. The licence is ODbL-1.0, and the README states that attribution is required.
Does dr5hn/countries-states-cities-database cover every city in the world?
The README reports 153,765 cities, towns and districts, plus 725,993 postcodes across 116 countries. It does not claim complete global coverage, and the postcode files in particular cover only those 116 countries.
Is the country state city API free to use?
The README describes a free tier for prototyping and paid tiers for production, with plans compared on the project's pricing page. The offline exports in the repository are separate from the API and are published under ODbL-1.0.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dr5hn-countries-states-cities-database)Star history chart for your README
[](https://hysenlabs.com/projects/dr5hn-countries-states-cities-database)Was this useful?