Skip to main content
LiveStore is a next-generation state management framework for building complex, client-centric applications. It replaces traditional state management libraries like Redux or Zustand with a powerful combination of reactive SQLite, event sourcing, and built-in real-time sync.

Introduction

Learn what LiveStore is and how it works

Quick Start (React)

Get a React app running with LiveStore in minutes

Core Concepts

Understand schemas, events, materializers, and the store

API Reference

Explore the full API surface

Why LiveStore?

LiveStore unifies state management, persistence, and sync into a single, principled model based on event sourcing. Instead of mutating state directly, you commit immutable events that are materialized into a local SQLite database and automatically synced across all connected clients.

Reactive SQLite

Query your data with full SQL support. Results update automatically when the underlying data changes — no loading states, no manual cache invalidation.

Built-in Sync

Events sync across clients via a push/pull model inspired by Git. Works offline automatically and reconciles state when connectivity returns.

Event Sourcing

Every change is captured as an immutable event. Replay, debug, undo, and audit your entire application history with ease.

Get started

1

Install LiveStore

Add the core package and the adapter for your platform.
npm install @livestore/livestore @livestore/adapter-web @livestore/react
2

Define your schema

Declare events, SQLite tables, and the materializers that connect them.
schema.ts
import { Events, makeSchema, Schema, State } from '@livestore/livestore'

const tables = {
  todos: State.SQLite.table({
    name: 'todos',
    columns: {
      id: State.SQLite.text({ primaryKey: true }),
      text: State.SQLite.text({ default: '' }),
      completed: State.SQLite.boolean({ default: false }),
    },
  }),
}

const events = {
  todoCreated: Events.synced({
    name: 'v1.TodoCreated',
    schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
  }),
}

const materializers = State.SQLite.materializers(events, {
  'v1.TodoCreated': ({ id, text }) => tables.todos.insert({ id, text }),
})

export const schema = makeSchema({ events, state: State.SQLite.makeState({ tables, materializers }) })
3

Create the store and query data

Set up the store in your framework integration and start querying reactively.
App.tsx
import { queryDb } from '@livestore/livestore'
import { useStore } from '@livestore/react'
import { schema, tables } from './schema'

const todos$ = queryDb(() => tables.todos, { label: 'todos' })

function TodoApp() {
  const store = useStore({ storeId: 'my-app', schema, adapter, batchUpdates })
  const todos = store.useQuery(todos$)
  return (
    <ul>
      {todos.map(todo => <li key={todo.id}>{todo.text}</li>)}
    </ul>
  )
}
4

Add sync (optional)

Connect a Cloudflare sync backend to distribute state across clients in real time.
src/livestore.worker.ts
import { makeWorker } from '@livestore/adapter-web/worker'
import { makeWsSync } from '@livestore/sync-cf/client'
import { schema } from './schema'

makeWorker({
  schema,
  sync: { backend: makeWsSync({ url: `${location.origin}/sync` }) },
})

Explore by platform

React Web

Set up LiveStore in a React application with the web adapter

Expo (React Native)

Build offline-first mobile apps with the Expo adapter

Node.js

Use LiveStore in server-side and CLI applications

Vue

Integrate LiveStore into Vue 3 applications

Build docs developers (and LLMs) love