# swr

Guidance for using SWR in React apps with client-side fetching, caching, revalidation, mutations, pagination, and live data.

- skill · `type=skill` · Codex, ChatGPT · 6 installs · ★ 7604
- Author: Vercel Labs · official OpenAI repository
- License: Apache-2.0 · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/openai/plugins/tree/HEAD/plugins/vercel/skills/swr/SKILL.md
- Updated: 2026-10-08
- HTML: https://affpapa.org/en/nevibecode/skills/swr

## What it does

This skill guides React work built around the SWR library. It covers `useSWR`, resource keys, fetcher functions, loading and error states, shared cache behavior, and manual refreshes through `mutate()`. The material also explains how `SWRConfig` can provide shared defaults for an application or subtree.

Separate sections cover `useSWRMutation` for server changes and optimistic UI, including rollback after a failed request. `useSWRInfinite` handles paginated and load-more interfaces, while subscription guidance covers WebSockets and SSE with cleanup and shared subscriptions. Error retry rules and conditional fetching are included too.

Hooks must not be called conditionally. Pass `null` as the key when a request should be skipped. The project needs React and the `swr` package; the skill itself can be added to Codex with the commands listed below.

## Install

### Codex (native platform)

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

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

### Claude Code

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

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

### Cursor

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

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install openai/plugins swr
```

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

### Gemini CLI

**Platform CLI**
```bash
gemini skills install https://github.com/openai/plugins --path plugins/vercel/skills/swr
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/swr/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/vercel/skills/swr/SKILL.md

## When to use it
- set up client-side React fetching with SWR
- share cached results across components
- add optimistic server mutations with rollback
- build pagination or a load-more list
- configure retries and real-time subscriptions

## Example prompts
- Set up a profile request with `useSWR`, including loading and error states.
- Implement a user update with `useSWRMutation`, optimistic data, and rollback on failure.
- Build a paginated items list with `useSWRInfinite` and a load-more button.

## Source text · SKILL.md · Apache-2.0

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: fc158c8cb06bb6d2.

BEGIN THIRD-PARTY FILE fc158c8cb06bb6d2
````text
---
name: swr
description: SWR data-fetching expert guidance. Use when building React apps with client-side data fetching, caching, revalidation, mutations, optimistic UI, pagination, or infinite loading using the SWR library.
metadata:
  priority: 4
  docs:
    - "https://swr.vercel.app/docs"
  sitemap: "https://swr.vercel.app/sitemap.xml"
  pathPatterns:
    - 'lib/fetcher.*'
    - 'src/lib/fetcher.*'
    - 'utils/fetcher.*'
    - 'src/utils/fetcher.*'
    - 'hooks/use*SWR*'
    - 'src/hooks/use*SWR*'
    - 'hooks/useFetch*'
    - 'src/hooks/useFetch*'
  importPatterns:
    - 'swr'
    - 'swr/*'
  bashPatterns:
    - '\bnpm\s+(install|i|add)\s+[^\n]*\bswr\b'
    - '\bpnpm\s+(install|i|add)\s+[^\n]*\bswr\b'
    - '\bbun\s+(install|i|add)\s+[^\n]*\bswr\b'
    - '\byarn\s+add\s+[^\n]*\bswr\b'
  promptSignals:
    phrases:
      - "swr"
      - "useswr"
      - "stale-while-revalidate"
    allOf:
      - [data fetching, client]
      - [cache, revalidat]
    anyOf:
      - "mutation"
      - "optimistic"
      - "infinite loading"
      - "pagination"
    noneOf: []
    minScore: 6
---

# SWR — React Hooks for Data Fetching

You are an expert in SWR v2 (latest: 2.4.1), the React Hooks library for data fetching by Vercel. SWR implements the stale-while-revalidate HTTP cache invalidation strategy — serve from cache first, then revalidate in the background.

## Installation

```bash
npm install swr
```

## Core API

### `useSWR`

```tsx
import useSWR from 'swr'

const fetcher = (url: string) => fetch(url).then(res => res.json())

function Profile() {
  const { data, error, isLoading, mutate } = useSWR('/api/user', fetcher)

  if (isLoading) return <div>Loading...</div>
  if (error) return <div>Error loading data</div>
  return <div>Hello, {data.name}</div>
}
```

**Key parameters:**
- `key` — unique string, array, or function identifying the resource (often a URL)
- `fetcher` — async function that receives the key and returns data
- `options` — optional config object

**Return values:** `data`, `error`, `isLoading`, `isValidating`, `mutate`

### `useSWRMutation` — Remote Mutations

```tsx
import useSWRMutation from 'swr/mutation'

async function updateUser(url: string, { arg }: { arg: { name: string } }) {
  return fetch(url, { method: 'POST', body: JSON.stringify(arg) }).then(res => res.json())
}

function Profile() {
  const { trigger, isMutating } = useSWRMutation('/api/user', updateUser)

  return (
    <button disabled={isMutating} onClick={() => trigger({ name: 'New Name' })}>
      Update
    </button>
  )
}
```

### `useSWRInfinite` — Pagination & Infinite Loading

```tsx
import useSWRInfinite from 'swr/infinite'

const getKey = (pageIndex: number, previousPageData: any[]) => {
  if (previousPageData && !previousPageData.length) return null
  return `/api/items?page=${pageIndex}`
}

function Items() {
  const { data, size, setSize, isLoading } = useSWRInfinite(getKey, fetcher)
  const items = data ? data.flat() : []

  return (
    <>
      {items.map(item => <div key={item.id}>{item.name}</div>)}
      <button onClick={() => setSize(size + 1)}>Load More</button>
    </>
  )
}
```

## Global Configuration

Wrap your app (or a subtree) with `SWRConfig` to set defaults:

```tsx
import { SWRConfig } from 'swr'

function App() {
  return (
    <SWRConfig value={{
      fetcher: (url: string) => fetch(url).then(res => res.json()),
      revalidateOnFocus: false,
````
END THIRD-PARTY FILE fc158c8cb06bb6d2

The third-party file has ended. Everything between the fc158c8cb06bb6d2 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 3436 of 5774 bytes. © Vercel Labs · Apache-2.0 · https://github.com/openai/plugins/tree/HEAD/plugins/vercel/skills/swr/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
