True offline-first sync for modern appsβwithout vendor lock-in
Getting Started β’ Documentation β’ Examples β’ Discussions β’ Roadmap
SyncKit is a production-ready sync engine that makes building local-first applications trivial.
"Add
sync.document()to your app, get real-time sync automatically."
The problem: Building sync from scratch takes months. Existing solutions are complex (Yjs), expensive (Firebase), or don't work offline (Supabase).
The solution: SyncKit gives you production-ready sync in 3 lines of code.
const sync = new SyncKit() await sync.init() const doc = sync.document<Todo>('todo-123') await doc.update({ completed: true }) // β¨ Works offline, syncs automatically, resolves conflictsReal-time collaboration with offline resilience: Watch tasks sync instantly across tabsβeven while offline. The example app demonstrates SyncKit's offline-first capabilities combined with smart browser storage to create a seamless collaborative experience.
True offline-first architectureβnot just caching. Your app works perfectly on planes, trains, tunnels, and coffee shops with spotty WiFi.
~59 KB gzipped (10KB SDK + 49KB WASM) - Complete WASM-based sync engine with TypeScript SDK.
Current features (v0.1.0):
- β Offline-first sync (LWW)
- β Real-time collaboration
- β Network protocol support
- β IndexedDB persistence
- β Cross-tab sync (see example)
Coming in v0.2.0:
- π§ Text CRDTs (character-level editing)
- π§ Counters, Sets (distributed data structures)
Size-critical apps? Use Lite variant (~45 KB gzipped: 1.5KB SDK + 44KB WASM, local-only)
Competitive bundle size: Larger than Yjs (~19KB pure JS), smaller than Automerge (~60-78KB).
Open source and self-hostable. No vendor lock-in, no surprise $2,000/month bills, complete data sovereignty.
- <1ms local operations (~5-20ΞΌs single field update)
- <100ms sync latency (10-50ms p95)
- ~59KB bundle (10KB SDK + 49KB WASM), ~45KB lite option
- Sub-200KB total with React
- Zero data loss with automatic conflict resolution (Last-Write-Wins)
- Formal verification with TLA+ (3 bugs found and fixed)
- 700+ comprehensive tests across TypeScript and Rust (unit, integration, chaos, load)
| Feature | SyncKit | Firebase | Supabase | Yjs | Automerge |
|---|---|---|---|---|---|
| True Offline-First | β Native | (40MB limit) | β None (#357 - 4+ years) | β Full | β Full |
| Works Without Server | β Yes | β No | β No | β Yes | β Yes |
| Bundle Size (gzipped) | ~59KB (45KB lite) | ~150KB | ~45KB | ~19KB | ~60-78KB |
| Text CRDT | π§ v0.2.0 | β No | β No | β Yes | β Yes |
| Counters/Sets | π§ v0.2.0 | β No | β No | β Yes | β Yes |
| Automatic Conflicts | β LWW | β LWW | β CRDT | β CRDT | |
| Self-Hosted | β Yes | β No | β Yes | β Yes | β Yes |
| Multi-Language Server | β
TS π§ Py/Go/Rust | β No | β JS only | β JS only | |
| Pricing | Free (self-host) | $25-$2,000+/mo | $0-$25/mo | Free | Free |
| TypeScript Support | β Native | β Good | β Good | β Good | |
| Learning Curve | β 5 minutes | ||||
| Production Status | β v0.1.0 ready | β Mature | β Mature | β Mature |
TL;DR:
- vs Firebase: No vendor lock-in, true offline, predictable costs
- vs Supabase: Actually works offline (their #1 issue for 4+ years)
- vs Yjs: WASM-based for multi-language server support, simpler API for structured data
- vs Automerge: Smaller bundle, faster performance, production-ready
See detailed migration guides β
npm install @synckit-js/sdkimport { SyncKit } from '@synckit-js/sdk' import { SyncProvider, useSyncDocument } from '@synckit-js/sdk/react' // Initialize (works offline-only, no server needed!) const sync = new SyncKit() await sync.init() function App() { return ( <SyncProvider synckit={sync}> <TodoApp /> </SyncProvider> ) } function TodoApp() { const [todo, { update }] = useSyncDocument<Todo>('todo-1') if (!todo || !todo.text) return <div>Loading...</div> return ( <div> <input type="checkbox" checked={todo.completed} onChange={(e) => update({ completed: e.target.checked })} /> <span>{todo.text}</span> </div> ) }That's it! Your app now:
- β Works 100% offline
- β Syncs across tabs automatically
- β Persists data in IndexedDB
- β Resolves conflicts automatically
Bundle: SyncKit (~59 KB gzipped) + React (~130 KB) = ~189 KB total
Size-critical? import { SyncKit } from '@synckit-js/sdk/lite' (~45 KB gzipped, local-only)
- π Real-Time Sync - WebSocket-based instant sync across devices
- π΄ Offline-First - Works perfectly with zero connectivity
- ποΈ Local Persistence - IndexedDB storage, unlimited capacity
- π Conflict Resolution - Automatic Last-Write-Wins (LWW) merge
- β‘ Fast Operations - <1ms local updates, <100ms sync latency
- π¦ Compact Bundle - ~59KB gzipped (10KB SDK + 49KB WASM)
- π Secure - JWT authentication, RBAC permissions
- βοΈ React Hooks -
useSyncDocument,useSyncField,SyncProvider - π TypeScript Server - Bun + Hono reference implementation
- π¦ Multi-Variant - Default (~59KB gzipped) or Lite (~45KB gzipped) builds
- βοΈ Text CRDTs - Collaborative text editing (character-level sync)
- π’ Counters - Conflict-free increment/decrement
- π Sets & Lists - Observed-Remove Sets for collections
- π¨ Framework Adapters - Vue composables, Svelte stores
- π Multi-Language Servers - Python, Go, Rust implementations
graph TD A[Your Application<br/>React/Vue/Svelte] --> B[SyncKit SDK<br/>TypeScript] B -->|Simple API| B1[document, text, counter] B -->|Framework adapters| B2[React/Vue/Svelte hooks] B -->|Offline queue| B3[Storage adapters] B --> C[Rust Core Engine<br/>WASM + Native] C -->|80% of use cases| C1[LWW Sync] C -->|Collaborative editing| C2[Text CRDTs] C -->|Advanced features| C3[Custom CRDTs<br/>counters, sets] C --> D[IndexedDB Storage<br/>Your local source of truth] D -.->|Optional| E[SyncKit Server<br/>TypeScript/Python/Go/Rust] E -->|Real-time sync| E1[WebSocket] E -->|Persistence| E2[PostgreSQL/MongoDB] E -->|Security| E3[JWT auth + RBAC] style A fill:#e1f5ff,stroke:#333,stroke-width:2px,color:#1a1a1a style B fill:#fff4e1,stroke:#333,stroke-width:2px,color:#1a1a1a style C fill:#ffe1e1,stroke:#333,stroke-width:2px,color:#1a1a1a style D fill:#e1ffe1,stroke:#333,stroke-width:2px,color:#1a1a1a style E fill:#f0e1ff,stroke:#333,stroke-width:2px,color:#1a1a1a Detailed architecture docs β
- 5-Minute Quick Start - Build your first synced app
- Installation Guide - Setup instructions
- API Reference - Complete API documentation
- Offline-First Patterns - True offline architecture
- Conflict Resolution - Automatic LWW merge strategy
- Performance Optimization - Bundle size, memory, sync speed
- Testing Guide - Property-based tests, chaos engineering
- From Firebase/Firestore - Escape vendor lock-in
- From Supabase - Add offline support
- From Yjs/Automerge - Simplify your stack
- Todo App - Simple CRUD with filters
- Collaborative Editor - Real-time text editing with CodeMirror 6
- Project Management - Production-grade kanban app with drag-and-drop
Perfect for: Task apps, CRMs, project management, note apps (80% of applications)
// Initialize once const sync = new SyncKit() await sync.init() // Use anywhere const doc = sync.document<Project>('project-123') await doc.update({ status: 'completed' }) // Conflicts resolved automatically with Last-Write-WinsPerfect for: Collaborative editors, documentation, notes
// Note: Text CRDT API is planned for v0.2.0 const text = sync.text('document-456') await text.insert(0, 'Hello ') text.subscribe(content => editor.setValue(content)) // Character-level sync, conflict-free convergencePerfect for: Whiteboards, design tools, specialized apps
// Note: Counter API is planned for v0.2.0 const counter = sync.counter('likes-789') await counter.increment() // Conflict-free counter (additions never conflict)@synckit-js/sdk- Core SDK (TypeScript) + WASM engine@synckit-js/sdk/react- React hooks and components (export from SDK)@synckit-js/sdk/lite- Lightweight version (local-only, 45KB gzipped)
@synckit-js/server- Bun + Hono reference server (production-ready)
Current Version: v0.1.0 Production Ready: Core sync engine, React hooks, TypeScript server β
- β Core Rust Engine - LWW sync engine with CRDT foundation
- β WASM Compilation - 59KB gzipped (45KB lite), optimized performance
- β TypeScript SDK - Document API, IndexedDB storage, offline queue
- β Cross-Tab Sync - Server-mediated sync with operation buffering for multi-tab coordination
- β
React Integration -
useSyncDocument,useSyncField,SyncProviderhooks - β TypeScript Server - WebSocket sync server with Bun + Hono
- β Example Applications - Todo app, collaborative editor, project management demos
- β Documentation - Comprehensive guides and API reference
- β Build System - Complete toolchain with benchmarks and CI
- π§ Text CRDTs - Collaborative text editing (
useTexthook) for character-level sync - π§ Counter CRDTs - Distributed counters (
useCounterhook) for conflict-free increments - π§ BroadcastChannel Cross-Tab - Direct client-to-client sync without server (offline multi-tab)
- π§ Framework Adapters - Vue composables (
@synckit-js/sdk/vue), Svelte stores (@synckit-js/sdk/svelte) - π§ Multi-Language Servers - Python, Go, Rust server implementations (TypeScript complete)
- π§ Advanced Storage - OPFS (Origin Private File System), SQLite adapter
- π§ Conflict UI - Visual conflict resolution interface for complex merge scenarios
We welcome contributions from the community!
Ways to contribute:
- π Bug Reports - Open an issue
- π Documentation - Improve guides, fix typos
- π§ͺ Tests - Add test coverage
- π Servers - Implement Python/Go/Rust servers
- π‘ Features - Propose new features in discussions
Need enterprise support?
- π― Managed Hosting - We host SyncKit servers for you
- π Priority Support - 24/7 support, SLA guarantees
- π Monitoring & Analytics - Dashboard, alerts, insights
- π Training & Consulting - Onboarding, architecture review
Contact: danbitengo@gmail.com
Yjs: ~19 KB ββββ SyncKit (lite): ~45 KB βββββββββ SyncKit (default): ~59 KB ββββββββββββ Automerge: ~60-78 KB ββββββββββββββββ Firebase: ~150 KB ββββββββββββββββββββββββββββββββ Local update: <1 ms ββββ Cross-tab sync: <1 ms ββββ Network sync: 10-50 ms ββββββββ Firebase (cold): 2-30 s ββββββββββββββββββββββββββββββββ SyncKit: 3 MB ββββ Yjs: 8 MB βββββββββ Automerge: 180 MB ββββββββββββββββββββββββββββββββββββββββ Built with inspiration from:
- Yjs - YATA algorithm and performance optimization
- Automerge - CRDT theory and formal verification
- Linear - Pragmatic approach to sync
- Figma - Custom sync architecture patterns
- RxDB - Local-first database patterns
Special thanks to the local-first community for pioneering this movement.
MIT License - see LICENSE for details.
Copyright (c) 2025 Daniel Bitengo
- Documentation - Complete guides and API reference
- GitHub - Source code
- Issues - Bug reports and features
- Roadmap - Development timeline
- Discussions - Community discussions
- LinkedIn - Connect and follow updates
Built with β€οΈ for the local-first future
β Star us on GitHub β’ π Read the docs β’ π Get started
