[HN Gopher] Show HN: SyncKit - Offline-first sync engine (Rust/W...
       ___________________________________________________________________
        
       Show HN: SyncKit - Offline-first sync engine (Rust/WASM and
       TypeScript)
        
       Author : danbitengo
       Score  : 67 points
       Date   : 2025-11-27 14:31 UTC (8 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | danbitengo wrote:
       | Hey HN, I built SyncKit after shipping two local-first projects
       | (RestBolt and Graft) and realizing there's no simple way to add
       | cross-device sync.
       | 
       | The problem: Existing solutions are either too complex
       | (Automerge/Yjs require learning CRDTs) or too restrictive
       | (Firebase isn't truly local-first, Supabase has no offline
       | support - issue #357 has been open 4+ years with 350+ upvotes).
       | 
       | SyncKit is the middle ground: simple API, works offline-first,
       | self-hostable.
       | 
       | Technical highlights: - TLA+ formal verification: 118,711 states
       | checked, caught bugs before implementation - Rust - WASM core
       | (48.9KB gzipped) - 700+ tests including 80 chaos tests (zero data
       | loss) - Server: Bun/Hono WebSocket (SDK works in any JS runtime)
       | - Production-ready: v0.1.0 on npm and Docker Hub
       | 
       | Known limitations (v0.1.0): - LWW only - advanced CRDTs (Text,
       | Counter, Set) coming in v0.2.0 - React hooks only - Vue/Svelte
       | adapters planned - Reference server is Bun (Node/Deno coming
       | v0.3.0)
       | 
       | Happy to answer questions about the CRDT implementation, TLA+
       | modeling, or WebSocket architecture.
       | 
       | GitHub: https://github.com/Dancode-188/synckit npm: @synckit-
       | js/sdk
        
         | threatofrain wrote:
         | TLA+ checked! Whoa!
        
           | danbitengo wrote:
           | Thanks! The TLA+ modeling actually caught 3 bugs even before
           | I wrote any code. Worth the upfront investment. It's way
           | easier to debug a state machine model than distributed sync
           | logic.
           | 
           | Happy to share more about the verification approach if you're
           | interested!
        
             | JackYoustra wrote:
             | VERY interested, are you planning on writing a blog? If so
             | I would definitely read that post.
        
               | danbitengo wrote:
               | I appreciate the enthusiasm! And yeah, I'm planning to
               | start blogging about the build process and some of the
               | technical decisions probably after launch week settles
               | down. I'll post about it on LinkedIn and in the GitHub
               | Discussions when it's live. If you're following either,
               | you'll see it!
               | 
               | Thanks for the interest!
        
             | rancar2 wrote:
             | Please do in the repo, and thank you for the wonderful
             | contribution on multiple fronts. This is very well done
             | work and documentation. A few tips to help others discover
             | the value on the Readme: Add the key memory benchmark
             | (currently just above the acknowledgments) to the top of
             | the Readme and link to the rest of the benchmarks on the
             | page that you already have (maybe rename it benchmarks.md
             | in the process): https://github.com/Dancode-188/synckit/blo
             | b/main/docs/guides...
        
               | danbitengo wrote:
               | That's a great suggestion. The memory benchmark being
               | buried is a fair point. I'll move it up top and create a
               | proper benchmarks.md page. Thanks for the detailed
               | feedback.
        
         | mkl wrote:
         | The ReadMe says "Zero data loss with automatic conflict
         | resolution (Last-Write-Wins)", bur doesn't LWW guarantee data
         | loss?
        
           | danbitengo wrote:
           | See my response to skybrian above. You're both asking the
           | same good question about the LWW messaging. Short version:
           | system-level guarantees, not user-level concurrent edit
           | preservation.
        
         | jmoggr wrote:
         | > Automerge/Yjs require learning CRDTs
         | 
         | I've been using Automerge for a while and haven't had to look
         | at any CRDTs. To me this looks very similar to Automerge.
         | 
         | Neat project!
        
       | android521 wrote:
       | Is support for react native on the roadmap?
        
         | danbitengo wrote:
         | Not yet, but it's definitely something I'm considering.
         | 
         | Right now v0.1.0 is React (web) only. I'm planning Vue/Svelte
         | for v0.2.0, and React Native could absolutely be v0.3.0 or
         | sooner if there's demand.
         | 
         | The nice thing is the core sync engine is Rust - WASM, so it's
         | framework-agnostic. The main work is just creating the React
         | Native bindings and not rebuilding the sync logic.
         | 
         | Are you working on something with React Native? Curious what
         | your offline sync needs are because it'd help me prioritize
         | what to build next.
        
       | gagik_co wrote:
       | This is impressive! After Realm depreciation I have been trying
       | many different offline sync options, they are especially few on
       | Dart... Dart-Rust binding generator is pretty great though so
       | it's nice this is in Rust. Will keep an eye on this.
        
         | danbitengo wrote:
         | Thanks! Yeah, Realm's shift in direction left a gap in the
         | offline-first space.
         | 
         | I didn't build Dart bindings yet (Rust - WASM - TypeScript for
         | v0.1.0), but since the core is in Rust, Dart bindings via
         | dart_rust_bridge are definitely feasible. Would actually be a
         | great addition.
         | 
         | Are you actively looking for a Realm replacement for a Dart
         | project? Curious what your offline sync requirements are. It
         | might help me prioritize Dart support
        
           | satvikpendem wrote:
           | I use Loro CRDT, which is written in Rust as well, on my Dart
           | apps with flutter_rust_bridge and it works pretty well. For
           | syncing I'm using their Loro protocol product although I used
           | iroh before. However, the annoying thing about how the CRDT
           | libraries work is that they're essentially key value NoSQL
           | type storage, not relational. I would love something like
           | SQLite or Postgres on both the server and client that can
           | sync, which companies like ElectricSQL have, but no Dart
           | bindings and also I'd prefer to be in the all Rust ecosystem
           | as well as self host.
        
             | rancar2 wrote:
             | This is a write up that may be helpful for you:
             | https://sqlsync.dev/posts/stop-syncing-everything/
        
             | danbitengo wrote:
             | You've hit on the core limitation because SyncKit has the
             | same issue. Document/key-value like Loro and Yjs. The
             | relational model problem is fundamental to CRDTs. They
             | guarantee conflict-free convergence because documents are
             | independent, but that breaks with foreign keys and joins.
             | Can't have arbitrary SQL queries and guaranteed convergence
             | without coordination.
             | 
             | ElectricSQL and PowerSync solve it differently (full SQL
             | but weaker offline guarantees). For SyncKit, document-based
             | state is an architectural choice, not something v0.2.0 will
             | change.
             | 
             | I'm curious to know how you're working around this with
             | Loro. Are you building your own query layer or are you
             | keeping everything denormalized?
        
       | mike_kamau wrote:
       | Good work @danbitengo Is this usable in native Android app
       | development?
        
         | danbitengo wrote:
         | Thanks! For native Android, not directly yet because v0.1.0 is
         | Rust - WASM - TypeScript (web/Node/Deno/Bun).
         | 
         | But since the core sync engine is pure Rust, native Android
         | bindings are definitely possible. The main paths would be:
         | 
         | 1. JNI bindings directly from Rust
         | 
         | 2. Or using the existing WASM core with a JVM WASM runtime
         | 
         | Haven't prioritized this yet since v0.1.0 focused on web/JS
         | ecosystem, but if there's demand for Android, I could explore
         | it. Are you working on something that needs offline sync on
         | Android?
        
       | p2hari wrote:
       | Always nice to see something in here. Would love to hear what is
       | your take on https://www.instantdb.com/?
        
         | danbitengo wrote:
         | I haven't tried InstantDB yet, but it looks really interesting.
         | Thanks for the pointer! Will definitely check it out.
        
       | skybrian wrote:
       | The conflict resolution guide seems quite clear:
       | 
       | https://github.com/Dancode-188/synckit/blob/main/docs/guides...
       | 
       | But I'm a little confused about why it says "Zero data loss with
       | automatic conflict resolution" on the top level page and "data
       | loss possible" under the disadvantages of last-write-wins
       | conflict resolution. It makes sense that you have to start
       | somewhere, but to my mind, last-write-wins isn't really conflict
       | resolution? What does using this library solve?
       | 
       | I guess it means edits to different fields don't conflict. But if
       | it's the same field, it will get clobbered.
        
         | danbitengo wrote:
         | You're right that this is confusing.
         | 
         | "Zero data loss" means system-level guarantees (no corruption
         | from network failures, crashes, etc), not that concurrent edits
         | to the same field are preserved. LWW definitely clobbers one of
         | the edits.
         | 
         | What v0.1.0 does give you is field-level granularity (edits to
         | different fields don't conflict) and guaranteed convergence
         | (all devices reach the same state). But yeah, same field = last
         | write wins.
         | 
         | The Rust core already has better CRDTs (Text, Counter, Set)
         | that handle concurrent edits properly. They just need to
         | exposed in the TypeScript SDK for v0.2.0.
         | 
         | I should clarify this in the docs. Thanks for pointing it out.
        
       | whatever3 wrote:
       | Based on the commits(especially the early/foundational ones) this
       | seems to be built primarily with Claude, but I don't see that
       | mentioned in the README.
        
       | pm wrote:
       | When you mentioned offline sync and graft, I mistook you for the
       | author of this project:
       | 
       | https://github.com/orbitinghail/graft
       | 
       | However, they're clearly two different projects.
       | 
       | I don't want to take away from the work you've done, as you're
       | clearly knowledgeable, but as someone else observed, heavy use of
       | AI assistance can be observed in all your public projects. It's
       | worth explicitly addressing, especially considering the
       | foundational nature of your project: it's not easily replaced if
       | it turns out to have to have subtle bugs.
       | 
       | Though I rarely use it myself, I'd like to know, simply because
       | I'm curious as to how other engineers have incorporated such
       | assistance it into their process.
        
       | kbenson wrote:
       | I _think_ I know what this is, but the description is so much in
       | its own context I 'm not _sure_. It 's for web-apps that also
       | want an offline local version that works and deals with syncing
       | the data when online again and either local or remote is updated?
       | 
       | It probably markets and explains itself perfectly find for
       | someone in that space and/or looking for this solution, so I'm
       | not sure that's actually a problem, but if you also want to stick
       | in the mind of someone that sees this and doesn't have any
       | _current_ interest, but may stumble into needing a solution like
       | this in the future, a few extra words in your initial description
       | might help it be understood more quickly and be something
       | remembered even if they don 't dive into it. Or maybe it's fine
       | and I'm just a bit slow today.
        
       | Tooster wrote:
       | I want to create a local first, offline/p2p realtime multiplayer
       | prototype app soon with reactive/signal data model and frontend
       | agnostic design (considering solidjs/svelte). I'm on a tech
       | research stage. How does it compare to rxdb, tinybase and zero
       | sync? For reference right now I'm considering tinydb/rxdb.
        
       | dgrcode wrote:
       | Some time ago I was looking for a similar solution -offline first
       | and easy sync- and was happy to find https://jazz.tools/. There
       | are many things in common between these two projects. Just
       | mentioning in case you want to check it out.
        
       ___________________________________________________________________
       (page generated 2025-11-27 23:01 UTC)