Evolu - React Hooks for Local-First Apps

React Hooks library for local-first apps (opens in a new tab) with end-to-end encrypted backup and sync using SQLite (opens in a new tab) and CRDT (opens in a new tab).


Evolu is designed for privacy, ease of use, and no vendor lock-in.

Local-first apps allow users to own their data. Evolu stores data in the user's device(s), so Evolu apps can work offline and without a specific server. Evolu Server

Evolu merges data changes made on different devices without conflicts using Conflict-free Replicated Data Type (CRDT). How Evolu Works

Getting Started · GitHub Repository (opens in a new tab) · Twitter (opens in a new tab)


import { pipe } from "@effect/data/Function";
import * as S from "@effect/schema/Schema";
import * as E from "evolu";
const TodoId = E.id("Todo");
type TodoId = S.Infer<typeof TodoId>;
const NonEmptyString50 = pipe(
type NonEmptyString50 = S.Infer<typeof NonEmptyString50>;
const TodoTable = S.struct({
  id: TodoId,
  title: NonEmptyString50,
  description: S.nullable(E.NonEmptyString1000),
  isCompleted: E.SqliteBoolean,
type TodoTable = S.Infer<typeof TodoTable>;
const Database = S.struct({
  todo: TodoTable,
const { useQuery, useMutation } = E.createHooks(Database);
const { rows, isLoaded } = useQuery(
  (db) =>
    // A type-safe SQL query builder.
    db.selectFrom("todo").select(["id", "title"]).orderBy("createdAt"),
  // The filterMap helper for ad-hoc schema migrations.
  (row) => row
const { create, update } = useMutation();
if (!S.is(NonEmptyString50)(title)) return;
const { id } = create("todo", { title, isCompleted: false });
update("todo", { id, isCompleted: true }, onComplete);


  • The official SQLite Wasm in all browsers (React Native and Electron soon)
  • E2E encrypted sync and backup with CRDT (merging changes without conflicts)
  • Free Evolu server for testing (paid production-ready soon, or you can run your own)
  • Typed database schema with branded types (NonEmptyString1000, PositiveInt)
  • Reactive queries
  • Real-time experience via revalidation on focus and network recovery
  • Schema evolving via filterMap ad-hoc migration
  • No signup/login, no email collection, only Bitcoin-like mnemonic (12 words)
  • React Suspense (soon)


The Evolu community is on GitHub Discussions (opens in a new tab). To chat with other community members, you can join the Evolu Discord (opens in a new tab).