# native-data-fetching

Sets conventions and patterns for Expo networking. Helps configure React Query, error retries, offline syncing, and secure token storage.

- skill · `type=skill` · Codex, ChatGPT · 1 install · ★ 7604
- Author: Expo Team · official OpenAI repository
- License: MIT · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/openai/plugins/tree/HEAD/plugins/expo/skills/native-data-fetching/SKILL.md
- Updated: 2026-10-08
- HTML: https://affpapa.org/en/nevibecode/skills/native-data-fetching

## What it does

This skill guides agents through handling network requests in Expo and React Native apps. It details patterns for the native fetch API, SWR, and `@tanstack/react-query`, along with Expo Router route loaders (`useLoaderData`) for web SDK 55+.

The guidelines mandate avoiding `axios` in favor of `expo/fetch`. It covers structured failure handling via `ApiError`, exponential backoff logic, token storage through `expo-secure-store`, and network status events using `@react-native-community/netinfo`.

## Install

### Codex (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add openai/plugins --skill native-data-fetching -a codex
```

2. **Manually: put the files in place**
- File: `.agents/skills/native-data-fetching/SKILL.md` — For all projects use ~/.agents/skills/

### Claude Code

1. **Skills CLI (Vercel)**
```bash
npx skills add openai/plugins --skill native-data-fetching -a claude-code
```

2. **Manually: put the files in place**
- File: `~/.claude/skills/native-data-fetching/SKILL.md` — Copy the whole skill folder; for one project use .claude/skills/native-data-fetching/

### Cursor

**Manually: put the files in place**
- File: `.cursor/skills/native-data-fetching/SKILL.md` — Cursor also reads .agents/skills/ and .claude/skills/

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install openai/plugins native-data-fetching
```

2. **Manually: put the files in place**
- File: `.github/skills/native-data-fetching/SKILL.md`

### Gemini CLI

**Platform CLI**
```bash
gemini skills install https://github.com/openai/plugins --path plugins/expo/skills/native-data-fetching
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/native-data-fetching/SKILL.md` — The legacy .windsurf/skills/ path still works

### Claude.ai

**Claude.ai**
- Zip the folder and upload it in Settings → Capabilities → Skills

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/openai/plugins/tree/HEAD/plugins/expo/skills/native-data-fetching/SKILL.md

## When to use it
- configure `@tanstack/react-query` providers and mutations
- store and refresh auth tokens using `expo-secure-store`
- sync offline query status with `@react-native-community/netinfo`
- implement fetch wrappers with exponential backoff retries
- set up API URLs with `EXPO_PUBLIC_` environment variables

## Example prompts
- Set up a TanStack Query client in app/_layout.tsx with offline support via NetInfo.
- Create an authenticated fetch wrapper that stores bearer tokens in expo-secure-store.
- Implement a fetch helper with ApiError parsing and exponential backoff retry logic.

## Source text · SKILL.md · MIT

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: a3842fcb2206287a.

BEGIN THIRD-PARTY FILE a3842fcb2206287a
````text
---
name: native-data-fetching
description: Use when implementing or debugging ANY network request, API call, or data fetching. Covers fetch API, React Query, SWR, error handling, caching, offline support, and Expo Router data loaders (`useLoaderData`).
version: 1.0.0
license: MIT
---

# 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+)
```

## 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

## 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, isLoading, error, refetch } = useQuery({
    queryKey: ["user", userId],
    queryFn: () => fetchUser(userId),
  });

  if (isLoading) return <Loading />;
  if (error) return <Error message={error.message} />;

  return <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) => {
    mutation.mutate(data);
  };

  return <Form onSubmit={handleSubmit} isLoading={mutation.isPending} />;
}
```

---

### 3. Error Handling

**Comprehensive error handling**:

```tsx
class ApiError extends Error {
  constructor(message: string, public status: number, public code?: string) {
    super(message);
    this.name = "ApiError";
  }
}
````
END THIRD-PARTY FILE a3842fcb2206287a

The third-party file has ended. Everything between the a3842fcb2206287a tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 3392 of 11645 bytes. © Expo Team · MIT · https://github.com/openai/plugins/tree/HEAD/plugins/expo/skills/native-data-fetching/SKILL.md

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
