We're Evaluating a New Default GraphQL Client: Discussion Wanted

As the title says, we’re evaluating a new default GraphQL client, and we want to hear what you think about what we think.

Redwood right now: Apollo Client v3

Right now, Redwood uses Apollo Client. Apollo Client’s a complex tool, and on top of that, Apollo Client v3 just came out. It’s not a complete overhaul of v2 by any means, but some key things did change.

None of us are Apollo Client experts; if you are, we’d especially love to hear from you!

But even before that, many of us have had problems with Apollo Client. And it’s usually because of the cache. A fair share of the problems I’ve debugged on Discord have been about why some optimistic update didn’t work (or even how to do it in the first place), or why a Cell didn’t refresh.

We all know: caching is hard. No one’s saying it’s not. Updating a record with Apollo Client isn’t too bad, but creating and deleting one seems needlessly complex… Of course you always hope that it’s not needlessly complex for no reason. And there are a whole bunch of reasons for it to be the way it is (TL;DR normalization). But then it makes you wonder: do we really need normalization in the first place? Sure, we might want it at some point, but out of the gate? It just doesn’t seem to be what most users are worried about.

In some sense, which GraphQL client Redwood uses should be an implementation detail. But in some places, like Scaffolds, it surfaces. Since scaffolds are in many ways, the way that people learn Redwood, we have to be a little more careful.

Redwood’s goals

In considering all this, we always have to remember Redwood’s goals: what does Redwood want to be, do, offer?

The mantra that probably comes to all of our minds: convention over configuration. Another is “make easy things easy and hard things possible”. Redwood should be, by default, providing what you probably want, but also let you change it.

So is Apollo Client what you probably want? And if it’s not, are we letting you change it? Both of these questions are the premise for our evaluation and this post.

Evaluating a new default GraphQL client: urql

We’re thinking about making urql Redwood’s default GraphQL client.

Why urql? We’re still doing our research, but here’s one aspect we know we like right off the bat: it’s more layered. Not everyone needs a complex cache (or even a cache at all), and especially not right out of the box. urql’s more basic document caching, with its aggressive invalidation, is, in the beginning, probably more than enough. And if you want normalization, you can add it with Graphcache.

But what would it actually mean if we switched?

It really does depend on your app, but Redwood’s still really early, so we’re going to optimistically say: not much! At least not much more than the switch from Apollo Client v2 to v3 anyway :sweat_smile:.

The only thing that we can say for sure is that you’d have to provide a useQuery hook to Cells so that we can make Cells work with whatever GraphQL client you choose to use.

But I like Apollo Client! Would I still be able to use it?

Yes! This change would make it possible to configure a GraphQL client of your choice, while still providing a sane default (right now, the candidate for that is urql) if you choose not to.

We’re still early in the process, but we want to know what you think now before we get too into the weeds. Thanks for reading and please let us know!


I really love Apollo Server (which Redwood also uses). It automatically makes me fetch for Apollo Client, but I agree that Apollo Client is not the golden goose it seems to be. There doesn’t seem to be a benefit with using both Apolllo Server and Client… In a Redux project it also awkwardly overlaps with some Redux responsibilities. For a big client, we are also thinking about replacing it with urql, however we don’t have any experiences yet to share.

What about just disabling Apollo Client caching?

1 Like

We love Apollo Server too and have no intention of changing that!

In a Redux project it also awkwardly overlaps with some Redux responsibilities.

On top of being a cache management solution, Apollo Client tries to be a state management solution as well so that makes sense. That’s another reason we’re not sure about Apollo Client. State management is one of the most complex topics in React, in that there’s so many solutions. And we’re not sure if we should be advocating for any one of them just yet.

What about just disabling Apollo Client caching?

We totally could, but then it kind of makes you wonder why we’re using it in the first place :thinking:.

Apollo Client (especially v3) seems really powerful in that it’s kind of like having another layer of resolvers for your graphql sdl but on the client side. So if you’re developing something like an offline-first application, it might be really great because you could check if the query’s in local storage or something before hitting the server. But right now that’s another layer of configuration where the best practices aren’t really well defined, or defined at all.

1 Like

