Local-first is alive and strong 💪🏻
I was in Berlin last week for localfirstconf.
On my way to Berlin for @localfirstconf ✈️ Expecting a lot from the conferences for local-first ⚡️ @livestoredev 👀 Zero sync 🪄 @tan_stack DB Stay tuned for more updates 🔛
Here are my personal top 3 picks from the conference 👇
Universal Version Control
The main theme of the conference was sync ⚡️
Everyone is into making or learning about sync engines. I am as well (I implemented my own 💁🏼♂️).
The original promise of sync engines was to solve all conflicts for you, and come up with a consistent state for all clients.
But, turns out that's not ideal UX 🤔
This is the analogy shared by Aaron Boodman at the conference:
You and a friend decide to remotely collaborate on an essay about cats.
You go offline and keep writing, but suddenly decide to change the subject to dogs.
Meanwhile, your friend keeps writing about cats.
When you come back online, how should the sync engine merge conflicts? 🤔
Answer: it (mostly) can't 🤷🏼♂️
And if it does, the result is usually a disaster:
- You lose all your dogs content
- Your friend loses all your cats content
- The sync engine mixes stuff and comes up with a mess
Alas, completely automatic merges are not ideal in most cases for UX 😬
Instead, the solution may be something closer to git: Version Control.
That's what Ink & Switch proposes with Universal Version Control:
"We want to research universal version control tools that work for everything and everyone."
Instead of automatic sync, your software keeps track of the history, and allows the user to merge changes manually. Not only for text (like git), but in any context 🙌
I think this idea will develop and become more prominent soon 🔜
TanStack DB
Reactivity is one of the major DX improvements for state management on the client.
TanStack brings reactivity a step further with TanStack DB:
"A reactive client store for building super fast apps on sync."
It's an extension of TanStack Query to allow local-syncing/live-queries, like this:
import { useLiveQuery } from "@tanstack/react-db"
const Todos = () => {
const { data: todos } = useLiveQuery((query) =>
query.from({ todoCollection }).where("@completed", "=", false)
)
return <List items={todos} />
}
Live queries in general are the next generation of state management on the client. TanStack DB made the first "mainstream" step towards this vision.
It a similar idea to
useLiveQuery
from Dexie, which I use extensively already 👀
LiveStore
LiveStore has been cooking for a while behind the curtains, and now it's live and open source:
After 4 years of development, LiveStore is now open-source. github.com/livestorejs/li…
I had the chance to get access before this official release and try it out:
- Define tables (local SQLite)
- Define events
- Define materializers (how events are applied to tables)
Events are the most accurate representation of state. Everything else is a lossy abstraction. LiveStore gets it right ⚡️
All the syncing complexity is hidden from you behind an event sourcing system.
"How LiveStore is using the event-sourcing architecture as the foundation for its sync engine" @schickling shared his insights from building @livestoredev along with announcing that it is now open source 🚀🥳
You will definitely hear more about LiveStore 🔜
A lot of progress since last year, but still a lot of research and experiments work in progress 🙌
Meanwhile, quick reminder that my Effect Days 2025 talk is out on Youtube:
See you next 👋