Exploring options for local storage & sync

Local-first CRDTs Architecture

From CouchDB & PouchDB to CR-SQLite — what 30-minute sync times taught us, and why a CRDT-on-SQLite path turned out to be the right one. Includes our recent contribution adding OPFS to CR-SQLite.

We started by building Librocco around CouchDB & PouchDB, but eventually decided this wasn’t a viable path forward. There were several reasons for this: CouchDB’s shortcomings; PouchDB’s outdated docs — but ultimately the deciding factor was sync performance. With full production data, two syncing nodes could take more than 30 minutes to communicate changes. This created challenges: how would we keep the UI responsive while this is ongoing, and how would we present conflict resolution in a way that doesn’t overwhelm after all of this time?

We researched alternatives and landed on CR-SQLite because:

  1. SQL felt familiar
  2. CRDT-based sync resolved conflicts without complex user-facing logic
  3. It can be used with or without a central coordinating server, making it a true peer-to-peer option.

We recently contributed to CR-SQLite, updating it to the latest WA-SQLite in order to enable OPFS as a storage layer. Since SQLite stores everything in a single file, this makes importing and exporting data from local storage far easier, and also improves our initial sync times significantly.

Related reading

Feeling stuck or unsure how to proceed?

With every project, we follow a fixed-time, variable-scope approach inspired by Basecamp's Shape Up. Book a short 30 minute call with us to help shape and reduce the scope of your problem until a sensible next step emerges. No obligation beyond that. You'll leave with a clearer framing and a concrete next step, whether or not we continue working together.