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.
Drop internal type switch between graphql and @0no-co/graphql.web's types, since the latter now does this already automatically Submitted by @kitten (
Prevent reusal of incoming API data in Graphcache’s produced (“owned”) data. This prevents us from copying the __typename and other superfluous fields
__typename and other superfluous fields
Submitted by @kitten (See #3165)@defer directives from becoming “sticky” and causing every subsequent cache read to be treated as if the field was deferred
Submitted by @kitten (See #3167)hasNext: true and fallthrough logic to cached queries that contain deferred, uncached fields. Deferred query results will now be fetched against the API correctly, even if prior requests have been incomplete
Submitted by @kitten (See #3163)offlineExchange duplicating offline mutations in failed queue
Submitted by @kitten (See #3158)mapExchange from forwarding async-mapped operations after their teardown has already been received
Submitted by @JoviDeCroock (See #3879)payload property in makeResult so that the first incremental/multipart response is parsed correctly. Previously, transports that wrap each result in a payload property (e.g. Apollo Federation's multipart subscriptions) would have their first response dropped as "No Content", while subsequent responses were handled correctly by mergeResultPatch
Submitted by @JoviDeCroock (See #3881)exports field from the generated subpath package.json files (e.g. @urql/exchange-graphcache/extras, @urql/exchange-graphcache/default-storage, @urql/core/internal, @urql/next/rsc). These targets pointed at the parent dist/ directory (../dist/...), which violates the Node.js package-exports spec requirement that every exports target begin with ./. Metro (Expo 53 / React Native 0.79) validates this and logged a warning for every affected package. Subpath resolution continues to work: exports-aware bundlers resolve through the root package.json, while legacy resolution relies on the main/module/types fields that remain in place
Submitted by @JoviDeCroock (See #3886)Use nullish coalescing for preferGetMethod and preferGetForPersistedQueries so that false is kept if set Submitted by @dargmuesli (See #3812)
preferGetMethod and preferGetForPersistedQueries so that false is kept if set
Submitted by @dargmuesli (See #3812)Nothing published for this version
Remove dependence on graphql package and replace it with @0no-co/graphql.web, which reduces the default bundlesize impact of urql packages to a minimu
graphql package and replace it with @0no-co/graphql.web, which reduces the default bundlesize impact of urql packages to a minimum. All types should remain compatible, even if you use graphql elsewhere in your app, and if other dependencies are using graphql you may alias it to graphql-web-lite
Submitted by @kitten (See #3097)OperationResult.hasNext and OperationResult.stale to be required fields. If you have a custom exchange creating results, you'll have to add these fields or use the makeResult, mergeResultPatch, or makeErrorResult helpers
Submitted by @kitten (See #3061)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)stringifyDocument in offlineExchange rather than print and serialize operation.extensions as needed
Submitted by @kitten (See #3094)hasNext and stale passthroughs on caching exchanges
Submitted by @kitten (See #3059)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
export the getOperationName utility function Submitted by @giacomocerquone (See #3785)
isOfflineError option to the offlineExchange to allow it to be customized to different conditions to determine whether an operation has failed because of a network error
Submitted by @robertherber (See #3020)updates config to react to arbitrary type updates other than just Mutation and Subscription fields.
You’ll now be able to write updaters that react to any entity field being written to the cache,
which allows for more granular invalidations. Note: If you’ve previously used updates.Mutation
and updated.Subscription with a custom schema with custom root names, you‘ll get a warning since
you’ll have to update your updates config to reflect this. This was a prior implementation
mistake!
Submitted by @kitten (See #2979)stale: true flag added to them. This is a regression from https://github.com/urql-graphql/urql/pull/2831 and only applies to cacheExchanges that had the schema option set
Submitted by @kitten (See #2999)invariant to data layer that prevents cache writes during cache query operations. This prevents cache.writeFragment, cache.updateQuery, and cache.link from being called in resolvers for instance
Submitted by @kitten (See #2978)Nothing published for this version
Correct typo in cacheHit debug message of the debugExchange Submitted by @jorrit (See #3773)
debugExchange
Submitted by @jorrit (See #3773)fetchSource not text-decoding response chunks as streams, which could cause UTF-8 decoding to break
Submitted by @i110 (See #3767)console.debug rather than console.log
Submitted by @kitten (See #3770)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)
Nothing published for this version
Remove addMetadata transform where we'd strip out metadata for production environments, this particularly affects OperationResult.context.metadata.cac
addMetadata transform where we'd strip out metadata for production environments, this particularly affects OperationResult.context.metadata.cacheOutcome
Submitted by @alpavlove (See #3714)Nothing published for this version
⚠️ Fix deepMerge regression on array values Submitted by @JoviDeCroock (See #3696)
deepMerge regression on array values
Submitted by @JoviDeCroock (See #3696)teardown is received. This bug could be triggered when a shared query operation triggers again and causes a cache miss (e.g. due to an error). The re-execution of the operation would then be blocked as Graphcache considered it a "reexecution loop" rather than a legitimate execution triggered by the UI. (See https://github.com/urql-graphql/urql/pull/2737 for more information), by @kitten (See #2876)Nothing published for this version
Remove for-of syntax from @urql/core helpers for JSC memory reduction Submitted by @kitten (See #3690)
Nothing published for this version
Allow empty error messages when re-hydrating GraphQL errors Submitted by @JoviDeCroock (See #3650)
Nothing published for this version
Removes double serialization of data in ssrExchange Submitted by @negezor (See #3632)
Nothing published for this version
Change how we calculate the OperationKey to take files into account, before we would encode them to null resulting in every mutation with the same var
OperationKey to take files into account, before we
would encode them to null resulting in every mutation with the same variables
(excluding the files) to have the same key. This resulted in mutations that upload
different files at the same time to share a result in GraphCache
Submitted by @JoviDeCroock (See #3601)Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Use documentId from persisted documents for document keys, when it's available Submitted by @kitten (See #3575)
⚠️ Fix issue where a reexecute on an in-flight operation would lead to multiple network-requests. For example, this issue presents itself when Graphca
DocumentNode AST when updating the cache, to prevent results after a network request from differing and breaking referential equality due to added __typename fields, by @kitten (See #2736)undefined fields), which previously actually caused a hidden cache miss, which may then affect a subsequent non-optimistic mutation result, by @kitten (See #2740)@urql/core only, this change also affects the offlineExchange in @urql/exchange-graphcache due to it relying on the identity being previously an object rather than an integer, by @kitten (See #2732)Nothing published for this version
Use nullish coalescing for preferGetMethod and preferGetForPersistedQueries so that false is kept if set Submitted by @dargmuesli (See #3812)
preferGetMethod and preferGetForPersistedQueries so that false is kept if set
Submitted by @dargmuesli (See #3812)Nothing published for this version
…when the generic is set or inferred. This is a breaking change for TypeScript users potentially, unless all types are adhered to, by @kitten (See #260…
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)fragmentName for write and read operations, by @JoviDeCroock (See #2609)optimistic option now accepts optimistic mutation resolvers that return fields by
name rather than alias. Previously, depending on which mutation was run, the optimistic resolvers
would read your optimistic data by field alias (i.e. "alias" for alias: id rather than "id").
Instead, optimistic updates now correctly use field names and allow you to also pass resolvers as
values on your optimistic config, by @JoviDeCroock (See #2616)dedupExchange
Submitted by @JoviDeCroock (See #3520)maskTypename
Submitted by @JoviDeCroock (See #3520)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
Mark @urql/core as a peer dependency as well as a regular dependency Submitted by @kitten (See #3579)
multipart/mixed responses (result properties essentially are namespaced on a payload key)
Submitted by @JoviDeCroock (See #3499)DocumentNode with no/empty definitions and a documentId property is considered a persisted document. When this is detected a documentId parameter rather than a query string is sent to the GraphQL API, similar to Automatic Persisted Queries (APQs). However, APQs are only supported via @urql/exchange-persisted, while support for documentId is now built-in
Submitted by @kitten (See #3515)url to be a plain, non-URL pathname (i.e. /api/graphql) to be used with preferGetMethod
Submitted by @akrantz01 (See #3514)Headers class being used in fetchOptions
Submitted by @JoviDeCroock (See #3505)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
Omit minified files and sourcemaps' sourcesContent in published packages Submitted by @kitten (See #3755)
Your coding agent can read these notes before it upgrades. Set up the MCP server →