Skip to content

Implement Expo/React Native support and add forward geocoding#8

Open
sebschlo wants to merge 1 commit intolucaspiller:masterfrom
sebschlo:master
Open

Implement Expo/React Native support and add forward geocoding#8
sebschlo wants to merge 1 commit intolucaspiller:masterfrom
sebschlo:master

Conversation

@sebschlo
Copy link

@sebschlo sebschlo commented Mar 7, 2026

Overview

Add forward geocoding (geocoder.forward(query)) that does exact match with prefix/substring fallback, ranked by population. Requires a database generated with the updated schema — gracefully returns undefined on older databases missing the asciiname/population columns.

Add Expo/React Native entrypoint (src/expo.js) that wraps expo-sqlite into the node-sqlite3 callback interface the existing modules expect. Decouple sqlite3 from index.js so it's lazily required only for Node usage.

Add geonames: support to location.find() for stable identifiers, and fix a copy-paste bug in location.js where callback was referenced but never defined.

Switch named SQL params ($lat, $id) to positional (?) for cross-runtime compatibility with both sqlite3 and expo-sqlite.

Update the database generation script with configurable feature codes, population filters, and admin1 toggle. Extract schema to scripts/schema.sql.

Agent Usage

Note

This PR was kicked off by the following Codex 5.3 prompt, and then heavily reviewed, tested, and human-reworked.

You are working in a fork of offline-geocoder to make it production-usable from Expo/React Native (iOS + Android), not just Node.

Goal

Build a cross-platform offline geocoder library that:

  1. Works in Expo/React Native using expo-sqlite
  2. Still supports Node usage (if practical), but RN support is the priority
  3. Provides stable city IDs for grouping as geonames:
  4. Supports both reverse geocoding and forward city search (name -> canonical city)

Required changes

  1. Replace Node-only runtime assumptions
  • Remove dependence on Node native sqlite3 for RN path.
  • Remove direct runtime dependence on Node-only APIs (path, fs, native addons) in RN entry points.
  • Keep Node support in a separate adapter if needed.
  1. Introduce adapter architecture
  • Create a core query layer (SQL + result normalization).
  • Create DB adapters:
    • Node adapter (optional, existing behavior)
    • Expo adapter using expo-sqlite
  • Ensure API surface is consistent across adapters.
  1. API design
  • Provide:
    • reverse(latitude, longitude) -> nearest city
    • forward(query) -> best canonical city match
    • location.find(id) (or equivalent)
  • Normalize response to include:
    • id (numeric geonames id)
    • name, formatted, country, admin1, coordinates
  1. Database generation pipeline
  • Fix/update generation scripts so they work with current GeoNames dumps.
  • Validate schema + indexes for both reverse and forward lookups.
  • Ensure generated DB is reproducible and documented.
  • If SQL/script in repo is outdated, correct it with tests.
  1. Tests
  • Add/keep automated tests for:
    • Reverse lookup known coordinates (e.g. Rome sample)
    • No-result behavior
    • Forward lookup exact and fuzzy cases
  • Add tests for Expo adapter query execution (can be integration-style with small fixture DB).
  1. Packaging and docs
  • Add clear RN/Expo usage docs:
    • how to bundle/copy prebuilt DB into app assets
    • how to open DB with Expo
  • Keep install and API docs concise and accurate.
  • No network geocoding fallback inside this library.

Constraints

  • Do not add unnecessary dependencies.
  • Keep behavior deterministic and privacy-first (fully offline lookups).
  • Prefer minimal, surgical refactors over rewrite.
  • Keep backward compatibility where reasonable, but RN compatibility is the blocker. Ideally we submit a PR to expand the capabilities of this library.

Deliverables

  1. Code changes implementing above
  2. Passing tests
  3. README updates for Node + Expo usage
  4. Short migration notes (what changed from old API)

…ration

Add forward geocoding (geocoder.forward(query)) that does exact match with
prefix/substring fallback, ranked by population. Requires a database
generated with the updated schema — gracefully returns undefined on older
databases missing the asciiname/population columns.

Add Expo/React Native entrypoint (src/expo.js) that wraps expo-sqlite into
the node-sqlite3 callback interface the existing modules expect. Decouple
sqlite3 from index.js so it's lazily required only for Node usage.

Add geonames:<id> support to location.find() for stable identifiers, and
fix a copy-paste bug in location.js where callback was referenced but
never defined.

Switch named SQL params ($lat, $id) to positional (?) for cross-runtime
compatibility with both sqlite3 and expo-sqlite.

Update the database generation script with configurable feature codes,
population filters, and admin1 toggle. Extract schema to scripts/schema.sql.

Tests now use a fixture database instead of requiring the full data/ dir.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant