API reference@evolu/commonlocal‑first/Evolu › EvoluConfig

Defined in: packages/common/src/local-first/Evolu.ts:81

Properties

appName

readonly appName: string & Brand<"UrlSafeString"> & Brand<"AppName">;

Defined in: packages/common/src/local-first/Evolu.ts:99

The app name. Evolu is multitenant - it can run multiple instances concurrently. The same app can have multiple instances for different accounts.

Evolu derives the final instance name from appName and appOwner in EvoluConfig. The derived instance name is used as the SQLite database filename and as the log prefix. This ensures that each Owner gets a separate local database while preserving a readable app prefix.

Example

// appName: AppName.orThrow("MyApp")

appOwner

readonly appOwner: AppOwner;

Defined in: packages/common/src/local-first/Evolu.ts:122

AppOwner used to create this Evolu instance.

Exposed as Evolu.appOwner. If appOwner is not passed, Evolu creates one.

AppOwner controls access to the encrypted local SQLite database. If its secret material (Owner secret / Mnemonic) is not stored safely, data written by that instance is permanently inaccessible.

Best onboarding UX is accountless first use: let users try a ready-to-use app, then prompt backup of evolu.appOwner.

Recommended usage:

  • Omit appOwner for first run, then persist evolu.appOwner after user activity and guide the user to back it up.
  • Pass appOwner restored from secure storage (for example, Expo SecureStore, WebAuthn-backed storage, or app-managed account recovery flow).

indexes?

readonly optional indexes?: IndexesConfig;

Defined in: packages/common/src/local-first/Evolu.ts:217

Use the indexes option to define SQLite indexes.

Table and column names are not typed because Kysely doesn't support it.

https://medium.com/@JasonWyatt/squeezing-performance-from-sqlite-indexes-indexes-c4e175f3c346

Example

const evolu = createEvolu(evoluReactDeps)(Schema, {
  indexes: (create) => [
    create("todoCreatedAt").on("todo").column("createdAt"),
    create("todoCategoryCreatedAt").on("todoCategory").column("createdAt"),
  ],
});

memoryOnly?

readonly optional memoryOnly?: boolean;

Defined in: packages/common/src/local-first/Evolu.ts:195

Keep local data only in memory instead of persisting it on this device. Useful for testing, temporary data, or sensitive data that should not be recoverable from local storage after the process ends.

Local data stored in memory is completely destroyed when the process ends. Sync can still persist data remotely when transports are enabled.

The default value is: false.


onDatabaseDeleted?

readonly optional onDatabaseDeleted?: () => void;

Defined in: packages/common/src/local-first/Evolu.ts:225

Called when this instance's local database is deleted.

Apps can use this to update UI immediately because the corresponding Evolu instance becomes unusable after local database deletion.

onOwnerDeleted?

readonly optional onOwnerDeleted?: (owner: Owner) => void;

Defined in: packages/common/src/local-first/Evolu.ts:233

Called when local data for an Owner is deleted.

Apps can use this to update UI immediately because that owner stops being used across tabs and instances.

transports?

readonly optional transports?: readonly OwnerWebSocketTransport[];

Defined in: packages/common/src/local-first/Evolu.ts:183

Transport configuration for sync and backup.

If not specified, Evolu uses the default Evolu relay. Pass one or more transports to override it with your own relays. Pass an empty array to disable sync, which is useful when sync should be configured later.

Empty transports start the instance without sync. In that case, Evolu.useOwner must be called with explicit non-empty transports to enable sync for any Owner, including the AppOwner.

Redundancy: The ideal setup uses at least two completely independent relays - for example, a home relay and a geographically separate relay. Data is sent to both relays simultaneously, providing true redundancy similar to using two independent clouds. This eliminates vendor lock-in and ensures your app continues working regardless of circumstances - whether home relay hardware fails or disappears, or a remote relay provider shuts down.

Currently supports:

  • WebSocket: Real-time bidirectional communication with relay servers

Use createOwnerWebSocketTransport to create WebSocket transport configurations with proper URL formatting and OwnerId inclusion. The OwnerId in the URL enables relay authentication, allowing relay servers to control access (e.g., for paid tiers or private instances).

The default value is:

{ type: "WebSocket", url: "wss://free.evoluhq.com" }.

Example

// Single WebSocket relay
transports: [{ type: "WebSocket", url: "wss://relay1.example.com" }];

// Multiple WebSocket relays for redundancy
transports: [
  { type: "WebSocket", url: "wss://relay1.example.com" },
  { type: "WebSocket", url: "wss://relay2.example.com" },
  { type: "WebSocket", url: "wss://relay3.example.com" },
];

// Local-only instance (no sync) - useful for device settings or when relay
// URL will be provided later (e.g., after authentication), allowing users
// to work offline before the app connects
transports: [];

// Using createOwnerWebSocketTransport helper for relay authentication
transports: [
  createOwnerWebSocketTransport({
    url: "ws://localhost:4000",
    ownerId,
  }),
];