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

Strata Sync

ElectricSQL

Local storage

Built-in (IndexedDB)
Bring your own

Conflict resolution

Automatic, field-level
Bring your own

Real-time editing

Rich-text with Yjs
Not included

Offline writes

Full offline support
Bring your own

Undo and redo

Built-in
Not included

What you can build

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

Device A
Offline
Device B
Offline

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.