ReadyNative

Apollo Client

Set up Apollo Client for data in an Expo app with ReadyNative: GraphQL client + normalized cache · Expo Go OK

Expo Go: yes

Runs in Expo Go; no dev build needed for this module.

Apollo Client 4 is the GraphQL data layer, wired up in src/lib/apollo.tsx. I'd pick it when your backend speaks GraphQL - you get a normalised InMemoryCache, useQuery / useMutation and a cache-and-network default - and I'd stay on react-query or swr for REST. Refetch-on-foreground is already handled: the client uses Apollo 4.3's RefetchEventManager with the windowFocus source swapped for an AppState observable, so every active query refetches when the app comes back unless it sets refetchOn: false.

Setup

bun run setup --data apollo
  1. Put your GraphQL endpoint in .env as EXPO_PUBLIC_GRAPHQL_URL, for example https://countries.trevorblades.com/graphql. It's optional - the example query is skipped until you set it.
  2. For an authenticated API, add an ApolloLink (@apollo/client/link/context) inside createApolloClient in src/lib/apollo.tsx.

Setup installs @apollo/client ^4.3, graphql ^16 and rxjs ^7.8 (a required peer of v4), and adds src/lib/apollo.tsx (apolloClient plus ApolloProvider at order 20), and a MockedProvider test, plus src/hooks/use-example-query.ts and the /examples/query route and screen with --with-examples.

KeyRequiredWhat it is
EXPO_PUBLIC_GRAPHQL_URLnoThe HttpLink endpoint

Usage

In Apollo 4 the React hooks live in @apollo/client/react and the core in @apollo/client:

import { gql } from "@apollo/client";
import { useQuery } from "@apollo/client/react";

const ME = gql`
  query Me {
    me {
      id
      name
    }
  }
`;

const { data, loading, error, refetch } = useQuery(ME);

Mutations use useMutation from the same entry point. With --with-examples, src/hooks/use-example-query.ts shows the typed shape with a TypedDocumentNode.

For readable error messages in development, import loadDevMessages and loadErrorMessages from @apollo/client/dev and call both in src/lib/apollo.tsx behind __DEV__.

Gotchas

  • Expo Go works - it's pure JS, and Metro's package-exports resolution (SDK 53+) handles the v4 entry points.
  • On every sign-out and account deletion wipeLocalData() runs the onWipeLocalData hooks, and src/lib/apollo.tsx registers apolloClient.clearStore() there, so the next user never sees the previous user's cached responses.
  • InMemoryCache is lost on restart. To persist it, add apollo3-cache-persist (it works with v4) and await persistCache({ cache, storage }) before rendering, using the adapter from @/lib/storage.
  • The online refetch source is Apollo's default (the browser online event, a no-op on native). For offline-aware refetches add @react-native-community/netinfo and pass an online source to RefetchEventManager; @apollo/client/link/retry covers transient failures.
  • No codegen is wired - the example hand-types its TypedDocumentNode. Add @graphql-codegen/cli if you want schema-derived types.
  • Swapping stacks: bun run setup --data none (or --data react-query / --data swr) removes the files, deps, provider and env key, and with the examples, /examples/query falls back to the core "Module not installed" screen.

Remove it

While modules/ exists (a tree set up with --keep-modules), setup does all of it:

bun run setup --data none --yes --keep-modules

In a finalized tree setup is a stub, so you undo it by hand. Here is everything this module added:

  1. Delete the files that are still there (the demo screens are gone already unless you set up with --with-examples): src/app/examples/query.tsx, src/hooks/__tests__/use-example-query.test.tsx, src/hooks/use-example-query.ts, src/lib/apollo.tsx, src/screens/examples/query-example-screen.tsx.
  2. Replace, don't delete src/hooks/use-forecast.ts: core code imports it, so swap in the no-op version from modules/data/none/files/ of a fresh clone of your tier repo - same exports, nothing behind them.
  3. Uninstall the dependencies: bun remove @apollo/client graphql rxjs.
  4. Unwrap the provider: delete <ApolloProvider> and its import from src/providers.tsx.
  5. Remove the env keys EXPO_PUBLIC_GRAPHQL_URL from .env, .env.example and your EAS environment, and EXPO_PUBLIC_GRAPHQL_URL from src/lib/env.ts.
  6. Check it: bun run typecheck and bun run lint point at anything that still imports the removed files; bun run gen:graph refreshes docs/ARCHITECTURE.md.

Reference

Everything below is generated from modules/data/apollo/module.json - the same file bun run setup reads, so it is what actually lands in your repo.

Install

bun run setup --data apollo

Module id: data/apollo.

Dependencies

PackageVersionKind
@apollo/client^4.3.0dependency
graphql^16.14.2dependency
rxjs^7.8.2dependency

Environment keys

KeyRequiredServer-onlyExampleDocs
EXPO_PUBLIC_GRAPHQL_URLnonohttps://countries.trevorblades.com/graphql-

Keys go in .env (see .env.example). Required keys are checked by bun run doctor; Server-only keys have no EXPO_PUBLIC_ prefix, are read only by API routes and never reach the bundle.

Providers

Rendered in src/providers.tsx (lower order = outermost):

OrderProviderFrom
20ApolloProvider@/lib/apollo

Files

6 files copied to the project root
  • src/app/examples/query.tsx
  • src/hooks/__tests__/use-example-query.test.tsx
  • src/hooks/use-example-query.ts
  • src/hooks/use-forecast.ts
  • src/lib/apollo.tsx
  • src/screens/examples/query-example-screen.tsx

On this page

Get ReadyNative