# Kong swrv: stale-while-revalidate data fetching for Vue

> A Composition API hook that returns cached data first and revalidates behind it, with polling, deduplication, retry, stale-if-error, and a cache you can replace.

**Kong/swrv** — Stale-while-revalidate data fetching for Vue

- Repository: https://github.com/Kong/swrv
- Website: https://docs-swrv.netlify.app
- Stars: 2,278 · Forks: 76
- Language: TypeScript
- License: Apache-2.0
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/kong-swrv

## One hook, four return values

The entire API is one function. You call it with a key, an optional fetcher, and optional configuration, and it returns data, an error, two status flags, and a way to trigger revalidation manually:

```ts
const { data, error, isValidating, mutate } = useSWRV(key, fetcher, options)
```

The getting started example is a complete Vue single file component:

```vue
<template>
  <div>
    <div v-if="error">failed to load</div>
    <div v-if="!data">loading...</div>
    <div v-else>hello {{ data.name }}</div>
  </div>
</template>

<script>
import useSWRV from 'swrv'

export default {
  name: 'Profile',

  setup() {
    const { data, error } = useSWRV('/api/user', fetcher)

    return {
      data,
      error,
    }
  },
}
</script>
```

Two details in that signature carry weight. The `data` and `error` values are Vue refs, which is what makes the component re-render when the fetcher resolves. And the fetcher can be anything asynchronous, so an application already using Axios or a GraphQL client keeps it. When the fetcher is omitted entirely, swrv falls back to the browser's Fetch API; when it is passed as `null`, swrv serves from cache and never revalidates, which is the switch you use in tests and for server-rendered pages.

There is one calling-convention rule the README states plainly: `useSWRV` must be called from a component's `setup()` function or inside an active `effectScope()`.

## The config defaults that decide how it behaves

The README lists the defaults and links to `src/use-swrv.ts` for the authoritative values, which is the right place to look because several of them are opinionated.

`refreshInterval = 0` disables polling unless you ask for it, so out of the box there is no background traffic. `dedupingInterval = 2000` is the one to understand first: requests with the same key inside a two-second window are collapsed into a single network call, which is the mechanism behind the request deduplication the feature list claims. `ttl = 0` means cached data never expires on its own, so a `ttl` of zero is not a bug but a decision that invalidation is your job.

Retry behaviour is the other cluster. `shouldRetryOnError = true`, `errorRetryInterval = 5000`, and `errorRetryCount: 5` describe a backoff-free fixed-interval retry that gives up after five attempts. Note that the last one is written with a colon in the README while the rest use an equals sign, which suggests the list was transcribed rather than generated; the pinned link to the source is what settles it. `revalidateOnFocus = true` refreshes when the window regains focus, and `revalidateDebounce = 0` debounces that, with the README noting it is most useful when a component renders from cache immediately and then unmounts.

Taken together these defaults describe a library that is chatty by design but bounded: it talks on focus, it retries five times at five second intervals, and it collapses duplicate work inside two seconds.

## Swapping the cache, and reading it directly

The feature list calls the cache implementation customizable, and the README documents four ways to work with it. You can serve from cache only by passing `null` as the fetcher. You can isolate the cache per app instance, which the README specifically calls out for test suites, so one test's responses do not leak into the next. You can write to a cache you provide, and you can persist to localStorage.

The v1.3.0 release made this more explicit by adding an injectable data cache through provide and inject, alongside an exports map that makes the ESM build loadable. The package.json confirms the direction of travel. It now declares both `dist` and `esm` builds with a conditional exports map, and it exposes a dedicated `./testing` subpath alongside the root entry:

```json
"./testing": {
  "import": {
    "types": "./esm/testing.d.ts",
    "default": "./esm/testing.js"
  },
  "require": {
    "types": "./dist/testing.d.ts",
    "default": "./dist/testing.js"
  }
},
```

A `./testing` entry point is a small design decision with a large practical effect. Test helpers, cache reset utilities, and adapters can be imported without pulling them into your production bundle, which is exactly the concern the per-app cache isolation option exists to solve. If you are writing tests around components that use `useSWRV`, that subpath is where to look first.

The README also documents `useSwrvState` for lifting swrv state, a Vuex integration, prefetching, dependent fetching where one key's value seeds another's fetcher, and a stale-if-error mode that keeps showing the last good value instead of an error.

## Vue 2 support ended, and SSR is gone

Two removals are worth reading carefully because they change who can adopt the library.

The feature list shows SSR support struck through, with a note that it was removed as of version 0.10.0 and a link to the pull request that did it. Yet the repository's `examples/` directory still contains `examples/ssr-nuxt/` and `examples/axios-typescript-nuxt/`. Those examples predate the removal and are not evidence that server rendering works today. The README's own feature list is the more reliable statement, and it says plainly that SSR is not supported.

