May 27, 2026

What’s New in Apollo Client 4.2

Jerel Miller

Jerel Miller

We’re excited to announce the release of Apollo Client 4.2. This release brings two additional long-awaited features:

  • Type-safe default options
  • Event-based refetching

Let’s dive in!

Type-safe default options

Prior to version 4.2, you had to choose between convenience and type-safety when you wanted to propagate a default option throughout your application. For example, you might set your default errorPolicy to "all" in order to render partially successful queries in your components.

This could introduce a mismatch between the runtime behavior and what TypeScript reports as the right value. Consider this useSuspenseQuery example:

1const { data } = useSuspenseQuery(QUERY);2//      ^? TData34const { data } = useSuspenseQuery(QUERY, { errorPolicy: "all" });5//      ^? TData | undefined

With no explicit errorPolicy, useSuspenseQuery‘s throws by default when an error is returned, which means `data` can be typed as the query data type. Passing errorPolicy: "all" changes the return type to include undefined because the server might return an error with no data.

Changing the default errorPolicy in defaultOptions was considered unsafe however because it modified the runtime behavior, but the types remained the same. This could cause crashes in your production environment that weren’t caught by TypeScript because you might access properties on undefined.

In 4.2, default options are now propagated through all React hooks and APIs to provide the correct type to match the runtime value. You opt in by declaring your default options using TypeScript module augmentation:

1// apollo.d.ts2import "@apollo/client";34declare module "@apollo/client" {5  namespace ApolloClient {6    namespace DeclareDefaultOptions {7      interface WatchQuery {8        errorPolicy: "all";9      }10    }11  }12}

To make sure the runtime behavior matches the types, Apollo Client forces you to add a matching defaultOptions option:

1new ApolloClient({2  // without this option, TypeScript reports an error3  defaultOptions: {4    watchQuery: {5      errorPolicy: "all"6    }7  }8})

With that TypeScript declaration in place, the hook now reflects the runtime value:

1const { data } = useSuspenseQuery(QUERY);2//      ^? TData | undefined

This behavior extends to all query and mutation hooks and core APIs.

Learn more about declaring type-safe default options in the TypeScript guide.

Deprecation of generic arguments

To achieve type-safe default options, Apollo Client requires the use of type inference. As a result, passing generic arguments to hooks and core APIs is now deprecated.

1// Generic arguments are no deprecated2useQuery<DataType, VariablesType>(QUERY)

You can still use this signature, but you won’t be able to take advantage of the new type-safety. Migrate to TypedDocumentNode instead:

1const QUERY: TypedDocumentNode<DataType, VariablesType> = gql``

Learn more about migrating in the migration guide.

Event-based refetching

One of our most popular requests has been window focus refetching, a feature popularized by TanStack Query that triggers automatic refetches when the browser tab regains focus. Building your own system for handling automatic refetches resulted in a complicated mess of useEffect or wrapper hooks to provide this sort of functionality yourself.

4.2 introduces the new RefetchEventManager, which handles refetches for you in response to events such as window focus or network reconnection. Pass a RefetchEventManager instance to the refetchEventManager option to opt-into automatic refetches:

1import { RefetchEventManager, windowFocusSource } from "@apollo/client";23const client = new ApolloClient({4  // ...5  refetchEventManager: new RefetchEventManager({6    sources: {7      windowFocus: windowFocusSource,8    },9  }),10});

Anytime a user focuses the browser tab, the client automatically refetches active queries.

Queries can also opt-out of a specific event refetch with the new refetchOn option:

1useQuery(QUERY, { 2  // Don't refetch this query when the windowFocus event is triggered3  refetchOn: { windowFocus: false } 4});

RefetchEventManager is designed for extensibility in mind. You can register your own custom events, provide customized handlers to determine which queries should be refetched, and more.

See the event-based refetching docs to learn more.

Wrapping up

Ready to upgrade? Install Apollo Client 4.2 today:

1npm install @apollo/client@latest

For the full list of changes, check out the release notes. Questions and feedback are always welcome in the Apollo Community.

Happy querying!

Written by

Jerel Miller

Jerel Miller

Read more by Jerel Miller