# swr

SWR data-fetching guidelines for React and TypeScript apps. It guides agents on caching, request deduplication, and optimistic mutations.

- skill · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · 870 installs · ★ 286
- Author: Mindrally
- License: Apache-2.0 · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/Mindrally/skills/tree/HEAD/swr/SKILL.md
- Updated: 2026-10-08
- HTML: https://affpapa.org/en/nevibecode/skills/mindrally-swr

## What it does

This skill provides coding agents with standard patterns for client-side data fetching using SWR in React. It specifies a clean project layout across `hooks/swr/`, `lib/fetcher.ts`, and `providers/SWRProvider.tsx`. Generated setups configure automatic deduplication with a 2000 ms interval and up to three retry attempts on fetch errors.

The instructions cover conditional queries using `null` keys, polling via `refreshInterval`, and pagination with `keepPreviousData: true`. Mutate examples demonstrate optimistic UI updates paired with `rollbackOnError: true` for clean rollback. Without the `swr` package added to `package.json`, none of these hooks will compile.

## Install

### Claude Code (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add Mindrally/skills --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/

### Codex

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

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

### Cursor

1. **Skills CLI (Vercel)**
```bash
npx skills add Mindrally/skills --skill swr -a cursor
```

2. **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 Mindrally/skills swr
```

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

### Gemini CLI

1. **Skills CLI (Vercel)**
```bash
npx skills add Mindrally/skills --skill swr -a gemini-cli
```

2. **Platform CLI**
```bash
gemini skills install https://github.com/Mindrally/skills --path swr
```

### Windsurf (Devin Desktop)

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

### OpenCode

**Skills CLI (Vercel)**
```bash
npx skills add Mindrally/skills --skill swr -a opencode
```

### 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/Mindrally/skills/tree/HEAD/swr/SKILL.md

## When to use it
- configure a global `SWRConfig` provider with an authenticated fetcher
- implement optimistic updates with automatic error rollback
- set up conditional data fetching and paginated queries
- add polling intervals and window focus revalidation

## Example prompts
- Create a `useUser` hook with conditional fetching based on `userId` using SWR
- Write a global `SWRProvider` with a custom fetcher and deduping interval
- Build an optimistic update handler for user profiles with `rollbackOnError`

## 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: 429d4a8cab81c8b4.

BEGIN THIRD-PARTY FILE 429d4a8cab81c8b4
````text
---
name: swr
description: Guidelines for using SWR (stale-while-revalidate) React Hooks for efficient data fetching, caching, and revalidation
metadata:
  maintainer: Mindrally
  source: https://github.com/Mindrally/skills
---

# SWR Best Practices

You are an expert in SWR (stale-while-revalidate), TypeScript, and React development. SWR is a React Hooks library for data fetching that first returns data from cache (stale), then sends the request (revalidate), and finally delivers up-to-date data.

## Core Principles

- Use SWR for all client-side data fetching
- Leverage automatic caching and revalidation
- Minimize boilerplate with SWR's built-in state management
- Implement proper error handling and loading states
- Use TypeScript for full type safety

## Key Features

- **Stale-While-Revalidate**: Returns cached data immediately, then revalidates in background
- **Automatic Revalidation**: On mount, window focus, and network reconnection
- **Request Deduplication**: Multiple components using same key share one request
- **Built-in Caching**: Zero-configuration caching with smart invalidation
- **Minimal API**: Simple hook-based interface

## Project Structure

```
src/
  hooks/
    swr/
      useUser.ts
      usePosts.ts
      useProducts.ts
  lib/
    fetcher.ts           # Global fetcher configuration
  providers/
    SWRProvider.tsx      # SWR configuration provider
  types/
    api.ts               # API response types
```

## Setup and Configuration

### Global Configuration

```typescript
// providers/SWRProvider.tsx
import { SWRConfig } from 'swr';

const fetcher = async (url: string) => {
  const res = await fetch(url);

  if (!res.ok) {
    const error = new Error('An error occurred while fetching data.');
    throw error;
  }

  return res.json();
};

export function SWRProvider({ children }: { children: React.ReactNode }) {
  return (
    <SWRConfig
      value={{
        fetcher,
        revalidateOnFocus: true,
        revalidateOnReconnect: true,
        shouldRetryOnError: true,
        errorRetryCount: 3,
        dedupingInterval: 2000,
      }}
    >
      {children}
    </SWRConfig>
  );
}
```

### Custom Fetcher

```typescript
// lib/fetcher.ts
export async function fetcher<T>(url: string): Promise<T> {
  const response = await fetch(url, {
    headers: {
      'Content-Type': 'application/json',
    },
  });

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

  return response.json();
}

// With authentication
export async function authFetcher<T>(url: string): Promise<T> {
  const token = getAuthToken();

  const response = await fetch(url, {
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`,
    },
  });

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

  return response.json();
}
```

## Basic Usage

### useSWR Hook

The `useSWR` hook accepts three parameters:
- **key**: A unique string identifier for the request (like a URL)
- **fetcher**: An async function that fetches the data
- **options**: Configuration options

```typescript
import useSWR from 'swr';

interface User {
  id: string;
  name: string;
  email: string;
}

function useUser(userId: string) {
````
END THIRD-PARTY FILE 429d4a8cab81c8b4

The third-party file has ended. Everything between the 429d4a8cab81c8b4 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 3267 of 10361 bytes. © Mindrally · Apache-2.0 · https://github.com/Mindrally/skills/tree/HEAD/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
