Evolu - Local-First Platform

Local-first (opens in a new tab) apps allow users to own their data. Evolu stores data in the user's device(s), so Evolu apps can work offline. Evolu merges data changes made on different devices without conflicts using Conflict-free Replicated Data Type (CRDT). How Evolu Works

ℹ️

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

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

Overview

import * as Schema from "@effect/schema/Schema";
import * as Evolu from "@evolu/react";
 
const TodoId = Evolu.id("Todo");
type TodoId = Schema.Schema.To<typeof TodoId>;
 
const NonEmptyString50 = Evolu.String.pipe(
  Schema.minLength(1),
  Schema.maxLength(50),
  Schema.brand("NonEmptyString50"),
);
type NonEmptyString50 = Schema.Schema.To<typeof NonEmptyString50>;
 
const TodoTable = Schema.struct({
  id: TodoId,
  title: NonEmptyString50,
  description: Schema.nullable(Evolu.NonEmptyString1000),
  isCompleted: Evolu.SqliteBoolean,
});
type TodoTable = Schema.Schema.To<typeof TodoTable>;
 
const Database = Schema.struct({
  todo: TodoTable,
});
 
const { useQuery, useMutation } = Evolu.create(Database);
 
const { rows } = 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 (!Schema.is(NonEmptyString50)(title)) return;
const { id } = create("todo", { title, isCompleted: false });
 
update("todo", { id, isCompleted: true }, onComplete);

Features

  • SQLite in all browsers, Electron, and React Native
  • 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 with React Suspense support
  • 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)
  • Fetching nested objects and arrays in a single SQL query
  • JSON support with automatic parsing and stringifying

Community

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).