latlng — Open-source geospatial object engine in Rust + WebAssembly
GitHub
would create a stacking<br>context that traps the ticker below the content container at z-20.<br>-->
A geospatial object engine for<br>moving things.
latlng is an open-source spatial database in Rust. Index moving points, define geofences as code, stream geofence events as they happen — natively, or directly in the browser via WebAssembly.
View on GitHub
How it works
50 simulated vehicles
Hamburg districts (geofences)<br>@latlng/wasm<br>in a Web Worker
Features<br>Built for things that move.
Core commands and queries are available over HTTP/JSON and Cap'n Proto, geofence events stream over WebSocket subscriptions, and the browser SDK runs the same Rust core in WebAssembly.
Spatial indexing
R-tree spatial indexing and field indexes for nearby, within, intersects, scan, and text search — backed by a portable Rust core.
Geofencing as code
Define hooks with circles, bounds, GeoJSON areas, or roaming distance. Emit inside, outside, enter, exit, cross, and roam events as objects move.
Webhook eventing
Durable HTTP POST delivery from a SQLite-backed outbox. Per-request timeouts, exponential backoff, dead-letter — at-least-once with stable event IDs.
Three transports
HTTP/JSON with generated OpenAPI, WebSocket subscriptions, and async Cap'n Proto RPC — all backed by the same engine and auth model.
Pluggable storage
Run the server in memory or on an append-only file. The Rust storage layer also includes SQLite for embedded use, plus AOF compaction, verification, backup, and restore.
Single-leader replication
Streaming replication over Cap'n Proto with checksum-based resume. Read-only followers catch up incrementally and serve queries after initial sync.
Auth that fits
Static bearer tokens, HMAC JWTs, asymmetric JWTs from PEM keys or JWKS. Claims-based authz scoped per collection.
Browser-native
The same engine compiles to wasm and runs in a Web Worker. Build local-first map apps with no server in the loop — like the demo above.
Operational from day one
Prometheus metrics, structured logging, HTTP rate limits per principal, runtime config rewrite — built for production, not just demos.
How it works<br>One engine. Two shapes.
latlng compiles a single Rust core into the form that fits where you run it — a service you deploy or a worker that ships with your web app.
Native server latlng-server<br>Run it as a standalone process. HTTP/JSON, WebSocket subscriptions, and async Cap'n Proto RPC, all from the same binary, behind the same auth.<br># Start the server binary<br>latlng-server
# Store a point<br>curl -sS -X POST http://127.0.0.1:7421/collections/fleet/objects/truck-1 \<br>-H 'content-type: application/json' \<br>-d '{"object":{"Point":{"lat":53.55,"lon":9.99,"z":null}}}'
# Query nearby points<br>curl -sS -X POST http://127.0.0.1:7421/collections/fleet/search/nearby \<br>-H 'content-type: application/json' \<br>-d '{"lat":53.55,"lon":9.99,"meters":1000,"options":{}}'<br>Browser @latlng/wasm<br>The same engine, compiled to WebAssembly and pinned inside a Web Worker. Local-first geospatial — no server, no network, no key.<br>import { createLatLng } from "@latlng/wasm";
const db = await createLatLng();<br>await db.createCollection("fleet");<br>await db.setPoint("fleet", "truck-1", { lat: 53.55, lon: 9.99 });
const nearby = await db.nearby("fleet", {<br>lat: 53.55,<br>lon: 9.99,<br>meters: 1000,<br>});
console.log(nearby.results);
Getting started<br>Run latlng where you need it.
Use a release binary, install on macOS via Homebrew, pull the published container, or build the native server and CLI from source.
Release binaries Download from GitHub
Release archives contain the native server and CLI. Pick the asset for your platform, extract it, and start the server binary.<br>Assets are named linux-x64, macos-arm64, and windows-x64.<br>curl -fsSL -o latlng-linux-x64.tar.gz \<br>"https://github.com/tobilg/latlng/releases/latest/download/latlng-linux-x64.tar.gz"
tar -xzf latlng-linux-x64.tar.gz<br>chmod +x latlng-server latlng-cli<br>./latlng-server<br>Homebrew Tap and install
Install the native server and CLI on macOS via Homebrew. The tap ships the same release binaries with a launchd service definition and a default config under the Homebrew prefix.<br>Currently macOS on Apple Silicon (arm64) only.<br>brew tap tobilg/latlng<br>brew install latlng
# Run as a background service<br>brew services start latlng
# Or run it directly with the bundled config<br>latlng-server --config $(brew --prefix)/etc/latlng/latlng.toml<br>Docker Run the image
The published image runs as a non-root user and expects a mounted config file at /etc/latlng/latlng.toml.<br>The example config exposes HTTP, WebSocket, metrics, and Cap'n Proto ports.<br>TAG=v0.1.1<br>git clone https://github.com/tobilg/latlng.git<br>cd latlng
docker run --rm --name latlng \<br>-p 7421:7421 -p 7422:7422 \<br>-v "$(pwd)/examples/docker/single-node.toml:/etc/latlng/latlng.toml:ro" \<br>-v latlng-data:/var/lib/latlng \<br>tobilg/latlng:$TAG<br>From source Build locally
Build the release...