v0.1.3 on npm

SQLite replication
that just works

Multi-server. Multi-writer. Multi-runtime. Zero data loss.

No consensus. No Raft. No coordinator. Just triggers, ACK, and UUID.

bash — hook-sync
# Install
$ npm install hooksync.js
$ go get hook-sync/go/trigger

# Run two nodes — that's it
$ ./hook-sync-go -id node1 -listen :9001 -peer localhost:9002
$ ./hook-sync-go -id node2 -listen :9002 -peer localhost:9001
3.8x
faster than Postgres
at batch 10K
36/36
split-brain tests
pass (Go, Bun, Node)
3
runtimes sync
to each other
0
data loss
crash-tested

How it works

Three primitives: triggers, ACK, and UUID. No consensus algorithm. No Raft. No coordinator.

1
App Write
Native SQLite speed
→
2
Trigger
Capture to _changes
→
3
Ship
HTTP POST to peers
→
4
Apply
INSERT OR REPLACE
→
5
ACK
Delete from _changes

Why hook-sync?

SQLite simplicity + multi-writer replication + cross-runtime interop, without consensus overhead.

Multi-Writer

All nodes accept writes independently. UUID PKs = zero conflict, no coordinator, no CRDT.

Cross-Runtime

Go, Bun, Node, and any language with SQLite + HTTP. Same wire protocol. Mix and match freely.

Zero Write Penalty

Sync runs in background. Write speed identical with or without peers. 0% overhead.

Crash Recovery

Changes survive in SQLite _changes table. Resume on restart. Zero data loss, verified.

Split-Brain Safe

Last-write-wins by timestamp. Both nodes always converge. Clock skew detected via health endpoint. 36/36 tests pass.

Clock Skew Detection

Health endpoint reports max clock skew. Alert when nodes drift — NTP required, same as Cassandra.

4 Topologies

Point-to-point, full mesh, dedicated hub, multi-region. All built and benchmarked.

How it compares

hook-sync fills a gap no other project covers: SQLite simplicity + multi-writer + cross-runtime.

PostgresLitestreamrqlitehook-sync
Multi-writer✗ Primary-only✗ Read-only✗ Leader-only✓ All nodes write
Write penalty✗ WAL overhead✓ Async✗ Raft quorum✓ 0% overhead
Cross-runtime✗ C only✗ Go only✗ Go only✓ Go · Bun · Node · any
Split-brain safe✓ Sync repl✗✓ Raft✓ Timestamp LWW
Crash recovery✓ WAL replay✓ S3 restore✓ Raft log✓ _changes replay
Batch 10K QPS8,278N/AN/A31,558

Pick your stack

Each runtime is self-contained. All sync to each other — same wire protocol, same ACK-based reliability.

go get hook-sync/go/trigger

Go →

Importable packages. Trigger + hook capture modes. Pre-built binaries. Cross-runtime.

bun add hooksync.js

Bun →

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

npm install hooksync.js

Node.js →

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

SQLite + HTTP = sync

Other Languages →

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

Four topologies

From 2 nodes to multi-region. All built, verified, and benchmarked.

Node A ←→ Node B

Point-to-Point →

2 nodes, active-active. Simplest setup — one --peer flag each.

A ←→ B ↕ ╳ ↕ C ←→ D

Full Mesh →

3-7 nodes, all-to-all. Per-peer watermarks, no coordinator.

edge1 → hub → edge2 edge3 → hub → edge4

Dedicated Hub →

8+ nodes. Go-only relay with Pebble KV. Durable forwarding queue.

R1: edge → hub A ←→ hub B ← edge :R2

Multi-Region →

Hub-to-hub cross-region. Loop prevention via X-Node-Url header.

Ready to sync?

Get up and running in 5 minutes. Go, Bun, Node, or any language with SQLite + HTTP.

Quick Start →