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- Put your GraphQL endpoint in
.envasEXPO_PUBLIC_GRAPHQL_URL, for examplehttps://countries.trevorblades.com/graphql. It's optional - the example query is skipped until you set it. - For an authenticated API, add an
ApolloLink(@apollo/client/link/context) insidecreateApolloClientinsrc/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.
| Key | Required | What it is |
|---|---|---|
EXPO_PUBLIC_GRAPHQL_URL | no | The 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 theonWipeLocalDatahooks, andsrc/lib/apollo.tsxregistersapolloClient.clearStore()there, so the next user never sees the previous user's cached responses. InMemoryCacheis lost on restart. To persist it, addapollo3-cache-persist(it works with v4) andawait persistCache({ cache, storage })before rendering, using the adapter from@/lib/storage.- The
onlinerefetch source is Apollo's default (the browseronlineevent, a no-op on native). For offline-aware refetches add@react-native-community/netinfoand pass anonlinesource toRefetchEventManager;@apollo/client/link/retrycovers transient failures. - No codegen is wired - the example hand-types its
TypedDocumentNode. Add@graphql-codegen/cliif 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/queryfalls 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-modulesIn a finalized tree setup is a stub, so you undo it by hand. Here is everything this module added:
- 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. - Replace, don't delete
src/hooks/use-forecast.ts: core code imports it, so swap in the no-op version frommodules/data/none/files/of a fresh clone of your tier repo - same exports, nothing behind them. - Uninstall the dependencies:
bun remove @apollo/client graphql rxjs. - Unwrap the provider: delete
<ApolloProvider>and its import fromsrc/providers.tsx. - Remove the env keys
EXPO_PUBLIC_GRAPHQL_URLfrom.env,.env.exampleand your EAS environment, andEXPO_PUBLIC_GRAPHQL_URLfromsrc/lib/env.ts. - Check it:
bun run typecheckandbun run lintpoint at anything that still imports the removed files;bun run gen:graphrefreshesdocs/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 apolloModule id: data/apollo.
Dependencies
| Package | Version | Kind |
|---|---|---|
@apollo/client | ^4.3.0 | dependency |
graphql | ^16.14.2 | dependency |
rxjs | ^7.8.2 | dependency |
Environment keys
| Key | Required | Server-only | Example | Docs |
|---|---|---|---|---|
EXPO_PUBLIC_GRAPHQL_URL | no | no | https://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):
| Order | Provider | From |
|---|---|---|
| 20 | ApolloProvider | @/lib/apollo |
Files
6 files copied to the project root
src/app/examples/query.tsxsrc/hooks/__tests__/use-example-query.test.tsxsrc/hooks/use-example-query.tssrc/hooks/use-forecast.tssrc/lib/apollo.tsxsrc/screens/examples/query-example-screen.tsx