Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
geodb-rs
Author: Holger Trahe | License: MIT (Code) / CC-BY-4.0 (Data)
Crates.io
PyPI
pub.dev (Flutter)
App Store
A high-performance, pure-Rust geographic database with countries, states/regions, cities, aliases, phone codes, currencies, timezones, and multi-platform support including WebAssembly, iOS, macOS, watchOS, and Android.
This repository is a Cargo workspace containing:
geodb-core— main geographic database library (published on crates.io) — docs: https://docs.rs/geodb-coregeodb-cli— command-line interface — docs: https://docs.rs/geodb-cligeodb-wasm— WebAssembly bindings + browser demo — docs: https://docs.rs/geodb-wasmgeodb-py— Python bindings (published on PyPI as "geodb-rs") — https://pypi.org/project/geodb-rs/geodb-ffi— FFI bindings for mobile platforms (iOS, macOS, watchOS, Android)geodb_flutter— Flutter plugin (published on pub.dev) — https://pub.dev/packages/geodb_flutter
Overview
geodb-core provides:
- 🚀 Fast loading from compressed JSON or binary cache
- 💾 Automatic caching based on dataset file and filters
- 🔎 Flexible lookups: ISO codes, names, aliases, phone codes
- 🌍 Countries, states/regions, cities, populations
- 🗺 Accurate metadata: region, subregion, currency
- 📞 Phone code search
- ⏱ Zero-copy internal model
- 🦀 Pure Rust — no unsafe
- 🕸 WASM support via
geodb-wasm - 📱 Mobile support via
geodb-ffi(iOS, macOS, watchOS, Android)
The dataset is adapted from https://github.com/dr5hn/countries-states-cities-database (licensed under CC-BY-4.0, attribution required).
Important: Data source and automatic downloading
geodb-core uses the upstream dataset from the dr5hn/countries-states-cities-database repository:
Automatic data download and caching:
- The published crate does NOT include data files (keeps package size under 1MB)
- On first load, the library automatically downloads the dataset from GitHub (~3.7MB)
- After download, a binary cache is generated for fast subsequent loads
- Download and cache generation happen only once per system
- Requires the
builderfeature (enabled by default) and internet connection for first load- Downloaded data and cache stored in
crates/geodb-core/data/directoryIf you update or replace the dataset, ensure it retains the same JSON structure. Please observe the CC-BY-4.0 license and attribution of the upstream project.
Installation
For Rust applications
[]
= "0.1"
Note: First load will download the dataset from GitHub (~3.7MB) and build the binary cache (requires internet connection). Subsequent loads will be instant using the cached binary.
For WebAssembly (browser/Node)
[]
= "0.1"
For Swift (iOS, macOS, watchOS)
Add the Swift Package via git URL:
// In Xcode: File → Add Package Dependencies
// URL: https://github.com/holg/geodb-rs
// Or in Package.swift:
dependencies: [
.package(url: "https://github.com/holg/geodb-rs", from: "1.0.0")
]
Then import and use:
import GeodbKit
let engine = try GeoDbEngine()
let stats = engine.stats()
print("Countries: \(stats.countries), States: \(stats.states), Cities: \(stats.cities)")
// Search
let results = engine.smartSearch(query: "Berlin")
for city in results {
print("\(city.name), \(city.state), \(city.country)")
}
// Find nearest cities
let nearest = engine.findNearest(lat: 52.52, lng: 13.405, count: 10)
For Flutter (iOS, Android, macOS)
# pubspec.yaml
dependencies:
geodb_flutter: ^0.1.8
import 'package:geodb_flutter/geodb_flutter.dart';
final geodb = GeodbFlutter();
await geodb.initialize();
final results = await geodb.smartSearch('Berlin');
final nearest = await geodb.findNearest(lat: 52.52, lng: 13.405, count: 10);
For Android (Kotlin - Native)
See the example app in GeoDB-App/android-app/. The app uses UniFFI-generated Kotlin bindings.
import uniffi.geodb_ffi.GeoDbEngine
val engine = GeoDbEngine()
val stats = engine.stats()
println("Countries: ${stats.countries}, States: ${stats.states}, Cities: ${stats.cities}")
// Search
val results = engine.smartSearch("Berlin")
results.forEach { city ->
println("${city.name}, ${city.state}, ${city.country}")
}
// Find nearest cities
val nearest = engine.findNearest(52.52, 13.405, 10u)
Quick Start
use *;
Loading & Caching
Default loading
Loads from:
geodb-core/data/countries+states+cities.json.gz
Creates automatic cache:
countries+states+cities.json.ALL.bin
let db = load?;
Load from a custom file
let db = load_from_path?;
Cache becomes:
worlddata.json.ALL.bin
Filtered loading (ISO2)
let db = load_filtered_by_iso2?;
Cache:
countries+states+cities.json.DE_US.bin
Cache rules:
<dataset_filename>.<filter>.bin
Usage Examples
List all countries
use *;
let db = load?;
for country in db.countries
Find by ISO code
if let Some = db.find_country_by_iso2
Country details
if let Some = db.find_country_by_iso2
States & cities
if let Some = db.find_country_by_iso2
Phone search
let countries = db.find_countries_by_phone_code;
Filter-based city search (CityQuery API)
Use the chainable query_cities() API to disambiguate cities with common names:
use *;
let db = load?;
// Find Springfield in Illinois, US (not the 30+ other Springfields!)
let results = db.query_cities
.filter_country
.filter_region
.filter_city
.collect;
assert_eq!;
let = &results;
println!;
// Output: Springfield - Illinois, US
// Find Lüdinghausen in NRW (accent-insensitive search)
let city = db.query_cities
.filter_country
.filter_region
.filter_city // works without umlaut too
.first;
// Count all Springfields worldwide
let count = db.query_cities
.filter_city
.count;
println!;
Filters support:
- Country: ISO2/ISO3 codes (
"US","DEU") or name substring ("Germany") - Region: State code (
"CA","NW") or name ("California","Nordrhein-Westfalen") - City: Name substring with accent-insensitive matching
WebAssembly (geodb-wasm)
Exports:
search_country_prefixsearch_countries_by_phonesearch_state_substringsearch_city_substringsmart_searchget_stats
To run locally:
Live demos:
- Search Demo: https://trahe.eu/geodb-rs.html
- Performance Benchmark: https://trahe.eu/geodb-bench.html
Command-line interface (geodb-cli)
The CLI is finished and available on crates.io. It provides quick access to the database for exploration, scripting, or data checks.
Install:
Commands:
Filter-based query (disambiguate cities):
# Find Springfield in Illinois, US (not the 30+ other Springfields!)
# Find Lüdinghausen in NRW, Germany
# List all cities in Bavaria
Docs.rs: https://docs.rs/geodb-cli
Python bindings (geodb-py)
- Package name on PyPI: geodb-rs https://pypi.org/project/geodb-rs/
- Module to import in Python:
geodb_rs - Built and published wheels for these targets:
- os: ubuntu-latest
target: x86_64
manylinux: auto
- os: ubuntu-latest
target: aarch64
manylinux: auto
- os: macos-13
target: x86_64
manylinux: ""
- os: macos-14
target: aarch64
manylinux: ""
- os: windows-latest
target: x64
manylinux: ""
Quick start:
= # tries bundled data first
# (countries, states, cities)
Flutter Plugin (geodb_flutter)
Cross-platform Flutter plugin with native Rust performance.
pub.dev
Installation
dependencies:
geodb_flutter: ^0.1.8
Platform Support
| Platform | Status | Architectures |
|---|---|---|
| iOS | Ready | arm64 device, arm64 simulator |
| macOS | Ready | arm64, x86_64 (Universal) |
| Android | Ready | arm64-v8a, armeabi-v7a, x86_64, x86 |
Quick Start
import 'package:geodb_flutter/geodb_flutter.dart';
final geodb = GeodbFlutter();
// Initialize (required first)
await geodb.initialize();
// Get stats
final stats = await geodb.getStats();
print('${stats.cities} cities in ${stats.countries} countries');
// Smart search
final results = await geodb.smartSearch('Berlin');
for (final city in results) {
print('${city.name}, ${city.country} (${city.iso2})');
}
// Find nearest cities
final nearest = await geodb.findNearest(lat: 52.52, lng: 13.405, count: 10);
// Search within radius
final nearby = await geodb.findInRadius(lat: 52.52, lng: 13.405, radiusKm: 50.0);
For a complete example, see GeoDB-Apps/geodb_city_autocomplete/ in the repository.
Mobile Apps (GeoDB-App)
The repository includes native apps for Apple and Android platforms:
App Store & Downloads
| Platform | Status | Link |
|---|---|---|
| iOS | Available | App Store |
| macOS | In Review | Coming soon |
| tvOS | In Review | Coming soon |
| watchOS | Available | Included with iOS app |
| TestFlight | Available | Join Beta |
iOS / macOS / watchOS / tvOS (Swift)
Located in GeoDB-App/GeoDB/ - a universal Xcode project supporting:
- iOS app - Available on App Store
- macOS app - In Apple Review
- tvOS app - In Apple Review
- watchOS app (including Apple Watch Ultra support with arm64_32)
Uses the GeodbKit Swift package via SPM.
Android (Kotlin)
Located in GeoDB-App/android-app/ - a Jetpack Compose app featuring:
- Text search for cities, states, countries
- Nearest city search by coordinates
- Radius search
- Interactive detail dialogs
Pre-built APKs available in releases/android/:
app-arm64-v8a-release.apk(15 MB) - Most modern Android phonesapp-armeabi-v7a-release.apk(14 MB) - Older 32-bit phonesapp-x86_64-release.apk(15 MB) - Emulatorsapp-universal-release.apk(40 MB) - All architectures
Workspace Layout
geodb-rs/
├── crates/
│ ├── geodb-core/ # Core Rust library
│ ├── geodb-cli/ # Command-line interface
│ ├── geodb-wasm/ # WebAssembly bindings
│ ├── geodb-py/ # Python bindings
│ └── geodb-ffi/ # FFI bindings (mobile)
├── GeoDB-App/
│ ├── GeoDB/ # Xcode project (macOS/iOS/watchOS)
│ ├── android-app/ # Android Kotlin app
│ ├── spm/ # Swift Package (GeodbKit)
│ │ ├── Package.swift
│ │ ├── GeodbFfi.xcframework/
│ │ └── Sources/
│ └── scripts/ # Build scripts
├── releases/
│ └── android/ # Pre-built APKs
├── Package.swift # Root SPM package (for git URL install)
├── scripts/ # Development scripts
└── README.md
Performance
- Initial load from JSON: ~20-40ms
- Cached load: ~1-3ms
- Memory use: 10-15MB
- Fully zero-copy internal model
Building from Source
Rust crates
Swift Package (XCFramework)
Android native libraries
# Requires cargo-ndk and Android NDK
Contributing
Before submitting PRs:
cargo fmt
cargo clippy --all-targets -- -D warnings
cargo test --workspace
cargo doc --workspace
cargo sort -cwg
taplo format --check
cargo deny check
License
Code
MIT License.
Data Attribution (Required)
This project includes data from:
countries-states-cities-database https://github.com/dr5hn/countries-states-cities-database Licensed under Creative Commons Attribution 4.0 (CC-BY-4.0). Attribution is required if you redistribute or use the dataset.
Links
Source & Documentation
- GitHub: https://github.com/holg/geodb-rs
- Rust docs:
- geodb-core: https://docs.rs/geodb-core
- geodb-cli: https://docs.rs/geodb-cli
- geodb-wasm: https://docs.rs/geodb-wasm
Package Registries
- Crates.io: https://crates.io/search?q=geodb
- PyPI (Python bindings): https://pypi.org/project/geodb-rs/
Live Demos
- WebAssembly Demo: https://trahe.eu/geodb-rs.html
- Performance Benchmark: https://trahe.eu/geodb-bench.html
App Downloads
- iOS App Store: https://apps.apple.com/app/geodb-rs/id6755972245
- TestFlight Beta: https://testflight.apple.com/join/TuFejJEq
- Android APKs: See
releases/android/folder
Made with Rust.