A relentless, offline-first sync engine for Go.
Zero dependencies. Instant sync. Full ownership.
🌐 Website · 📖 Documentation · 📦 NPM Package · 🎨 Website Repo
Most "offline-first" solutions lock you into their ecosystem (Firebase, Supabase, CouchDB). GoSync works differently.
It is a Protocol, not a Platform.
- Go + WASM: We run the exact same Go code in the browser (via WebAssembly) and on the server.
- IndexedDB Persistence: Your app works perfectly offline. Data survives refreshes and restarts.
- Bidirectional Sync: Changes made offline automatically upload when online. Server changes download instantly.
- Merkle Tree & Snapshots: Efficiently detects data mismatches and "heals" the state using a robust sync protocol.
- Local-First: The client is the source of truth. The server is just a backup.
- Client: Go (compiled to stored WASM) + IndexedDB (via
idb-keyval). - Server: Go + SQLite (or switch to Postgres easily).
- Communication: WebSockets (Real-time).
- Storage:
syscall/jsBridge to Browser APIs.
npm install @harshalpatel2868/gosync-clientWe included a "Kitchen Sink" demo.
Windows:
.\run_demo.batMac/Linux:
chmod +x run_demo.sh
./run_demo.sh- Open
http://localhost:3000. Status should be 🟢 Online. - Add a task: "Hello World".
- Kill the Server (Close the terminal). Status turns 🔴 Offline.
- Add a task: "I am offline".
- Refresh the Page. The tasks are still there! (IndexedDB Persistence).
- Restart the Server. Status turns 🟢 Online.
- Check Server Logs: It will say "Synced!" and have both items.
# Windows
go build -o server.exe ./cmd/server
# Mac/Linux
go build -o server ./cmd/server# Windows (PowerShell)
$env:GOOS = "js"; $env:GOARCH = "wasm"; go build -o dist/main.wasm ./cmd/client# Mac/Linux
GOOS=js GOARCH=wasm go build -o dist/main.wasm ./cmd/clientStart the Backend:
./server.exeStart the Frontend Host:
python -m http.server 3000 --directory distVisit http://localhost:3000.
Add items.
Go offline.
Refresh.
Synced.
How to use GoSync in your own Go application:
// 1. Define your data
type Task struct {
ID string
Content string
}
// 2. Initialize the Sync Engine
repo := gosync.NewBrowserRepo() // Auto-connects to IndexedDB
engine := gosync.NewEngine(repo)
// 3. Add Data (Works Offline!)
engine.Add(Task{ID: "1", Content: "Buy Milk"})
// -> Automatically syncs to server when onlinegraph TD
User[User Action] -->|Add Item| ClientDB[(IndexedDB)]
ClientDB -->|Update| Merkle[Merkle Tree]
Merkle -->|Hash Mismatch| Sync[Sync Engine]
Sync -->|WebSocket| Server[Go Server]
Server -->|Persist| SQLite[(SQLite/Postgres)]
MIT License © 2025 Harshal Patel.