skill

Expo Data Fetching

Framework (OSS). Use when implementing or debugging ANY network request, API call, or data fetching. Covers fetch API, React Query, SWR, error handling, caching, offline support, loading/empty/error screen states, and Expo Router data loaders (`useLoaderData`).

Expo0+ installsVetted

About

# Expo Networking

**You MUST use this skill for ANY networking work including API requests, data fetching, caching, or network debugging.**

## References

Consult these resources as needed:

``` references/ expo-router-loaders.md Route-level data loading with Expo Router loaders (web, SDK 55+) offline-and-cancellation.md NetInfo network status, offline-first React Query, AbortController ```

## When to Use

Use this skill when:

- Implementing API requests - Setting up data fetching (React Query, SWR) - Using Expo Router data loaders (`useLoaderData`, web SDK 55+) - Debugging network failures - Implementing caching strategies - Handling offline scenarios - Authentication/token management - Configuring API URLs and environment variables

## Preferences

- Avoid axios, prefer expo/fetch

## Every Screen Has Four States

Design **loading**, **error**, **empty**, and **content** for screens that load data. These can overlap: a refresh error should coexist with cached content.

- **Loading ≠ empty.** Empty means *resolved with zero items*, not missing data. Handle initial loading, failure, and hydration before checking list length. In TanStack Query v5, `isLoading` means the first fetch is running; a disabled or offline-paused query can have no data without being loading. Show the prerequisite or offline state in that case. - **Empty is a designed state, not a blank list.** Use `ListEmptyComponent` on FlatList/FlashList: explain why it is empty and offer the relevant next action. "No items yet" can offer Create; "No results" should offer changing or clearing the search/filter. - **Refetches keep stale content.** Render cached `data` even if a refresh fails, with a nonblocking error and retry. Use `isLoading` for first-fetch spinners and `isFetching` for background activity; prefer a skeleton for a slow initial load with a known layout, and `RefreshControl` for user-initiated refresh. - **Gate on hydration.** When initial UI or a redirect depends on persisted state (auth token, onboarding flag), the root layout renders nothing - or the splash - until that state has loaded. Deciding on unhydrated state flashes the wrong screen on every cold start and misroutes deep links that arrive before hydration.

**Saves preserve work.** While a mutation is pending, disable repeat submission. On failure, retain the draft, show an inline error, and let the user retry; clear or dismiss only after success. If updating optimistically, restore the previous value or mark the edit as unsynced on failure. Verify with a failed save followed by retry.

## Common Issues & Solutions

### 1. Basic Fetch Usage

**Simple GET request**:

```tsx const fetchUser = async (userId: string) => { const response = await fetch(`https://api.example.com/users/${userId}`);

if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); }

return response.json(); }; ```

**POST request with body**:

```tsx const createUser = async (userData: UserData) => { const response = await fetch("https://api.example.com/users", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, body: JSON.stringify(userData), });

if (!response.ok) { const error = await response.json(); throw new Error(error.message); }

return response.json(); }; ```

---

### 2. React Query (TanStack Query)

**Setup**:

```tsx // app/_layout.tsx import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 1000 * 60 * 5, // 5 minutes retry: 2, }, }, });

export default function RootLayout() { return ( <QueryClientProvider client={queryClient}> <Stack /> </QueryClientProvider> ); } ```

**Fetching data**:

```tsx import { useQuery } from "@tanstack/react-query";

function UserProfile({ userId }: { userId: string }) { const { data, fetchStatus, error, refetch } = useQuery({ queryKey: ["user", userId], queryFn: () => fetchUser(userId), });

if (data === undefined) { if (error) return <ErrorState message={error.message} onRetry={() => refetch()} />; if (fetchStatus === "paused") return <OfflineState />; return <Loading />; }

return ( <> {error && <InlineError message="Could not refresh. Showing saved data." onRetry={() => refetch()} />} {data === null ? <EmptyState message="User not found" /> : <Profile user={data} />} </> ); } ```

**Mutations**:

```tsx import { useMutation, useQueryClient } from "@tanstack/react-query";

function CreateUserForm() { const queryClient = useQueryClient();

const mutation = useMutation({ mutationFn: createUser, onSuccess: () => { // Invalidate and refetch queryClient.invalidateQueries({ queryKey: ["users"] }); }, });

const handleSubmit = (data: UserData) => { if (mutation.isPending) return; mutation.mutate(

Install

Run this command

git clone https://github.com/expo/skills && cp -r skills/plugins/expo/skills/expo-data-fetching ~/.claude/skills/

Works with

claude appclaude codeclaude apicursorcodexwindsurfclinezed

Manual steps

Clone the repository and copy the `plugins/expo/skills/expo-data-fetching` folder into your Claude skills directory. Compatible with Claude Code, Cursor, Codex, and any Agent Skills-compatible agent.

View source
License: MITBy Expo

Frequently asked questions

What is the Expo Data Fetching skill?

Framework (OSS). Use when implementing or debugging ANY network request, API call, or data fetching. Covers fetch API, React Query, SWR, error handling, caching, offline support, loading/empty/error screen states, and Expo Router data loaders (`useLoaderData`).

How do I install Expo Data Fetching?

Run this in your terminal:

git clone https://github.com/expo/skills && cp -r skills/plugins/expo/skills/expo-data-fetching ~/.claude/skills/
Which AI tools does Expo Data Fetching work with?

It works with claude_app, claude_code, claude_api, cursor, codex, windsurf, cline, zed.

Who made Expo Data Fetching?

Expo, released under the MIT license.

Is Expo Data Fetching free?

Yes, it is free to use under the MIT license.

Related assets

More curated picks in Development & Code.

All Expo Data Fetching alternatives →
skillclaude_appclaude_codeclaude_api
npx skills add google/agents-cli
Google Agents Cli Adk Code
This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent",…358,165+
skillclaude_appclaude_codeclaude_api
npx skills add google/agents-cli
Google Agents Cli Workflow
This skill should be used when the user wants to "develop an agent", "build an agent using ADK", "run the agent locally", "debug agent code", "test an…357,749+
skillclaude_appclaude_codeclaude_api
npx skills add google/agents-cli
Google Agents Cli Eval
This skill should be used when the user wants to "run an evaluation", "evaluate my agent", "evaluate my ADK agent", "write an eval dataset", "analyze…357,721+
skillclaude_appclaude_codeclaude_api
npx skills add google/agents-cli
Google Agents Cli Deploy
This skill should be used when the user wants to "deploy an agent", "deploy my ADK agent", "set up CI/CD", "configure secrets", "troubleshoot a deploy…357,661+
skillclaude_appclaude_codeclaude_api
npx skills add google/agents-cli
Google Agents Cli Publish
This skill should be used when the user wants to "publish an agent", "publish my ADK agent", "register an agent with Gemini Enterprise", "publish to G…357,490+
skillclaude_appclaude_codeclaude_api
npx skills add prisma/skills
Prisma Cli
Prisma ORM CLI commands reference covering init, generate, migrate, db, dev, complete, studio, validate, format, debug, and mcp. Use for ORM/database…309,452+

Audit before you install

Run any source through our checks - AI visibility, security, performance, and stack detection.

More in Development & Code