I Switched From Apollo To Urql (And It Was Worth It)

Wendy de Kock
JavaScript in Plain English
4 min readJun 10, 2021

--

In this article we’ll look into Urql as a replacement for Apollo. We will have a look at the practical side of switching out Apollo for Urql and the effect it had on my (Next.js) project.

If you read this article I am going to assume that you either have a GraphQL client implemented and are interested in other options or you are looking to implement a GraphQL client. This is why I’ll assume you know what GraphQL is and what it does.

Some other useful information, in this project I am using Next.js in the front-end with SSG (Static Site Generation), Express and GraphQL in the backend with a MongoDB database. The project I‘m working on and am passionate about is winkt.io (we love ink), a platform to expand the appreciation for tattoo art.

Making the Switch to Urql (how to implement)

The current Apollo implementation in this project is based on the with-apollo example from next.js. We can replace this with our new urqlClient:

urqlClient.js

To use Urql we need to create a client. The createClient function from Urql firstly takes in the url we are connecting with. Secondly we set the exchanges. If we wouldn’t define the exchanges Urql sets the default exchanges as exchanges: [dedupExchange, cacheExchange, fetchExchange].

dedupExchange — is responsible for deduplicating operations.
cacheExchange — is responsible for caching GraphQL API responses based on the unique query + variables (document cache).
fetchExchange — sends GraphQL requests using fetch and supports cancellation by default.

In our urqlClient we define the exchanges to add ssrCache. The order of exchanges matters, the most important thing is that fetchExchange needs to go last since it is asynchronous.

The ssrCache will allow us to collect all outcomes as they are being fetched on the server side and sent them to the client. On the client-side we can use the outcomes to avoid refetching the data.

Now that we’ve created our urqlClient we can wrap our application in urql’s provider. We can achieve this by overriding the Next.js _app component. Here we can also rehydrate the client with data from the server. There is currently nothing in our urqlState in the pageProps, but we will change this soon. Let’s take a look at our _app.js:

pages/_app.js

Updating components

Let’s have a look at the changes that need to be made in a component that queries GraphQL data. In this example I use getStaticProps to make use of SSG, if you would like to make use of SSR you can swap getStaticProps for getServerSideProps.

Underneath you’ll find a stripped down version of a component that queries data, the first example uses Apollo, the second one uses Urql. You can check out the comments in the Urql version for more information.

Component that queries with Apollo
Component that queries with Urql

We’ll also look at the difference in Mutations using an example component. Again you’ll find some details in the comments of the Urql version.

Component that performs a mutation with Apollo
Component that performs a mutation with Urql

Lastly if you have a component that displays GraphQL errors you need to replace ‘[GraphQL]’ instead of ‘GraphQL error: ’. And that’s it, we now successfully implemented Urql.

Results

First Load JS shared by all from 132kb to 95kb.
From 2.1s to 626ms in GraphQL calls on the product page

And an increase in the Google PageSpeed score. The mobile score went from 41 to 65 and desktop from 65 to 95.

Final notes

  • I use GraphQL data in almost all my pages so it makes sense to wrap my entire application in the Urql provider. If this is not the case for you, you could use a HOC for Urql.
  • The default caching strategy in Urql is document cache, you can also use normalized cache to prevent unnecessary calls and tell Urql which updates need to be made after a mutation.

This was my first technical blog post, I hope you enjoyed it and if you have any feedback for me please let me know in the comments.

More content at plainenglish.io

--

--

Front-end dev with a passion for Typescript / Vue / React / GraphQL / SSR, clean code and performance. I also love tattoos!