Strata Sync - Local-first sync engine

2 min read Original article ↗

Apps that just work.

Inspired by Linear’s sync engine. Open-source.

npx skills add stratasync/stratasync

Most apps don’t just work

Strata Sync changes that

No more spinners

Your data lives on the device, ready the moment you open the app.

Works offline

Edits apply immediately and sync to the server when you reconnect.

Always in sync

Real-time updates across every device and tab. No refresh banners, no stale data.

How Strata Sync compares

What you can build

Tick off items and reorder lists instantly, even in aeroplane mode.

Get started in minutes

npx skills add stratasync/stratasync

1. Define your models · lib/sync/models.ts

import { ClientModel, Model, Property } from "@stratasync/core"

@ClientModel("Todo", { loadStrategy: "instant" })
class Todo extends Model {
  @Property() declare title: string
  @Property() declare completed: boolean
}

2. Create the client · lib/sync/client.ts

import { createSyncClient } from "@stratasync/client"
import { createMobXReactivity } from "@stratasync/mobx"
import { createIndexedDbStorage } from "@stratasync/storage-idb"
import { GraphQLTransportAdapter } from "@stratasync/transport-graphql"

const client = createSyncClient({
  storage: createIndexedDbStorage(),
  transport: new GraphQLTransportAdapter({
    endpoint: "/api/graphql",
    syncEndpoint: "/api/sync",
    wsEndpoint: "wss://api.example.com/sync/ws",
    auth: { getAccessToken: async () => "token" },
  }),
  reactivity: createMobXReactivity(),
})

3. Build reactive components · components/todo-list.tsx

import { observer } from "mobx-react-lite"
import { useQuery, useSyncClient } from "@stratasync/react"

const TodoList = observer(() => {
  const { data: todos } = useQuery("Todo", {
    where: (t) => !t.completed,
  })
  const { client } = useSyncClient()

  const addTodo = async () => {
    const todo = await client.create("Todo", {
      title: "New todo",
      completed: false,
    })
    todo.title = "Actually, a better title"
    await todo.save()
  }

  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>{todo.title}</li>
      ))}
      <button onClick={addTodo}>Add</button>
    </ul>
  )
})

View full examples on GitHub

Ready to build apps that just work?

Open-source. No vendor lock-in.