cd /news/developer-tools/super-simple-sync-with-durable-state… · home topics developer-tools article
[ARTICLE · art-76730] src=streamsy.gandrew.com ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

Super Simple Sync with Durable State and TanStack DB

TanStack DB and Durable Streams have released StreamDB, a lightweight sync adapter that combines TanStack DB's local reactive collections with Durable Streams' resumable HTTP protocol, enabling developers to build custom sync engines without a full sync solution. The integration uses Durable State's collection-change vocabulary to route insert, update, and delete operations into local TanStack DB collections via a single ordered stream.

read3 min views1 publishedJul 28, 2026
Super Simple Sync with Durable State and TanStack DB
Image: source

Super Simple Sync with Durable State and TanStack DB Sync engines are taking off. In 2026 you are spoiled for choice: Zero, Electric, PowerSync, and LiveStore, to name a few. However, what if you don't need a full sync engine? Maybe you just need a little sync, or you want to build your own. Thanks to what Claude wants to call "the great unbundling" of ElectricSQL, we don't have to choose between a full sync engine and rolling our own

First, let's quickly review what we mean by a sync engine. There are really two ways to look at it:

  • From the developer perspective, a sync engine decouples data transport from local state management. It allows you to write your application as if the state were local, while the sync engine handles the details of keeping that state in sync with a remote source.
  • From the user perspective, a sync engine provides a local-first experience, with instantaneous loads and real-time updates.
[The three pieces](#the-three-pieces)

[TanStack DB: the local database](#tanstack-db-the-local-database)

The easiest way to think about TanStack DB is that it solves the client-side part of the sync engine. It gives us:

- typed local collections;
- live, reactive queries;
- optimistic mutations;
  • one local place to merge confirmed server changes.

The UI mostly does not care whether an item arrived during initial catch-up, live tailing, or an optimistic mutation. It reads from local collections. A sync adapter is responsible for keeping the collections' confirmed state aligned with the server.

Durable Streams: the transport Durable Streams is a protocol for persistent, addressable append-only streams over HTTP. It takes care of the low-level details for reading and writing to streams. The key feature is resumable catch-up and live reads over SSE. Reading from a stored offset handles both scenarios with the same protocol. The combination of append-only streams with resumable reads is useful in a surprising number of applications (durable LLM responses, chat logs, event sourcing, etc.), and is all we need to build a sync protocol.

Durable State: the contents of the stream A byte stream is not yet a sync protocol. The client needs to know whether a message inserts, updates, or deletes an item, and which local collection owns it.

Durable State supplies that collection-change vocabulary. An illustrative change might look like this: Where:

type

selects a collection;key

identifies an entity in that collection;operation

is insert, update, or delete;value

is the new entity value when applicable;txid

can correlate all changes produced by one accepted mutation.

A single ordered stream can contain several entity types. type + key

is enough to route each change into the correct local record.

Putting it all together On the client, we need to synchronise local TanStack DB collections with the remote state. We could write our own sync adapter by providing a sync

function:

However, the wonderful folks behind Durable Streams have already done this for us with StreamDB. We simply need to provide a schema and the URL of our Durable State stream.

The client schema

describes the same task collection and entity shape that the server registers below.

On the server, we need a Durable Streams server implementation — for example Streamsy, or any other implementation. With Streamsy it looks like this:

This uses the in-memory adapter for brevity; swap in Streamsy's @streamsy/storage-sqlite

adapter for a real deployment.

Ch-ch-ch-ch-changes The astute reader will have noticed that we have not yet discussed how server-side state is updated. The hand-wavy answer is that we append the same Durable State insert, update, and delete messages used to synchronise the client. How those messages are generated is up to the application: we might write them directly through a mutation API, or treat Durable State as a projection of another source of truth, such as a publication stream from a relational database. There is lots more to explore here in future articles.

Conclusion Three easy pieces connected with a few lines of code are all it takes to get started building sync-based applications. There are many more details to consider, and many possible architectures we can build on top, but these three pieces give us a solid foundation.

── more in #developer-tools 4 stories · sorted by recency
── more on @tanstack db 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/super-simple-sync-wi…] indexed:0 read:3min 2026-07-28 ·