React Native

Zero has built-in support for React Native and Expo.

Usage is identical to React on the web, except you must provide the Expo implementation of Zero's kvStore interface:

import type { ZeroOptions } from "@rocicorp/zero";
import { ZeroProvider } from "@rocicorp/zero/react";
import { expoSQLiteStoreProvider } from "@rocicorp/zero/expo-sqlite";
import {type Schema} from './schema.ts';
import {type Mutators} from './mutators.ts';

// on web, we use the browser's IndexedDB
const kvStore = Platform.OS === "web" ?
    undefined : expoSQLiteStoreProvider();

export default function RootLayout() {
  const zeroProps = useMemo(() => {
    return {
      kvStore,
      server: "http://localhost:4848",
      schema,
      mutators: createMutators(authData),
    } as const satisfies ZeroOptions<Schema, Mutators>;
  }, []);

  return (
    <ZeroProvider {...zeroProps}>
      <SafeAreaProvider>
        <App />
      </SafeAreaProvider>
    </ZeroProvider>
  );
}

For a complete example, see zslack.

OP-SQLite

Zero includes support for using the op-sqlite bindings to SQLite:

import { opSQLiteStoreProvider } from "@rocicorp/zero/op-sqlite";

export default function RootLayout() {
  const zeroProps = useMemo(() => {
    return {
      kvStore: opSQLiteStoreProvider(),
      // ...
    } as const satisfies ZeroOptions<Schema, Mutators>;
  }, []);

  return (
    <ZeroProvider {...zeroProps}>
      <SafeAreaProvider>
        <App />
      </SafeAreaProvider>
    </ZeroProvider>
  );
}

This is much faster than using expo-sqlite, but it doesn't work with Expo Go.