About one year ago, we announced the TanStack Query v5 roadmap, and the whole team has been working hard on that version ever since. So we're super happy to announce that today is the day: After 91 alpha releases, 35 betas and 16 release candidates, TanStack Query v5.0.0 is finally here! 🎉
v5 continues the journey of v4, trying to make TanStack Query smaller (v5 is ~20% smaller than v4), better and more intuitive to use. One of the main focus points for this release was around streamlining and simplifying the APIs we offer:
As a big breaking change, we've removed most overloads from the codebase, unifying how you use useQuery and other hooks. This is something we wanted to do for v4, but a TypeScript limitation prevented us from doing that. TypeScript addressed this issue in TS 4.7, so we were able to remove all the overloads that we had for calling useQuery with a different amount of parameters. This is a huge DX win, because methods with overloads usually have quite bad TypeScript error messages.
This is the biggest breaking change in v5, but we think it's worth it. The API is now much more consistent - you always just pass one object. To alleviate the pain of changing all occurrences manually, we have tried to prepare everyone for this coming change for the last months. The documentation was changed to use the new API, and we released an auto-fixable eslint rule in our eslint package. Additionally, v5 comes with a codemod to help with the transition.
Apart from that, we've renamed cacheTime to gcTime to better reflect what it is doing, merged keepPreviousData with placeholderData, renamed loading states to pending and removed the callbacks from useQuery. All these changes make v5 the most consistent and best version for new starters.
To read more about the breaking changes, have a look at our migration guide.
Of course, v5 comes loaded with amazing new features as well 🚀:
Enjoy a brand new, simplified way to perform optimistic updates by leveraging the returned variables from useMutation, without having to write code that updates the cache manually. For more details, have a look at the optimistic updates documentation
A frequently requested feature, as seen in this two-year-old issue, finally comes to life in v5: You can now get access to the state of all mutations, shared across components thanks to the new useMutationState hook.
That's right - suspense for data fetching is no longer experimental, but fully supported. React Query ships with new useSuspenseQuery, useSuspenseInfiniteQuery and useSuspenseQueries hooks. Have a look at the suspense docs to learn about the differences to the non-suspense versions.
v5 also comes with an experimental integration for suspense on the server in nextJs, unifying the best of both worlds: The react-query-next-experimental adapter allows us to write a single useSuspenseQuery, which will initiate data fetching as early as possible: on the server, during SSR. It will then stream the result to the client, where it will be put into the cache automatically, giving us all the interactivity and data synchronization of React Query.
Infinite Queries can now prefetch multiple pages at once, and you have the option to specify the maximum amount of pages stored in the cache as well.
The Query devtools have been re-written from scratch in a framework-agnostic way to make them available to all adapters. They also got a UI revamp and some new features like cache inline editing and light mode.
Another long-standing discussion from 2021 highlights the importance of fine-grained persistence with just-in-time restore capabilities (especially for mobile development) that the PersistQueryClient plugin doesn't have. With v5, we now have a new experimental_createPersister plugin that allows you to persist queries individually.
Now that we have a unified way to call useQuery (with just one object as parameter), we can also build better abstractions on top of that. The new queryOptions function gives us a type-safe way to share our query definitions between useQueryand imperative methods like queryClient.prefetchQuery. On top of that, it can make queryClient.getQueryData type-safe as well.
We hope you're going to enjoy using v5 as much as we've enjoyed building it. What's left for us to say thanks to everyone who made this release possible. No matter if you're core contributor, implemented an issue from the roadmap, if you've fixed a typo in the docs or gave feedback on the alpha releases: Every contribution matters! It's the people that makes this library great, and we're blessed to have such an amazing community. ❤️