Overview

Purpose and Scope

SWR is the Vercel-maintained React Hooks library for remote data fetching. The repository centers on a small set of hook-oriented APIs that let components ask for data, receive cached values quickly, and continue updating as the underlying resource changes. The README describes the library as a React Hooks data-fetching library and frames its name around stale-while-revalidate: return cached data first, revalidate in the background, and then publish the fresh result back to the component tree. That model is the conceptual thread connecting the core hook, pagination, mutation, subscription, and global configuration APIs.

Sources: README.md, src/index/index.ts

The project is distributed as the npm package named swr, with package metadata describing it as a React Hooks library for remote data fetching. The package exposes browser and server-compatible builds through explicit export entries, so application code normally imports from the top-level package for the core hook and from subpaths for specialized hook families. This structure matters for readers because SWR is not only a single default hook; it is a set of related public entrypoints with consistent cache, key, and configuration concepts shared across them.

Sources: package.json, src/index/index.ts

Relevant Source Files

  • README.md — Introduces SWR, explains stale-while-revalidate, lists major capabilities, and shows the minimal useSWR example.
  • package.json — Defines the swr package metadata, build outputs, scripts, and public export map for the top-level package and subpackages.
  • src/index/index.ts — Re-exports the default useSWR hook, SWRConfig, mutate, preload, unstable_serialize, useSWRConfig, and the main public TypeScript types.
  • src/infinite/index.ts — Implements and exports the infinite-loading middleware and default useSWRInfinite hook for paginated resources.
  • src/mutation/index.ts — Implements the mutation hook behavior, including trigger, reset, mutation state, and integration with the shared mutate API.
  • src/subscription/index.ts — Implements the experimental subscription hook that connects external data sources to SWR cache updates.

Core Primitives

The smallest SWR application starts with one resource key, one asynchronous fetcher, and one React component that renders loading, error, and data states. The README quick start shows useSWR called with an API key such as an endpoint string and a fetcher function. The hook returns data, error, and isLoading, allowing the component to describe each state without hand-writing request lifecycle bookkeeping. The README also emphasizes that the fetcher can be any asynchronous function, which keeps SWR transport and protocol agnostic rather than coupling it to one HTTP client.

Sources: README.md

import useSWR from 'swr'
 
function Profile() {
  const { data, error, isLoading } = useSWR('/api/user', fetcher)
 
  if (error) return <div>failed to load</div>
  if (isLoading) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

The public surface exported by the core entrypoint is broader than the default hook. The top-level source exports SWRConfig for global configuration, useSWRConfig for reading configuration and scoped helpers, mutate for cache writes and revalidation, preload for warming data before render paths need it, and unstable_serialize for turning keys into stable cache identifiers. It also exports public types for keys, fetchers, middleware, cache, mutation options, mutators, responses, and configuration. That makes the top-level entrypoint both the everyday application API and the type anchor for the rest of the package.

Sources: src/index/index.ts

Public Hook Families

The main hook family is useSWR from the package root. It is the default export of the core source entrypoint and is the API readers should learn first. Conceptually, useSWR binds a key and fetcher to the shared SWR runtime. A key identifies the resource, while the fetcher resolves the value for that resource. Configuration can be passed locally or provided globally. From the reader’s perspective, the result is a reactive data stream: cached data may render immediately, revalidation can happen automatically, and later updates cause the component to rerender with current values.

Sources: README.md, src/index/index.ts

For lists that grow page by page, the infinite subpackage provides useSWRInfinite. Its source wraps the normal useSWR hook with middleware and tracks page metadata under a prefixed infinite key. The implementation reads options such as initialSize, revalidateAll, persistSize, revalidateFirstPage, revalidateOnMount, and parallel. It stores and restores the current page size, subscribes to cache changes, and derives the first page key before loading page data. This means infinite loading is not a separate cache system; it is a pagination-oriented layer built on the same SWR primitives.

Sources: src/infinite/index.ts

For writes and remote actions, the mutation subpackage provides useSWRMutation. Its implementation reads the scoped mutate helper from useSWRConfig, stores the latest key, fetcher, and configuration in refs, and exposes a trigger function. Trigger serializes the key, validates that both key and fetcher exist, marks the mutation as active, runs the mutation fetcher through mutate, and then updates data, error, and isMutating. The source also gives mutations a reset path and intentionally avoids returning a value named mutate, reducing confusion between the trigger API and the global cache mutation API.

Sources: src/mutation/index.ts

For continuously pushed data, the subscription subpackage provides useSWRSubscription. The source describes it as an experimental hook for subscribing a SWR resource to an external data source. Internally it serializes the key, prefixes it to avoid conflicts with normal resources, creates an SWR resource with no fetcher, and wires the external subscribe callback to cache updates. Subscription state is scoped by cache boundary through a WeakMap, with reference counts and disposer functions ensuring that multiple components can share a subscription and that the external unsubscribe function runs when the last subscriber unmounts.

Sources: src/subscription/index.ts

Package and Entrypoint Map

The package export map makes the intended import structure explicit. The root export points to the core implementation and includes react-server, import, and require conditions. The infinite subpath also includes a react-server condition plus import and require builds. Mutation, subscription, and immutable expose import and require builds. The internal subpath is exported as well, including a react-server condition, but application code should prefer the public hook and configuration APIs unless it is intentionally building against lower-level SWR internals. The sideEffects flag is false, which supports tree-shaking in compatible bundlers.

Sources: package.json

Import pathPrimary roleBacking source in this page
swrCore useSWR, SWRConfig, mutate, preload, public typessrc/index/index.ts
swr/infinitePaginated and load-more data with useSWRInfinitesrc/infinite/index.ts
swr/mutationRemote mutation trigger state with useSWRMutationsrc/mutation/index.ts
swr/subscriptionExternal data-source subscriptions with useSWRSubscriptionsrc/subscription/index.ts

The repository is also organized for contributors and package validation. The package scripts include build, watch, type checking, linting, unit tests, build tests, end-to-end tests, coverage, and a combined check command. That operational metadata is useful even for readers focused on APIs because it shows that the library is maintained as a typed, multi-entry package rather than a single untyped bundle. If you plan to modify a hook family, start by identifying the source entrypoint, then run the relevant type and test scripts described in the package metadata before opening a change.

Sources: package.json

How the Pieces Fit Together

A useful way to read this repository is from the outside in. Start with the README’s data-flow story: a component asks for a resource, SWR can show cached data, and a revalidation later replaces it with fresh data. Then map that story to the top-level source export, where useSWR is the default hook and the supporting APIs provide configuration, mutation, preloading, serialization, and types. Once that model is clear, the specialized entrypoints become easier to reason about because each one extends the same cache and key system instead of inventing an unrelated runtime.

Sources: README.md, src/index/index.ts

The official examples reinforce this layering. API hooks demonstrate wrapping SWR in domain-specific hooks for different data requirements. Global fetcher examples show how SWRConfig avoids passing the same fetcher to every hook. Prefetch and preload examples show that data can be prepared before a component performs its render-time read. These examples are not separate architectures; they are reader-facing applications of the primitives exported by the package root and the specialized hook families. Use them as recipes after the core stale-while-revalidate lifecycle and import map are familiar.

Next Steps

If you are new to the project, read What Is SWR? and Quick Start before moving into API references. If you are choosing an entrypoint, use the root hook for ordinary resources, use the infinite hook for page arrays or load-more interfaces, use the mutation hook for explicit remote writes, and use the subscription hook when an external source pushes updates over time. For deeper work, continue to the pages on keys and serialization, cache providers, global configuration, revalidation strategies, and the individual API references for each hook family.