Show HN: Latlng – open-source geospatial object engine written in Rust

tobilg1 pts0 comments

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...

latlng server http from engine rust

Related Articles