Skip to content

Quick Start

Get a two-node active-active SQLite replication cluster running in 5 minutes.

Each runtime is self-contained — install, code, run, and topology links all in one place. All three sync to each other transparently. Mix and match freely.

Go

go get + importable packages. Trigger and hook capture modes. Pre-built binaries.

Bun

bun add hooksync.js + bun:sqlite. Trigger-based capture. Bun.serve() wiring.

Node.js

npm install hooksync.js + better-sqlite3. Trigger-based capture. http.createServer or Express.

Other Languages

Rust, Python, PHP, or any language with SQLite + HTTP. Wire protocol is language-agnostic.

Every synced table must have:

  • id — TEXT PRIMARY KEY (UUID, zero conflict)
  • updated_at — INTEGER (millisecond timestamp, for last-write-wins)
CREATE TABLE items(
id TEXT PRIMARY KEY,
name TEXT,
value INTEGER,
created_at INTEGER,
updated_at INTEGER
);

When you call attach() (JS) or trigger.Attach() (Go), the library:

  1. Creates _meta, _changes, _dead_letter, _peer_state tables
  2. Auto-generates INSERT/UPDATE/DELETE triggers via schema introspection
  3. Starts a background ship loop (50ms default)
  4. Handles ACK-based retry with exponential backoff
  5. Manages per-peer watermarks for multi-peer topologies

You only write CRUD endpoints + wire POST /sync to mgr.applyChanges() (JS) or http.Handle("/sync", mgr) (Go).

Once you have two nodes syncing, explore topologies: