Skip to main content

React Native

The Covara client makes no DOM assumptions, so the same client, repository, hooks, and subscriptions run in React Native. A few integration points differ from the browser.

Token storage

OIDC/JWT tokens are stored through a pluggable TokenStorage. In the browser the default is MemoryStorage (or LocalStorageAdapter); in React Native, provide an AsyncStorage-compatible adapter:

import AsyncStorage from "@react-native-async-storage/async-storage";
import { createClient } from "covara/client";

const asyncStorageAdapter = {
getItem: (key: string) => AsyncStorage.getItem(key),
setItem: (key: string, value: string) => AsyncStorage.setItem(key, value),
removeItem: (key: string) => AsyncStorage.removeItem(key),
};

const client = createClient({
baseUrl: "https://api.myapp.com",
auth: {
issuer: "https://auth.myapp.com/oidc",
clientId: "mobile-app",
redirectUri: "myapp://callback",
storage: asyncStorageAdapter, // satisfies TokenStorage
},
});

The same applies to useJWTAuth — pass an AsyncStorage-compatible storage.

Transport & offline backends

The transport and offline layers are environment-aware:

  • fetch and SSE work over React Native's networking.
  • For the offline queue, use InMemoryOfflineStorage or supply an AsyncStorage/SQLite-backed OfflineStorage implementation (the browser-only LocalStorageOfflineStorage/IndexedDBOfflineStorage aren't available natively).
  • offline.tabSync (BroadcastChannel) is a no-op outside the browser — leave it off.
import { createClient, InMemoryOfflineStorage } from "covara/client";

const client = createClient({
baseUrl: "https://api.myapp.com",
offline: { enabled: true, storage: new InMemoryOfflineStorage() }, // or your AsyncStorage-backed store
});

Files

There's no <img>/<a> — use getDownloadUrl(id) from useFiles (or the file client) to obtain a URL, then fetch the bytes with React Native's fetch/Image source:

const { getDownloadUrl } = useFiles({ resourcePath: "/api/files" });
<Image source={{ uri: getDownloadUrl(file.id) }} />;

Hooks

useLiveList, useMutation, useAuth, useJWTAuth, useFileUpload, and the billing hooks all work unchanged — they depend only on React, not the DOM.