Evolu Documentation

repository·main·Indexed 23 days ago

https://github.com/evoluhq/evolu

A TypeScript library and local-first platform for building responsive, data-driven applications. The ecosystem includes @evolu/common for core functionality, @evolu/nodejs for server integrations, and dedicated packages for React Web, React Native, Svelte, and universal React environments. It features Evolu Relay for deployment via Docker or Node.js and provides integration patterns for frameworks like Angular, Next.js, and Vue 3.

Tokens
46.5K
Snippets
98
Records
247
Agent score
84%

What's inside Evolu

  1. Overview of @evolu/common

    main
    The @evolu/common package provides the platform-independent core functionality for the Evolu ecosystem. It is designed to work consistently across all supported platforms (Web, React Native, Node.js, etc.), serving as the foundational layer for Evolu applications.
  2. Use Evolu for React Web

    main
    The @evolu/react-web package is designed for building Evolu applications on the web platform using React. It acts as a wrapper around @evolu/web, re-exporting all its functionality while adding React-specific components and hooks to facilitate seamless integration with the React ecosystem.
  3. Use @evolu/react for universal React functionality

    main
    The @evolu/react package provides universal React functionality for Evolu. It is designed to work across various React environments, but note that it is not intended for React Native or React Web specifically; those environments have their own dedicated packages (@evolu/react-native and @evolu/react-web). Use this package when building for general React environments that do not fall into those two categories.
  4. Choose between the Evolu TypeScript library and the Local-first platform

    main

    Evolu offers two distinct ways to build applications depending on your needs:

    1. TypeScript library: Use this if you want to write scalable TypeScript code using proven design patterns like Result, dependency injection, structured concurrency, and immutability. It is designed to be simple and idiomatic TypeScript without heavy functional programming abstractions (like pipes or black-box abstractions).

    2. Local-first platform: Use this if you want to build applications where users own their data. This path provides an offline-first experience with synchronization via self-hosted or cloud relays. It is end-to-end encrypted by default and built on SQLite with a scalable sync protocol.

  5. Use Evolu for the Web platform

    main
    The @evolu/web package (referred to as Evolu for Web) is designed for use within web browsers and provides access to standard W3C web platform APIs. For comprehensive documentation, detailed usage examples, and advanced implementation guides, visit the official website at evolu.dev.
  6. What is Evolu Relay and how should it be used?

    main

    Evolu Relay provides synchronization and backup services for Evolu applications. To ensure high availability and resilience, it is recommended to use a multi-relay architecture:

    1. Primary Relay: A fast, low-latency relay (e.g., on-premises or geographically close to users) for daily operations.
    2. Secondary Relay: A geographically distant relay to act as a fallback in case of primary relay hardware or network failures.

    Evolu apps can combine self-hosted relays with cloud-provided relays. Because Evolu Relay is stateless, it is compatible with serverless environments such as AWS Lambda or Cloudflare Workers.

  7. Overview of the Evolu Protocol

    main

    The Evolu Protocol is a local-first, end-to-end encrypted binary synchronization protocol. It is optimized for minimal size and maximum speed, enabling data sync between clients and relays, or in peer-to-peer (P2P) setups.

    Key characteristics:

    • Binary Format: Uses structure-aware encoding instead of JSON to improve compression of encrypted data and speed up sequential byte reading.
    • Range-Based Set Reconciliation (RBSR): Implements RBSR to efficiently synchronize data sets.
    • Optimized Encoding: Uses Delta encoding for timestamps and Run-length encoding (RLE) for Counter and NodeId to minimize message size.
    • Scalable Sync Strategies: Switches between sending full timestamp data and sending compact fingerprints (summaries) depending on the number of timestamps to reconcile.
  8. Enforce lifetime correctness with `assertNotDisposed`

    main

    To prevent programmer errors like using an object after it has been disposed, use assertNotDisposed guards. This is especially useful when a helper manages internal state (like a reference counter) rather than an external resource.

    In Evolu, it is a convention to call assertNotDisposed(disposables) inside synchronous methods of a returned object to ensure the underlying DisposableStack is still active. For async operations, if an operation is aborted due to disposal, use assertNotAborted to distinguish lifecycle-related aborts from ordinary control flow.

    const createRefCount = (): RefCount => {
      using disposer = new DisposableStack();
      let count = 0;
      const disposables = disposer.move();
    
      return {
        increment: () => {
          assertNotDisposed(disposables);
          count += 1;
          return count;
        },
    
        getCount: () => {
          assertNotDisposed(disposables);
          return count;
        },
    
        [Symbol.dispose]: () => disposables.dispose(),
      };
    };