The schema and the data should travel together. A local-first system shouldn't treat the schema as a centralized contract that every client must fetch separately from the data it describes.
What does it mean in practice?
Imagine a local-first application that stores a collection of tasks.
Traditionally, the application distributes these separately:
Schema: defines what a task is and how it is structured.
Data: contains actual tasks.
Application code: knows how to interpret the schema and render the data.
In a schema-coupled local-first design, a task could instead travel with the information needed to interpret it.
Why this matters for local-first systems
Offline autonomy: a device can interpret its local data without depending on a live central schema service.
Replication: when data moves between peers, the receiving system can discover how to interpret its structure.
Long-term ownership: users can retain and understand their data even after the original application disappears, provided the schema and required semantics remain available.
Independent evolution: different devices can encounter different schema versions and use explicit compatibility or migration rules.
Composability: applications can exchange data without requiring every application to have hard-coded knowledge of every data type.
The crucial distinction
Schema and data do not necessarily have to be serialized into the same file. They need to be bound together through identity, versioning, and dependency tracking.
For example, a record could reference an immutable schema identifier:
{
"schema": "task@3",
"id": "task-42",
"data": {
"title": "Explore local-first architecture",
"completed": false
}
}The schema can be stored elsewhere, as long as it is locally available or can travel with the record or collection. If the schema changes, the system must also define how older records remain interpretable.
This is particularly important in replicated systems: schema evolution is a coordination problem, not just a serialization problem.
The deeper architectural principle
I'd phrase your idea this way:
In local-first systems, data should carry its own structural context, and schema evolution should be part of the data's lifecycle.
That leads to an interesting question: should the schema be treated as merely a description of the data, or as a first-class piece of data itself—versioned, replicated, editable, and owned by the user?
The second approach can make the schema and the dataset evolve together without requiring a central authority to dictate their structure. It also means schema conflicts and migrations must be handled as part of the distributed system.
Do you like what you are reading? Subscribe to receive updates.
Unsubscribe anytime