Introduce SWR v2 and SWRDevTools

Toru Kobayashi
5 min readDec 23, 2022

SWR v2 has been released in Dec 2022, which includes many features and improvements like the following.

  • NewuseSWRMutation hook
  • Mutate multiple items feature
  • New preload API
  • New isLoading state
  • New keepPreviousData option
  • Improve Optimistic Updates support
  • Improve React 18 support
  • SWRDevTools

You can check these updates in the blog post. These features improve user experiences of your application and developer experiences of your team.

In this post, I’ll focus on some of the updates.

Mutate Multiple Items

I’d say this was the biggest missing feature for SWR v1.

The global mutate API now accepts a filter function as its first argument.

This gives us flexibility for mutation scenarios. Let’s take a look at examples.

Revalidate all cache data for the same API endpoint with different query params

For example, you have an API /api/users/?sort={id, name, etc}that returns users data, which accepts a sort key. When you have updated a user, you would want to revalidate all cache data for /api/users/ regardless of the sort key. The Mutate Multiple Items makes this possible.

import { mutate } from "swr";

const handleUpdateUser = async (user) => {
await updateUser(user);
// revalidate all cache data its key is start with /api/users
mutate(key => typeof key === "string" && key.startWith("/api/users/"));
// If you don't want to relivadate all keys and just want to invalidate the cache data,
mutate(
key => typeof key === "string" && key.startWith("/api/users/"),
undefined,
{ revalidate: false }
)
}

Revalidate the specific cache data of which keys are tagged arrays

SWR allows us to use an array as the key, which means you can add a tag into each key.

// ['user', 1]
// ['user', 2]
// ['item', 1]

We can update all cache data that have the same tag by the Mutate Multiple Items.

// Revalidate all cache data of which tag is "user"
mutate(key => Array.isArray(key) && key[0] === "user");

The filter function is applied to all cache keys, so you have to check the type of each cache key.

The Mutate Multiple Items gives us more flexible key management.

Clear all cache data

The Mutate Multiple Items can also use to clear all cache data.

const clearCache = () => mutate(
() => true,
undefined,
{ revalidate: false }
)

// ...clear cache on logout
clearCache()

You might wonder why we shouldn’t clear the cache data directly by accessing the cache object. Updating cache data directly might cause inconsistency in some scenarios like concurrent features or race conditions. So you should avoid it and use mutate instead.

Documentation

I think documentation is crucial for libraries. Developers can’t find a feature or might use it the wrong way when it’s not well documented. In the v2 release, We’ve reorganized some documentation, like the Mutation page. I’ve also added a new “Understanding SWR” page so that developers can understand how SWR behaves.

The preview of the Understanding SWR page
Diagrams in the Understanding SWR page

This is from my past experience. When I started trying SWR, I was very confused about how to combine return values, which are data, isValidating, and error. SWR v2 introduces more patterns with isLoading and the keepPreviousData option. I think developers get more confused with them. In order to help understand this, I’ve added the new page based on the diagrams Shu created.

Bundle Size and Optimization

As you can see, SWR v2 has many features, but the bundle size is smaller than v1! The reason is that we’ve updated the build target version from ES5 to ES2018, which drastically reduced the bundle size. It also brings performance improvements with SSR.

SWR v2 keeps the bundle size small

Middleware abstraction

This is about internal implementation, so you don’t have to care about that. But I wanted to pick up that because I was impressed the power of abstraction. SWR introduced Middleware in the v1 release, which enables us to extend SWR in user land. But this is also beneficial for SWR itself.

For example, useSWRMutation, preload are implemented as a middleware, so we separate these implementation from core implementation of SWR, which keeps core implementation small. I think it’s important for us to keep adding new features to SWR. useSWRInfinite and useSWRImmutable are also implemented as middleware. you can check it on the GitHub.

https://github.com/vercel/swr

SWRDevTools

DevTools is a long standing issue for SWR, so I started implementing it because it seems to be fun 😁 I’m honored that SWRDevTools is a part of features of v2 release.

https://swr-devtools.vercel.app/

This is the my first browser extension, so I’ve learned a lot of thing like this.

  • How to develop and debug a extension
  • How to inject a script into a web page
  • How to add a panel to the developer tools
  • How to communicate between a webpage, a content script, a background script, and a devtool panel
  • How to implement a browser extension that works on Chrome (MV3) and Firefox (MV2)

SWR v2 has a native support of SWRDevTools, so you don’t have to do any setup in your application. SWRDevTools has also support SWR v1. When you want to use SWRDevTools for SWR v1, you have to wrap your application into the SWRDevTools component.

I’ve also build a demo on the webpage so that developers can try SWRDevTools without installing the extension. This is also implemented by using SWRDevTools. This brings additional complexity into it, but that makes sense.

The online demo of SWRDevTools on the website

I hope SWRDevTools helps your development.

Thank you!

You can check other great features on the blog post and documentation!

I’ve learned a lot of things through working on the v2 release. All of the core member of SWR are great. Thank you for working with me!

The Author’s of SWR v2 blog
I’m very honored to be listed as a author
Thanks message to me
Thank you too!

--

--