I’ve done some experiments today with using graphql-hooks.


Have you looked at graphql-hooks’ SSR or memcache plugins? The smaller bundle size is nice, but I know that some people (and by some people I mean Burnsy) who are perfectly happy with Apollo and will still want to stick with them if bundle size was the only benefit.

But if graphql-hooks can also address caching issues along with providing a solution for SSR then it would be a much more compelling option.

I have looked at the memcache plugin. In fact, I even created a PR for Redwood that includes both graphql-hooks and the memcache plugin

“caching issues” is an interesting topic. I think we first have to define what exactly it is we need and want. Then we can go find a graphql client that can help us achieve those goals. Same thing with the SSR stuff really, we need to know what our story is going to be around that stuff before we know what a good fit would be.

Personally my biggest problem with Apollo Client is that it conflicts with another (totally unrelated) library I have to use. So I have to replace it. Except you can’t really currently, all you can do is use something else in addition to AC. And since you can’t get rid of what RW bundles, I figure it makes sense for the bundled option to be as small as possible.

So for an existing redwood project, would no changes be expected for this to work? if there are changes, where would the changes be required?

I really like the idea that we could also choose which client to use.

My take on this is this: RedwoodJS has allowed me to finally get into developing a full-stack application and actually be able to understand what is going on by getting me out of the weeds of needing to do everything to get a project running and for that I am very grateful. So as long as the implementation remains effective for keeping the best developer experience available I would think it makes sense to reduce the complexity of the core and allow the developers to add complexity when they need it. I have looked at both the Apollo and urql docs and from an API side they are very similar, at least at my limited level of experience. I know (at least believe I do) with the app I am currently developing that I would need the Graphcache exchange as I think that normalized data would fit what I am building better than a document cache, but I could be wrong (if so, wouldn’t even be the first time today).

Overall, the most impressive thing that I have found about Redwood is that it just works out of the box, I have been telling many other folks I know that are trying to get into development, even for just the sake of understanding what our core development team does, that Redwood is a great platform for not just building apps but learning how to build apps. Let’s make sure that doesn’t get broken


Redwood will 100% continue to ship with a GraphQL Client that Just Works™ straight out of the box. We want the developer experience to be great with what you get after the first install.

For existing projects that upgrade to a new RW version that comes with a new gql client some code modifications might be necessary. If that’s the case we will make sure to mention it in the release notes. Already now you can change the client that you and RW uses. The code for that landed in (I think) the last release. But it’s not documented yet because it’s not production ready. Especially needs some work around the TS types. Using a custom gql client will require extra code. So that’s always going to be more work than just using whatever RW has as its default client.

@viperfx @mbush92 I hope this answered both of your questions. If not, please feel free to ask again :slightly_smiling_face:


When people talking about ditching Apollo Client, it’s more about its peformance problem, bundle size is not nice as well. Apollo said they solve it in v3. But do not know, but currently does not see much problems arising.

A big candidate would Relay.js from Facebook, I used it for a year, the DX is top notch, being able to declare the data requirement of a component in its own file with fragment, without changing props every time the data requirements changes is huge, also, it support concurrent React already (send request outside of React lifecycle)

My rough idea is Redwood can extend the current concept of cell, but the problem is the backend, which requires a cursor based pagination (where Prisma already supports it), and a node () query for all entities, not hard though, just some potential blockers.

  • Relay is fast(Pinterest ditched Apollo and embraced Relay and they love it),
  • opinionated (which is good for RW, since Relay’s output is very predictable),
  • it can also hash queries, so we can close all unexpected queries.
  • Concurrent mode ready (a big chunk of boilerplate code to setup but not a problem for RW since we can embed it).
  • Typescript ready and great built-in code-gen.
  • And FB is using it, so stable and long term support.

Downside would be too strict, might conflict with RW’s flavor. And potential diverse in the future since it’s a FB product so always values FB requirement first.


Hey Albert, thanks so much for the detailed write up about Relay! I know that once we had a React Query provider created a lot of people were excited, tried it out, and loved it. If we had something similar for Relay I can imagine many people would check it out, but until that is the case the switching cost will be a bit too high for the average Redwood developer. Just some food for thought.