Vue 2 is a more recent change. The installation section still documents how to install it, mapping Vue 2.7 to `swrv@0.10.0` under the `v2-latest` npm tag and Vue 2.6 and below to `swrv@0.9.6` under `legacy`. Those instructions remain because those tagged releases remain installable. But v1.3.0, published on 2026-09-16, includes a commit titled "correct the Vue support range and drop Vue 2".

So the practical reading is that the current line is Vue 3 only, the install section documents history rather than a supported option, and the stated supported range is every Vue 3 minor release since 3.2. Vue 2 reached end of life on 31 December 2023, so this is a project following its ecosystem rather than making an independent bet.

## Provenance, naming, and how it compares to the React original

The README is explicit that swrv is "largely a port of swr", the React library, and that the name comes from the stale-while-revalidate cache invalidation strategy popularized by HTTP RFC 5861. It explains the strategy in one sentence that is worth keeping: SWR returns data from cache first, then sends the fetch request, then comes back with the up-to-date data.

The repository lives under the Kong organisation, which is the API gateway company, and the project carries the Apache 2.0 license. The documentation is hosted separately at docs-swrv.netlify.app, and the default branch is `master`. The repository language is TypeScript, the feature list claims TypeScript readiness, and there are separate tsconfig files for the build and the editor, plus a `types:check` script.

Because it is a port rather than an original, the honest comparison is with the React swr it derives from and with newer Vue options such as TanStack Query for Vue. The README itself only answers the first of those in its FAQ section, where it asks how swrv differs from the swr React library. It does not address the second, which means the case for choosing this particular library over a more actively maintained Vue data-fetching option is something you will have to argue for yourself. The `tests/test-compat-all.sh` script referenced in package.json suggests the maintainers take version-matrix compatibility seriously, and 2,277 stars with 33 open issues indicates the base is well established.

## Conclusion

swrv solves one problem precisely: showing a user something immediately and correcting it a moment later, without either blocking the render or firing a duplicate request per component. It does that in a few hundred lines with a minimal surface, four return values, and no required configuration. What it deliberately leaves out is as important as what it includes. There is no SSR, since that was removed in 0.10.0, and there is no Vue 2 support in current releases, which closed off one of the reasons to reach for it in 2026. If your data source is anything other than a plain GET, you are supplying the fetcher and therefore most of the thinking. Start with the getting started example, then read the config defaults in src/use-swrv.ts, because the defaults for deduping interval and error retry count are where the surprising behaviour lives.

## FAQ

### What does useSWRV return?

Four values plus a function: data as a Vue ref, error as a ref, isValidating as a boolean ref that is true while a request or revalidation is in flight, and mutate for triggering revalidation by hand. A later release also added isLoading, which differs from isValidating in that it is only true when data has not arrived yet.

### What is the fetcher parameter for in swrv?

It is any function that takes the key and returns a promise, so you can use Axios, a GraphQL client, or anything else you already depend on. Omit it and swrv uses the browser Fetch API. Pass null instead and swrv reads from cache without ever issuing a request, which is the mode used for server rendering and tests.

### Does swrv still support server side rendering?

No. The README feature list marks SSR support as removed as of version 0.10.0 and links the pull request. Some example directories for Nuxt remain in the repository from before that removal, so treat the feature list as authoritative rather than the examples folder.

### Can I use swrv with Vue 2?

Only on the older tagged releases. Vue 2.7 maps to swrv@0.10.0 under the v2-latest npm tag, and Vue 2.6 or below to swrv@0.9.6 under legacy. The v1.3.0 release dropped Vue 2, so the current line requires Vue 3.2 or newer.

### How does swrv avoid making the same request twice?

By deduplication keyed on the request key. The dedupingInterval default is 2000 milliseconds, so two components asking for the same key inside a two second window share one network call. Polling is off by default since refreshInterval is 0, and revalidation on window focus is on by default.

### How do I reset the swrv cache between tests?

The README documents a per-app cache isolation option specifically for test suites, so each app instance gets its own cache rather than sharing a module-level one. Newer versions also expose a dedicated ./testing entry point in the package exports map, which is the intended place to import reset helpers or adapters from.

## Sources

- [Kong/swrv on GitHub](https://github.com/Kong/swrv)
- [License: Apache-2.0](https://github.com/Kong/swrv/blob/master/LICENSE)
- [Project website](https://docs-swrv.netlify.app)
- [README](https://github.com/Kong/swrv/blob/master/README.md)
- [Releases](https://github.com/Kong/swrv/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/kong-swrv
