{"slug": "super-simple-sync-with-durable-state-and-tanstack-db", "title": "Super Simple Sync with Durable State and TanStack DB", "summary": "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.", "body_md": "[Super Simple Sync with Durable State and TanStack DB](#super-simple-sync-with-durable-state-and-tanstack-db)\n\nSync engines are taking off. In 2026 you are spoiled for choice: [Zero](https://zero.rocicorp.dev), [Electric](https://electric-sql.com), [PowerSync](https://www.powersync.com), and [LiveStore](https://livestore.dev), 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\n\nFirst, let's quickly review what we mean by a sync engine. There are really two ways to look at it:\n\n- 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.\n- From the user perspective, a sync engine provides a local-first experience, with instantaneous loads and real-time updates.\n\n[The three pieces](#the-three-pieces)\n\n[TanStack DB: the local database](#tanstack-db-the-local-database)\n\nThe easiest way to think about [TanStack DB](https://tanstack.com/db/latest) is that it solves the client-side part of the sync engine. It gives us:\n\n- typed local collections;\n- live, reactive queries;\n- optimistic mutations;\n- one local place to merge confirmed server changes.\n\nThe 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.\n\n[Durable Streams: the transport](#durable-streams-the-transport)\n\n[Durable Streams](https://durablestreams.com) 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.\n\n[Durable State: the contents of the stream](#durable-state-the-contents-of-the-stream)\n\nA 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.\n\n[Durable State](/docs/user/durable-state) supplies that collection-change vocabulary. An illustrative change might look like this:\n\nWhere:\n\n`type`\n\nselects a collection;`key`\n\nidentifies an entity in that collection;`operation`\n\nis insert, update, or delete;`value`\n\nis the new entity value when applicable;`txid`\n\ncan correlate all changes produced by one accepted mutation.\n\nA single ordered stream can contain several entity types. `type + key`\n\nis enough to route each change into the correct local record.\n\n[Putting it all together](#putting-it-all-together)\n\nOn the client, we need to synchronise local TanStack DB collections with the remote state. We could [write our own sync adapter](https://tanstack.com/db/latest/docs/guides/collection-options-creator#2-sync-implementation) by providing a `sync`\n\nfunction:\n\nHowever, the wonderful folks behind Durable Streams have already done this for us with [StreamDB](https://durablestreams.com/stream-db). We simply need to provide a schema and the URL of our Durable State stream.\n\nThe client `schema`\n\ndescribes the same task collection and entity shape that the server registers below.\n\nOn the server, we need a Durable Streams server implementation — for example [Streamsy](https://github.com/gingerhendrix/streamsy), or [any other implementation](https://github.com/durable-streams/durable-streams#servers--tools). With Streamsy it looks like this:\n\nThis uses the in-memory adapter for brevity; swap in Streamsy's `@streamsy/storage-sqlite`\n\nadapter for a real deployment.\n\n[Ch-ch-ch-ch-changes](#ch-ch-ch-ch-changes)\n\nThe 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.\n\n[Conclusion](#conclusion)\n\nThree 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.", "url": "https://wpnews.pro/news/super-simple-sync-with-durable-state-and-tanstack-db", "canonical_source": "https://streamsy.gandrew.com/articles/the-simplest-possible-sync-engine", "published_at": "2026-07-28 10:09:33+00:00", "updated_at": "2026-07-28 10:23:30.847536+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["TanStack DB", "Durable Streams", "StreamDB", "Streamsy", "ElectricSQL", "Durable State"], "alternates": {"html": "https://wpnews.pro/news/super-simple-sync-with-durable-state-and-tanstack-db", "markdown": "https://wpnews.pro/news/super-simple-sync-with-durable-state-and-tanstack-db.md", "text": "https://wpnews.pro/news/super-simple-sync-with-durable-state-and-tanstack-db.txt", "jsonld": "https://wpnews.pro/news/super-simple-sync-with-durable-state-and-tanstack-db.jsonld"}}