If you've ever built a registration form, checkout page, or any location-aware app, you've probably needed a list of countries, states, and cities.
Most developers either hardcode it (bad idea — data goes stale) or spend hours finding a reliable free source.
Here's the cleanest solution I've found — and it works in both JavaScript and Python.
The API
Locara provides a free REST API with 250+ countries, 5,300+ states, and 154,000+ cities. The structure is cleanly nested:
/countries
/countries/US/states
/countries/US/states/CA/cities
JavaScript example
Install the SDK:
npm install locara-js
Fetch countries, states, and cities:
import { LocaraClient } from "locara-js";
const client = new LocaraClient({ apiKey: "loc_live_xxxx" });
// Get all countries
const countries = await client.countries.list({ limit: 250 });
// Get states for a country
const states = await client.states.list("US");
// Get cities for a state
const cities = await client.cities.list("US", "CA");
console.log(countries.data[0].name); // "Afghanistan"
console.log(states.data[0].name); // "Alabama"
console.log(cities.data[0].name); // "Los Angeles"
Python example
Install the SDK:
pip install locara
Fetch the same data:
from locara import LocaraClient
client = LocaraClient(api_key="loc_live_xxxx")
# Get all countries
countries = client.countries.list(limit=250)
# Get states for India
states = client.countries.states("IN").list(limit=50)
# Get cities in Maharashtra
cities = client.countries.states("IN").cities("MH").list(limit=100)
for city in cities.data:
print(city.name)
Building a React dropdown
Here's a complete cascading dropdown component:
import { useState, useEffect } from "react";
import { LocaraClient } from "locara-js";
const client = new LocaraClient({ apiKey: "loc_live_xxxx" });
export function LocationDropdown() {
const [countries, setCountries] = useState([]);
const [states, setStates] = useState([]);
const [cities, setCities] = useState([]);
const [selectedCountry, setSelectedCountry] = useState("");
const [selectedState, setSelectedState] = useState("");
useEffect(() => {
client.countries.list({ limit: 250 }).then(r => setCountries(r.data));
}, []);
useEffect(() => {
if (!selectedCountry) return;
client.states.list(selectedCountry).then(r => setStates(r.data));
}, [selectedCountry]);
useEffect(() => {
if (!selectedState) return;
client.cities.list(selectedCountry, selectedState).then(r => setCities(r.data));
}, [selectedState]);
return (
<div>
<select onChange={e => setSelectedCountry(e.target.value)}>
<option value="">Select Country</option>
{countries.map(c => (
<option key={c.isoCode} value={c.isoCode}>{c.name}</option>
))}
</select>
<select onChange={e => setSelectedState(e.target.value)} disabled={!selectedCountry}>
<option value="">Select State</option>
{states.map(s => (
<option key={s.isoCode} value={s.isoCode}>{s.name}</option>
))}
</select>
<select disabled={!selectedState}>
<option value="">Select City</option>
{cities.map(c => (
<option key={c.id} value={c.id}>{c.name}</option>
))}
</select>
</div>
);
}
Free tier
Locara has a free tier with 3,000 requests/month — no credit card required. Enough for development and small projects.
Sign up at locara.online
Have questions about building location-aware apps? Drop them in the comments.
Top comments (0)