circuit

React Query vs SWR

Which one should you choose for your next project?




Photo by Vera Arsic from Pexels

Most modern web applications are dependent on some external data source. And in React, we generally use fetch or axios to get the data from the remote endpoints.

However, these 2 libraries only do so much. We still need to implement the loading state, error handling, caching, pagination, re-validation all of these things ourselves.

But there are 2 popular libraries for solving these problems. They are:

React Query

According to the documentation what this library offers are

Fetch, cache and update data in your React and React Native applications all without touching any “global state”.

Another library is

SWR

This library recognize itself as

React Hooks for Data Fetching

Today we will compare these 2 solutions and see which one is better in which scenarios.

The common things

Let's first talk about the common features. Both of these libraries can perform common tasks like

  • Query

  • Caching

  • Polling

  • Parallel Queries

  • Initial Data

  • Window focus re-fetching

  • Network status re-fetching

Now let's talk about the differences between them

Dev tools

This is a big one. React query offers Devtools which is just awesome. We have to pass it inside the root.

import { ReactQueryDevtools } from "react-query/devtools";

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      {/* The rest of your application */}
      <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  );
}

Unfortunately, SWR doesn't have any dev tools. There are some 3rd party packages that can do that though.

So this is a big win for react-query.

Global Error Handler

We can enable Global error handling on SWR taking the help of SWRConfig .

To enable it we wrap our root like the following

<SWRConfig
  value={{
    onError: (error, key) => {
      if (error.status !== 403 && error.status !== 404) {
        // We can send the error to Sentry,
        // or show a notification UI.
      }
    },
  }}
>
  <MyApp />
</SWRConfig>

But for some weird reason React query doesn't have this feature. We can achieve something like that by creating a special hook by ourselves but having official support would be awesome.

Update

Apparently, react-query does have official support for global error handling. You have to use the onError of query cache in your global configuration. Like the following.

const queryClient = new QueryClient({
  queryCache: new QueryCache({
    onError: (error, query) => {
      console.log(`Something went wrong: ${error.message}`);
    },
  }),
});

So that's a draw for this round :P

Thank you Dominik Dorfmeister for the correction. You can check his article on this topic here

Mutation Hooks

In React query we have mutation hooks by default. They are something like this

const mutation = useMutation(newTodo => axios.post('/todos', newTodo))

But in SWR we don't have any mutation hook rather we have the option to manipulate the data manually which is not convenient as mutation hooks.

import useSWR, { useSWRConfig } from "swr";

function App() {
  const { mutate } = useSWRConfig();

  const onClickHandler = () => {
    logout();
    mutate("/api/user"); // invalidate the user data
  };

  return <button> Logout </button>;
}

So this is obviously a huge win for React Query

Bundle Size

According to BundlePhobia the bundle size for SWR is 15kb where the bundle size for React Query is 50kb. Which is more than 3 times!

SWR vs React Query

So if you consider the size then obviously SWR wins by a large margin here!

Garbage Collection

According to react-query documentation, all of the data that is cached is garbage collected if any query remains inactive for 5 minutes.

Also, we have the ability to configure this according to our needs by changing the cacheTime in the configuration option.

But in SWR there is no garbage collection. SO you have to manipulate the cache manually if you want.

So this is a win for React Query

Final Verdict

In my opinion, both of these libraries are very good and can make the developer's life easy with improvement in the performance of the application.

However, it's clear that react-query has some very powerful features that SWR doesn't have. But that comes with the cost of increased bundle size.

So if you are building a simple application and want a ready-to-go simple solution then SWR should be your choice.

But if you need more control and customization and want to get the most out of the developer tools then definitely go for react-query.

That's it for today. Hopefully, now you have a better understanding of how these 2 libraries compare to each other.

Have a wonderful day!




Continue Learning