Choosing a Sync Engine for Local-First in 2026

The following is a first-hand account of how I chose a sync engine for nibfont. This is a real hand-written blog post with the opinions of a human.

tldr: zero wins, livestore is great but not a good match for my use case, electric is radioactive waste that should be avoided at all costs.


Some context on the requirements for nibfont:

  • Real-time multiplayer font editing, similar to Figma but for type design
  • Tens of thousands of glyphs per project, and tens of collaborators (not millions)
  • Very fast local-first writes for UX (offline-first is optional)
  • A good developer experience: minimal custom sync plumbing

First pass: Triplit

Early on, I picked Triplit. It’s a solid, fairly batteries-included engine that handles sync and real-time well.

Eventually I abandoned Triplit for two reasons:

  1. I couldn’t get it to play nice with better-auth.
  2. The Triplit team was “acqui-hired” by Supabase in August 2025, and Triplit became community-maintained. This raised concerns for long-term confidence in the project.

Second pass: Electric SQL + TanStack DB

After Triplit, I wanted a Postgres-forward stack. All hype indicators pointed to Electric SQL with TanStack DB.

On paper, it looked great:

  • Postgres as a first-class primitive
  • Incremental adoption with an existing Postgres database
  • Anything with first-class TanStack integration should work well in my experience

In practice, it was fucking garbage. The biggest issues were:

  • The Electric team geniously chose long polling as the sync push-mechanism, which is an extremely slow and brittle technique that I assume died in the early 2010s.
  • Client-side writes are “choose your own adventure” in Electric, aka set up your own backend HTTP rest-API-style endpoint(s) for writes. TanStack DB helps with this somewhat but it’s an uphill battle.

I spent about two months of my spare time trying to make this architecture work and could not get results I was happy with. I should’ve listened to my intuition about the former creator of gatsby joining the electric team.

Third pass: Livestore

After removing Electric, I replaced it with Livestore. I like Livestore’s architecture a lot. You can run most of it directly on Cloudflare with D1 as the backing SQLite store.

Performance was excellent, and the team actively dogfoods it in Overtone.

It also works extremely fast, and the creator has a live production app built on it called Overtone that they use to dogfood Livestore.

For my specific use case, I discovered that Livestore is not a good fit for one specific architectural reason: one user must correspond to one sqlite instance. This is a big limitation when it comes to sharing data between users. It’s possible to hack it and make it work on an org level, and I believe this is something the Livestore maintainers are working on supporting better, but currently poses a limitation. Livestore is best suited at the moment for something like Overtone, something Spotify-esque — lots of data per user, very little data shared between users, extremely fast client-side reads.

Fourth time’s the charm: Zero

Begrudgingly, I decided to move on from Livestore. I first heard about Zero through Syntax FM, and a colleague at Mirage also recommended it from first-hand production experience on an app. Zero is also basically Rocicorp’s third attempt at building a sync engine so I think they know what they’re doing.

I unleashed Claude on the task of migrating everything from Livestore to Zero and had a working local set up for Zero shortly.

After working out all the typecheck errors and cleaning up some cruft, everything worked, basically flawlessly. It integrates cleanly with Drizzle, and the client footprint is small.

One reason I initially skipped Zero is that it does not include real-time presence. I had to add separate infrastructure for cursor presence/chat. In hindsight, this separation is reasonable: data sync and ephemeral realtime events are different concerns.

So, literally that’s it. Zero just works. I might report back when I get clotheslined by attempting to scale websockets, but chances are my little side project font editor will not blow up so for now I’ll consider this a problem solved.

Honorary Mentions/Other Platforms

Other projects I looked at but did not choose:

  • evolu - very cool e2e encrypted sync engine project
  • jazz - extremely batteries-included
  • convex - also very batteries-included

Key visual: a stroke from the Broad Nib Brush tool in nib

end of storey Last modified: