Packages

@apollo/client

4.3.5 · 19 Oct 2026MIT5.3M / weekRepositoryHomepagenpmAtom feed

Your version

209 stable releases, newest first, by release line. Notes are quoted as the maintainers published them.

  1. 4.x · latest line
  2. 4.3.5

    19 Oct 2026
    • Fix an issue where custom scalar values that are not JSON-serializable caused errors. These values are properly serialized when used as input for variables or when used as a key field value so that cache writes and calls to cache.identify succeed.

    • Require the variables option in useFragment when the fragment has required variables. This matches the behavior of useSuspenseFragment and the query hooks.

    • Parse custom scalar fields in subscription results when using the no-cache fetch policy.

  3. 4.3.4

    16 Oct 2026
    • Fix an issue where a list field selected more than once with different selection sets lost the fields that only one of the selections included while a @defer boundary elsewhere in the query was still pending when using the GraphQL17Alpha9Handler. The results of all selections of the list field are now merged.

    • Fixed a bug where streamFieldInfo might not have been passed into custom merge functions for @stream directives that had an aliased field in the path.

    • Fix Missing field errors being logged when writing @defer results where a parent field is selected both inside and outside of a deferred fragment. Fields whose @defer boundary has not been delivered from the network are no longer reported as missing.

  4. 4.3.3

    8 Oct 2026
    • Fix a memory leak in isDeferredFragment/isStreamField

  5. 4.3.2

    5 Oct 2026
    • Fix an unhandled AbortError promise rejection that occurred when unsubscribing from a multipart HTTP subscription.

  6. 4.3.1

    18 Sep 2026
    • Fix an issue where useLazyQuery did not rerender with new variables until the network request had completed when calling execute with new variables while a request was already in-flight.

  7. 4.3.0

    11 Sep 2026
    • removed

      Remove the optional modifier from the variables property provided to the update function in client.mutate and useMutation. variables is always a defined object, even when variables are not provided to the mutation.

    • deprecated

      Mark skip as deprecated in useQuery and useSubscription now that both of these hooks support skipToken.

    • Field policies and inputObjects can now tell the cache whether a field is a list of scalars or a scalar whose value is an array. Previously all arrays were iterated and only the inner type was provided to the scalar parse/serialize functions.

      This required some breaking changes from previous prerelease versions:

      new InMemoryCache({
        scalars: {
          DateTime: new Scalar(/*...*/),
        },
        inputObjects: {
          EventFilter: {
            fields: {
              // Previously only the scalar type was provided
              datesBefore: "DateTime",
      
              // List syntax now required
              datesAfter: "[DateTime]",
              dates2d: "[[DateTime]]",
            },
          },
        },
        typePolicies: {
          Event: {
            fields: {
              // Previously only the scalar type was provided
              datesBefore: {
                scalar: "DateTime",
              },
      
              // List syntax now required
              datesAfter: {
                scalar: "[DateTime]",
              },
              dates2d: {
                scalar: "[[DateTime]]",
              },
            },
          },
        },
      });

      Now it's possible to handle scalars that are represented by arrays:

      const dateTimeRangeScalar = new Scalar<
        [string, string],
        { start: Date; end: Date }
      >({
        parse: ([start, end]) => ({
          start: new Date(start),
          end: new Date(end),
        }),
        serialize: (range) => [range.start.toISOString(), range.end.toISOString()],
        is: (value) => !Array.isArray(value),
      });
      
      const cache = new InMemoryCache({
        scalars: {
          DateTimeRange: dateTimeRangeScalar,
        },
        typePolicies: {
          Event: {
            fields: {
              range: {
                scalar: "DateTimeRange",
              },
            },
          },
        },
      });
      
      const query = gql`
        query {
          event {
            range
          }
        }
      `;
      
      cache.writeQuery({
        query,
        data: {
          event: {
            __typename: "Event",
            // Server returns DateTimeRange as a JSON array
            range: ["2024-01-01T00:00:00Z", "2024-06-01T00:00:00Z"],
          },
        },
      });
      
      const { data } = useQuery(query);
      // => { event: { __typename: "Event", range: { start: Date, end: Date } } }
  8. 4.2.12

    14 Aug 2026
    • Preserve multi-byte UTF-8 characters split across multipart response chunks.

  9. 4.2.11

    11 Aug 2026
    • Fix type signature of some DocumentationTypes to fix their display in our documentation.

    • Add a development-only warning when a network result is written to the cache but reading the query back from the cache returns a partial result. This usually points at a merge or read function that did not repair missing fields in the cache, which prevents Apollo Client from applying the cache result to the data received by the network.

  10. 4.2.10

    5 Aug 2026
    • Fix accidental widening of the client.mutate return type when optimisticResponse was present.

    • Fix result types widened when a query's variables had constant types (e.g. TypedDocumentNode<Data, { type: "main" }>). This caused options such as returnPartialData or errorPolicy to be reported as their widened types (e.g. boolean, ErrorPolicy) instead of the value that was passed which returned the wrong data and dataState types.

    • Fix issue where unknown options were permitted by TypeScript when passed alongside a valid option to APIs with modern signatures.

  11. 4.2.9

    30 Jul 2026
    • Fix a bug where GraphQL variable default values were not applied during cache reads when variables with defaults were explicitly set to undefined. This caused @include/@skip directives to throw "Invalid variable referenced" errors when the variable was passed as undefined instead of being omitted entirely.

    • Fix an issue where some @export queries would not react to cache updates when the fields keyed by exported variables were updated.

  12. 4.2.8

    23 Jul 2026

    Maintenance only: docs, tests, build or refactoring. Nothing changes in how you use it.

  13. 4.2.7

    13 Jul 2026
    • Cleanup some unused internals. Please file an issue if you notice anything change.

  14. 4.2.6

    6 Jul 2026
    • Prevent relay multipart subscriptions from issuing a fetch request after serializing the request body fails.

    • Speed up cache writes by avoiding a full AST visit of every written field to detect @stream. The check now runs only when the result carries stream info, and only inspects the field node's own directives. As a result, fields that merely contain @stream on a nested field are no longer treated as streamed themselves and now overwrite existing lists like regular fields instead of merging chunk-wise.

  15. 4.2.5

    1 Jul 2026
    • Export KeyArgsFunction and RelayFieldPolicy types from public entrypoints.

  16. 4.2.4

    30 Jun 2026
    • Fixes an issue where client.readFragment and client.readQuery ignored the optimistic option when passed in the options object.

  17. 4.2.3

    8 Jun 2026
    • Add support for graphql v17 as a valid peer dependency.

  18. 4.2.2

    3 Jun 2026
    • Preserve referential equality of masked data on refetch when the result is deeply equal to the previous result.

  19. 4.2.1

    2 Jun 2026
    • Fixes an issue where useLazyQuery would not apply a changed pollInterval between renders.

  20. 4.2.0

    20 May 2026
    • Introduce "classic" and "modern" method and hook signatures.

      Apollo Client 4.2 introduces two signature styles for methods and hooks. All signatures previously present are now "classic" signatures, and a new set of "modern" signatures are added alongside them.

      Classic signatures are the default and are identical to the signatures before Apollo Client 4.2, preserving backward compatibility. Classic signatures still work with manually specified TypeScript generics (e.g., useSuspenseQuery<MyData>(...)). However, manually specifying generics has been discouraged for a long time—instead, we recommend using TypedDocumentNode to automatically infer types, which provides more accurate results without any manual annotations.

      Modern signatures automatically incorporate your declared defaultOptions into return types, providing more accurate types. Modern signatures infer types from the document node and do not support manually passing generic type arguments; TypeScript will produce a type error if you attempt to do so.

      Methods and hooks automatically switch to modern signatures the moment any non-optional property is declared in DeclareDefaultOptions. The switch happens across all methods and hooks globally:

      // apollo.d.ts
      import "@apollo/client";
      declare module "@apollo/client" {
        namespace ApolloClient {
          namespace DeclareDefaultOptions {
            interface WatchQuery {
              errorPolicy: "all"; // non-optional → modern signatures activated automatically
            }
          }
        }
      }

      Users can also manually switch to modern signatures without declaring any defaultOptions, for example when wanting accurate type inference without relying on global defaultOptions:

      // apollo.d.ts
      import "@apollo/client";
      declare module "@apollo/client" {
        export interface TypeOverrides {
          signatureStyle: "modern";
        }
      }

      Users can do a global DeclareDefaultOptions type augmentation and then manually switch back to "classic" for migration purposes:

      // apollo.d.ts
      import "@apollo/client";
      declare module "@apollo/client" {
        export interface TypeOverrides {
          signatureStyle: "classic";
        }
      }

      Note that this is not recommended for long-term use. When combined with DeclareDefaultOptions, switching back to classic results in the same incorrect types as before Apollo Client 4.2—methods and hooks will not reflect the defaultOptions you've declared.

    • Improve the accuracy of client.query return type to better detect the current errorPolicy. The data property is no longer nullable when the errorPolicy is none. This makes it possible to remove the undefined checks or optional chaining in most cases.

    • Add support for automatic event-based refetching, such as window focus.

      The RefetchEventManager class handles automatic refetches in response to events. Apollo Client provides built-in sources for window focus and network reconnect as windowFocusSource and onlineSource.

      Event refetching is fully opt-in. Create and pass a RefetchEventManager instance to the ApolloClient constructor to activate the event listeners.

      import {
        ApolloClient,
        InMemoryCache,
        RefetchEventManager,
        windowFocusSource,
        onlineSource,
      } from "@apollo/client";
      
      const client = new ApolloClient({
        link,
        cache: new InMemoryCache(),
        refetchEventManager: new RefetchEventManager({
          sources: {
            // Refetch when window is focused
            windowFocus: windowFocusSource,
      
            // Refetch when the user comes back online
            online: onlineSource,
          },
        }),
      });

      By default, all active queries refetch when the events fire. Queries can opt out per-event or disable all event refetches:

      // Skip refetch on window focus for this query, but keep `online`
      useQuery(QUERY, {
        refetchOn: { windowFocus: false },
      });
      
      // Disable all event-driven refetches for this query
      useQuery(OTHER_QUERY, {
        refetchOn: false,
      });
      
      // Enable every event for this query, regardless of defaultOptions
      useQuery(LIVE_DASHBOARD, {
        refetchOn: true,
      });
      
      // Dynamically enable or disable a refetch when the event fires
      useQuery(LIVE_DASHBOARD, {
        refetchOn: ({ source, payload }) => {
          if (source === "windowFocus") {
            // payload is the data associated with the event
            return someCondition(payload);
          }
      
          return true;
        },
      });
      
      // Dynamically enable or disable a refetch for a specific event
      useQuery(LIVE_DASHBOARD, {
        refetchOn: {
          windowFocus: ({ payload }) => {
            // payload is the data associated with the event
            return someCondition(payload);
          },
        },
      });

      To enable per-query opt-in rather than opt-out, set defaultOptions.watchQuery.refetchOn to false and enable it per-query instead.

      const client = new ApolloClient({
        link,
        cache,
        refetchEventManager: new RefetchEventManager({
          sources: { windowFocus: windowFocusSource },
        }),
        defaultOptions: {
          watchQuery: { refetchOn: false },
        },
      });
      
      // Only this query refetches on window focus
      useQuery(DASHBOARD_QUERY, { refetchOn: { windowFocus: true } });

      When defaultOptions.watchQuery.refetchOn and per-query refetchOn options are provided, the objects are merged together.

  21. 4.1.9

    23 Apr 2026
    • Remove the workspaces field from the published package.json in dist to avoid Yarn v1 warnings about workspaces requiring private packages.

  22. 4.1.8

    23 Apr 2026
    • Ship agent skill for usage with @tanstack/intent — the skill is now bundled in the npm package under skills/apollo-client/ and discoverable by intent list. For more context, see the TanStack Intent QuickStart.

  23. 4.1.7

    8 Apr 2026
    • Fix RxJS interop issue with the observable returned by WebSocketLink.

  24. 4.1.6

    23 Feb 2026
    • Fix useQuery hydration mismatch when ssr: false and skip: true are used together

      When both options were combined, the server would return loading: false (because useSSRQuery checks skip first), but the client's getServerSnapshot was returning ssrDisabledResult with loading: true, causing a hydration mismatch.

  25. 4.1.5

    19 Feb 2026
    • Fix an issue where useQuery would poll with pollInterval when skip was initialized to true.

    • Fix issue where client.query would apply options from defaultOptions.watchQuery.

  26. 4.1.4

    5 Feb 2026
    • Ensure PersistedQueryLink merges http and fetchOptions context values instead of overwriting them.

  27. 4.1.3

    28 Jan 2026
    • Fix createFetchMultipartSubscription to support cancellation via AbortController

      Previously, calling dispose() or unsubscribe() on a subscription created by createFetchMultipartSubscription had no effect - the underlying fetch request would continue running until completion. This was because no AbortController was created or passed to fetch(), and no cleanup function was returned from the Observable.

  28. 4.1.2

    21 Jan 2026
    • ssrMode, ssrForceFetchDelay or prioritizeCacheValues should not override fetchPolicy: 'cache-only', fetchPolicy: 'no-cache', fetchPolicy: 'standby', skip: true, or skipToken when reading the initial value of an ObservableQuery.

    • Fix skipToken in useQuery with prerenderStatic and related SSR functions.

    • Avoid fetches with fetchPolicy: no-cache in useQuery with prerenderStatic and related SSR functions.

  29. 4.1.1

    20 Jan 2026
    • Ensure @client fields that are children of aliased server fields are resolved correctly.

  30. 4.1.0

    15 Jan 2026
    • Support headers transport for enhanced client awareness.

    • You can now provide a callback function as the context option on the mutate function returned by useMutation. The callback function is called with the value of the context option provided to the useMutation hook. This is useful if you'd like to merge the context object provided to the useMutation hook with a value provided to the mutate function.

      function MyComponent() {
        const [mutate, result] = useMutation(MUTATION, {
          context: { foo: true },
        });
      
        async function runMutation() {
          await mutate({
            // sends context as { foo: true, bar: true }
            context: (hookContext) => ({ ...hookContext, bar: true }),
          });
        }
      
        // ...
      }
    • Fix an issue where deferred payloads that returned arrays with fewer items than the original cached array would retain items from the cached array. This change includes @stream arrays where stream arrays replace the cached arrays.

  31. 4.0.13

    13 Jan 2026
    • Ensure that compact and mergeOptions preserve symbol keys.

      This fixes an issue where the change introduced in 4.0.11 via #13049 would not be applied if defaultOptions for watchQuery were declared.

      Please note that compact and mergeOptions are considered internal utilities and they might have similar behavior changes in future releases. Do not use them in your application code - a change like this is not considered breaking and will not be announced as such.

  32. 4.0.12

    12 Jan 2026

    Reading the note…

  33. 4.0.11

    16 Dec 2025

    Reading the note…

  34. 4.0.10

    10 Dec 2025

    Reading the note…

  35. 4.0.9

    31 Oct 2025

    Reading the note…

  36. 4.0.8

    27 Oct 2025

    Reading the note…

  37. 4.0.7

    30 Sep 2025

    Reading the note…

  38. 4.0.6

    25 Sep 2025

    Reading the note…

  39. 4.0.5

    12 Sep 2025

    Reading the note…

  40. 4.0.4

    2 Sep 2025

    Reading the note…

  41. 4.0.3

    29 Aug 2025

    Reading the note…

  42. 4.0.2

    27 Aug 2025

    Reading the note…

  43. 4.0.1

    25 Aug 2025

    Reading the note…

  44. 4.0.0

    21 Aug 2025

    Reading the note…

  45. 3.x
  46. 3.14.1

    12 Mar 2026

    Reading the note…

  47. 3.14.0

    21 Aug 2025

    Reading the note…

  48. 3.13.9

    29 Jul 2025

    Reading the note…

  49. 3.13.8

    17 Apr 2025

    Reading the note…

  50. 3.13.7

    10 Apr 2025

    Reading the note…

  51. 3.13.6

    4 Apr 2025

    Reading the note…

  52. 3.13.5

    20 Mar 2025

    Reading the note…