NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #3808 most downloaded on npm
The shared core for the highly customizable and versatile GraphQL client
Last release 3 months ago
22 Jun 2026
Release timing varies
gaps range from 2 weeks to 10 months
Nearly every release is documented
notes for 56 of the last 60 stable releases
4 versions withdrawn
withdrawn after publishing
7 years old
283 releases · first in 2020
One column per quarter.
Allow providing a custom isSubscriptionOperation implementation, by @n1ru4l (See #2534)
Add Accept header to GraphQL HTTP requests. This complies to the specification but doesn't go as far as sending Content-Type which would throw a lot o
Accept header to GraphQL HTTP requests. This complies to the specification but doesn't go as far as sending Content-Type which would throw a lot of APIs off. Instead, we'll now be sending an accept header for application/graphql+json, application/json to indicate that we comply with the GraphQL over HTTP protocol.
This also fixes headers merging to allow overriding Accept and Content-Type regardless of the user options' casing, by @kitten (See #2457)withPromise cases, by @JoviDeCroock (See #2446)text/* as error messages, by @kitten (See #2456)cut off url when using the GET method at 2048 characters (lowest url-size coming from chromium), by @JoviDeCroock (See #2384)
url when using the GET method at 2048 characters (lowest url-size coming from chromium), by @JoviDeCroock (See #2384)toPromise() return would not result in the stream tearing down, by @JoviDeCroock (See #2386)Prevent ignored characters in GraphQL queries from being replaced inside strings and block strings. Previously we accepted sanitizing strings via regu
Undo logic to catch errors from incremental fetching and forking the response stream, introduce logic to detect results, by @JoviDeCroock (See #2287)
⚠️ Fix mutation operation being used as compared identity and instead add a stand-in comparison, by @kitten (See #2228)
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Omit minified files and sourcemaps' sourcesContent in published packages Submitted by @kitten (See #3755)
Mark @urql/core as a peer dependency as well as a regular dependency Submitted by @kitten (See #3579)
Nothing published for this version
Mark @urql/core as a peer dependency as well as a regular dependency Submitted by @kitten (See #3579)
share calls, since @urql/core’s composeExchanges utility now automatically does so for us
Submitted by @kitten (See #3082)getOperationName export from @urql/core
Submitted by @kitten (See #3062)wonka@^6.3.0
Submitted by @kitten (See #3104)authExchange() will now block and pass on errors if the initialization function passed to it fails, and will retry indefinitely. It’ll also output a w
authExchange() will now block and pass on errors if the initialization function passed to it fails, and will retry indefinitely. It’ll also output a warning for these cases, as the initialization function (i.e. authExchange(async (utils) => { /*...*/ })) is not expected to reject/throw
Submitted by @kitten (See #3343)Handle refreshAuth rejections and pass the resulting error on to OperationResults on the authentication queue Submitted by @kitten (See #3307)
⚠️ Fix regression that caused teardowns to be ignored by an authExchange’s retry queue Submitted by @kitten (See #3235)
Update build process to generate correct source maps Submitted by @kitten (See #3201)
Publish with npm provenance Submitted by @kitten (See #3180)
⚠️ Fix operations created by utilities.mutate() erroneously being retried and sent again like a regular operation Submitted by @JoviDeCroock (See #316
utilities.mutate() erroneously being retried and sent again like a regular operation
Submitted by @JoviDeCroock (See #3164)useQuery from re-executing (and hitting the network) during SSR hydration when it's awaited for Suspense. Awaiting the query subscribed to the operation a second time, which re-dispatched it after the ssrExchange result had already been consumed, triggering a redundant network request even with staleWhileRevalidate: false. The awaited promise now resolves with the already-settled result instead of re-subscribing
Submitted by @JoviDeCroock (See #3884)await useQuery() in Vue to wait on the composable's existing reactive state instead of creating an additional query source subscription
Submitted by @JoviDeCroock (See #3890)Add minimumTime to refocusExchange to throttle query reexecution Submitted by @ThaUnknown (See #3825)
minimumTime to refocusExchange to throttle query reexecution
Submitted by @ThaUnknown (See #3825)share calls, since @urql/core’s composeExchanges utility now automatically does so for us
Submitted by @kitten (See #3082)sourcesContent, including additional source files, and had incorrect paths in some of them
Submitted by @kitten (See #3053)wonka@^6.3.0
Submitted by @kitten (See #3104)didAuthError keeps returning true
Submitted by @JoviDeCroock (See #3112)context option, which may be set to a context value or a function returning a context, can now return a Promise and will be correctly resolved and awaited, by @YutaUra (See #2806)provideClient, install, useClient, and useClientHandle. Multiple clients can be provided and consumed under different keys; default key remains '$urql' for backward compatibility
Submitted by @albertcito (See #3858)Implement new authExchange API, which removes the need for an authState (i.e. an internal authentication state) and removes getAuth, replacing it with
authExchange API, which removes the need for an authState (i.e. an internal authentication state) and removes getAuth, replacing it with a separate refreshAuth flow.
The new API requires you to now pass an initializer function. This function receives a utils
object with utils.mutate and utils.appendHeaders utility methods.
It must return the configuration object, wrapped in a promise, and this configuration is similar to
what we had before, if you're migrating to this. Its refreshAuth method is now only called after
authentication errors occur and not on initialization. Instead, it's now recommended that you write
your initialization logic in-line.authExchange(async utils => {
let token = localStorage.getItem('token');
let refreshToken = localStorage.getItem('refreshToken');
return {
addAuthToOperation(operation) {
return utils.appendHeaders(operation, {
Authorization: `Bearer ${token}`,
});
},
didAuthError(error) {
return error.graphQLErrors.some(
e => e.extensions?.code === 'FORBIDDEN'
);
},
async refreshAuth() {
const result = await utils.mutate(REFRESH, { token });
if (result.data?.refreshLogin) {
token = result.data.refreshLogin.token;
refreshToken = result.data.refreshLogin.refreshToken;
localStorage.setItem('token', token);
localStorage.setItem('refreshToken', refreshToken);
}
},
};
});
Submitted by @kitten (See #3012)willAuthError not being called for operations that are waiting on the authentication state to update. This can actually lead to a common issue where operations that came in during the authentication initialization (on startup) will never have willAuthError called on them. This can cause an easy mistake where the initial authentication state is never checked to be valid
Submitted by @kitten (See #3017)wonka@^6.0.0), which has no breaking changes but is built to target ES2015 and comes with other minor improvements.
The library has fully been migrated to TypeScript which will hopefully help with making contributions easier!, by @kitten (See #2504)wonka@^6.0.0), which has no breaking changes but is built to target ES2015 and comes with other minor improvements.
The library has fully been migrated to TypeScript which will hopefully help with making contributions easier!, by @kitten (See #2504)babel-plugin-modular-graphql helper, this because the graphql package hasn't converted to ESM yet which gives issues in node environments, by @JoviDeCroock (See #2551)Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →