Local-first spatial sync for PostGIS. A bounding box is a first-class live sync subscription.
const db = await DatumClient.connect({
serverUrl: 'ws://localhost:3000/ws',
bbox: [-122.5, 37.7, -122.4, 37.8],
})
// Full PostGIS, runs locally in WASM — no network
const features = await db.query(`
SELECT * FROM features WHERE ST_Area(geom) > 1000
`)Prerequisites: Docker, Node.js 20+
1. Start PostGIS + datum-server
docker compose up -d2. Install and run the demo
npm install
npm run build -w datum
npm run dev -w datum-demoOpen http://localhost:5173. Click the map to add features. Watch them sync.
3. Verify sync
Open a second browser tab — features added in one tab appear in the other within 5 seconds.
- Client (
datumnpm package): PGlite + PostGIS WASM. Full spatial queries run locally. - datum-server (Go): Thin protocol bridge. Calls PostGIS SQL functions. Contains no spatial logic.
- SQL migration: Installs
datum.sync(),datum.write(), and aNOTIFYtrigger into your PostGIS.
All spatial intelligence lives in PostGIS. The Go server is replaceable.
Run datum-server with -allowed-origin set to your app's domain to prevent unauthorized WebSocket connections:
docker run ghcr.io/a-saed/datum-server \
-db "postgres://user:pass@host/mydb" \
-table features \
-allowed-origin "https://myapp.com"The default * allows all origins and is only suitable for local development.
- API reference — TypeScript client, server flags, wire protocol, SQL functions
Client (PGlite + PostGIS WASM) ↔ WebSocket ↔ datum-server (Go, ~300 lines) ↔ pgx ↔ PostGIS
All spatial logic lives in PostGIS SQL functions (datum schema). The Go server is a stateless protocol bridge — no spatial operations, fully replaceable.
MIT