This starter wires network state, the shared transport, a mutation queue + replay, and TanStack Query persistence (MMKV). Together they provide practical offline behavior; they are not a full offline-first product by default.
-
NetInfo (
src/shared/services/api/network/netinfo.ts) — If@react-native-community/netinfois installed, the app subscribes to connectivity and sets transport offline mode viasetOfflineMode(). When the device goes from offline → online,syncEngine.onConnected()runs to replay queued mutations. -
Transport (
src/shared/services/api/transport/transport.ts) — While offline:- Queries throw an error with code
NETWORK_OFFLINE(no live fetch through the adapter). - Mutations and uploads are pushed to the offline queue and resolve with a queued result instead of calling the adapter.
- Subscriptions silently return a no-op unsubscribe — not queued, no error thrown.
- Queries throw an error with code
-
Offline queue (
src/shared/services/api/offline/offline-queue.ts) — FIFO, in-memory only. Queued work is lost if the process is killed while offline. For production durability, replace or back this with MMKV/SQLite (see comments in that file). -
Sync engine (
src/shared/services/api/offline/sync-engine.ts) — Replays queued mutations via the transport when back online, removes successful items, and can invalidate React Query caches using tags on queued items. Replay stops on the first failure to avoid cascading errors. -
React Query + MMKV (
src/shared/services/api/query/client/provider.tsx,mmkv-persister,persistence/limits) — Previously fetched query data can be dehydrated to MMKV under a policy (sensitive queries excluded, freshness/TTL rules). That is the main way reads still have data offline or after a cold start—not the snapshotcache-enginebelow. -
cache-engine (
src/shared/services/storage/cache-engine.ts) — Optional in-memory key/value snapshots for services; not persisted. Logout clears it alongside the offline queue.
createQueryClient suppresses retries and error toasts for both query and mutation errors when the normalized error code is NETWORK_OFFLINE, and enables refetchOnReconnect.
If NetInfo is not installed, initNetInfoBridge() is a no-op; you can still test offline using the dev helper __setOfflineForDev in netinfo.ts (development only).