Skip to content

Releases: apollographql/apollo-client

@apollo/client@3.14.0

21 Aug 15:20
cdcd7ed
Compare
Choose a tag to compare

Minor Changes

  • #12752 8b779b4 Thanks @jerelmiller! - Add deprecations and warnings to remaining APIs changed in Apollo Client 4.0.

  • #12746 0bcd2f4 Thanks @jerelmiller! - Add warnings and deprecations for options and methods for all React APIs.

  • #12751 567cad8 Thanks @jerelmiller! - Add @deprecated tags to all properties returned from any query API (e.g. client.query, observableQuery.refetch, etc.), client.mutate, and client.subscribe that are no longer available in Apollo Client 4.0.

  • #12746 0bcd2f4 Thanks @jerelmiller! - Add preloadQuery.toPromise(queryRef) as a replacement for queryRef.toPromise(). queryRef.toPromise() has been removed in Apollo Client 4.0 in favor of preloadQuery.toPromise and is now considered deprecated.

  • #12736 ea89440 Thanks @jerelmiller! - Add deprecations and deprecation warnings for ApolloClient options and methods.

  • #12763 5de6a3d Thanks @jerelmiller! - Version bump only to release latest as rc.

  • #12459 1c5a031 Thanks @jerelmiller! - Reset addTypenameTransform and fragments caches when calling cache.gc() only when resetResultCache is true.

  • #12743 92ad409 Thanks @jerelmiller! - Add deprecations and warnings for addTypename in InMemoryCache and MockedProvider.

  • #12743 92ad409 Thanks @jerelmiller! - Add deprecations and warnings for canonizeResults.

  • #12751 567cad8 Thanks @jerelmiller! - Warn when using a standby fetch policy with client.query.

Patch Changes

  • #12750 ecf3de1 Thanks @phryneas! - Prevent field policies from overwriting/merging into supertype field policies.

@apollo/client@4.0.0

21 Aug 18:10
c6ec3eb
Compare
Choose a tag to compare

Apollo Client 4.0 Release Notes

Apollo Client 4.0 delivers a more modern, efficient, and type-safe GraphQL client experience through various architectural improvements and API refinements. This release focuses on developer experience, bundle size optimization, and framework flexibility.

Key Improvements

🎯 Framework-Agnostic Core

Apollo Client 4.0 separates React functionality from the core library, making @apollo/client truly framework-agnostic. React exports now live in @apollo/client/react, allowing developers to use Apollo Client with any JavaScript framework without React dependencies.

📦 Smaller Bundle Sizes

  • Opt-in Local State Management: The @client directive functionality is now opt-in via the LocalState class, reducing bundle size when not using local state
  • Modern Build Target: Transpiled to target since 2023, node >= 20, not dead, leveraging modern JavaScript features for better performance
  • Improved Tree-Shaking: Proper exports field in package.json enables better dead code elimination

💥 Unified Error Handling

Apollo Client 4.0 completely reimagines error handling for better clarity and debugging:

  • ApolloError removed in favor of specific error classes
  • Unification of errors to a single error property
  • Network errors now respect errorPolicy settings
  • External errors passed through without wrapping
  • New, more granular error classes with static .is() methods for robust type narrowing

🔧 Enhanced TypeScript Support

  • Namespaced Types: Types are now colocated with their APIs (e.g., useQuery.Options instead of QueryHookOptions)
  • Precise Return Types: Return types accurately reflect the options passed (e.g., returnPartialData makes data type DeepPartial<TData>)
  • Stricter Type Safety: Required variables are now enforced more consistently throughout the client
  • New dataState Property: Enables accurate type narrowing of query results
  • Module Augmentation: Custom context types via declaration merging instead of fragile generics
  • Customizable Type Implementations: Select types can now be customized to provide your own type implementation to seamlessly integrate with external tools such as GraphQL Codegen or gql.tada

⚡ Modern Observable Implementation

Apollo Client 4.0 migrates from zen-observable to RxJS, providing the industry-standard Observable implementation backed by a rich ecosystem of utilities.

Major Features

Unified Error Handling

Apollo Client 4.0 completely reimagines error handling for better clarity and debugging:

Key Changes:

  • ApolloError removed in favor of specific error classes
  • Network errors now respect errorPolicy settings
  • External errors passed through without wrapping
  • New error classes with static .is() methods for type checking

Error Classes:

  • CombinedGraphQLErrors - GraphQL errors from the server
  • ServerError - Non-GraphQL server errors
  • ServerParseError - Server response parsing errors
  • UnconventionalError - Wrapper for non-error thrown values
  • LinkError - Errors from the link chain (via .is() check)

Migration Example:

// Apollo Client 3
if (error instanceof ApolloError) {
  console.log(error.graphQLErrors);
  console.log(error.networkError);
}

// Apollo Client 4
import { CombinedGraphQLErrors } from "@apollo/client";

if (CombinedGraphQLErrors.is(error)) {
  console.log(error.errors); // GraphQL errors
} else if (error) {
  console.log(error.message); // Other errors
}

The dataState Property

A new property that clearly indicates the completeness of query results:

Values:

  • empty - No data available (data is undefined)
  • partial - Incomplete data from cache when returnPartialData is true
  • streaming - Incomplete data from a deferred query still streaming
  • complete - Fully satisfied query result

Benefits:

  • Accurate TypeScript type narrowing
  • Clear loading state distinction
  • Better handling of partial results
const { data, dataState } = useQuery(MY_QUERY);

if (dataState === "complete") {
  // TypeScript knows data is fully populated
  console.log(data.allFields);
} else if (dataState === "partial") {
  // TypeScript knows data might be missing fields
  console.log(data?.someField);
}

Pluggable Incremental Delivery (@defer Support)

Apollo Client 4.0 makes incremental delivery configurable and future-proof:

import { Defer20220824Handler } from "@apollo/client/incremental";

const client = new ApolloClient({
  // ...
  incrementalHandler: new Defer20220824Handler(),
});

Available Handlers:

  • NotImplementedHandler - Default, throws if @defer is used
  • Defer20220824Handler - Apollo Router format support (also aliased as GraphQL17Alpha2Handler)

Local State Management Improvements

Local state is now opt-in via the LocalState class:

import { LocalState } from "@apollo/client/local-state";

const client = new ApolloClient({
  cache,
  localState: new LocalState({
    resolvers: {
      Query: {
        myField: () => "Hello World",
      },
    },
  }),
});

Resolver Context Changes:

// Apollo Client 3
const resolver = (parent, args, context, info) => {
  const { cache } = context;
};

// Apollo Client 4
const resolver = (parent, args, context, info) => {
  const { client, requestContext, phase } = context;
  const cache = client.cache;
};

React-Specific Improvements

More Predictable Hooks

useLazyQuery Overhaul:

  • No longer accepts variables or context options (pass to execute instead)
  • execute function only accepts variables and context
  • Cannot be called during render or SSR
  • Automatic cancellation of in-flight queries when new ones start

useMutation Changes:

  • Removed ignoreResults option - use client.mutate directly for fire-and-forget mutations

useQuery Changes:

  • notifyOnNetworkStatusChange now defaults to true
  • Removed deprecated onCompleted and onError callbacks

New SSR API

The new prerenderStatic API replaces deprecated SSR functions:

import { prerenderStatic } from "@apollo/client/react/ssr";

// Works with React 19's prerender APIs
const html = await prerenderStatic(<App />, {
  client,
});

React Compiler Support

Pre-compiled React hooks optimized by the React Compiler:

// Use compiled hooks for potential performance improvements
import { useQuery } from "@apollo/client/react/compiled";

The compiled hooks are built with React Compiler v19.1.0-rc.2 and include a runtime polyfill for compatibility with React 17+.

Link System Evolution

All Links Now Classes

Migration from creator functions to classes:

// Apollo Client 3
import { createHttpLink, setContext } from "@apollo/client";
const httpLink = createHttpLink({ uri: "/graphql" });
const authLink = setContext((operation, prevContext) => {
  /*...*/
});

// Apollo Client 4
import { HttpLink, SetContextLink } from "@apollo/client";
const httpLink = new HttpLink({ uri: "/graphql" });
const authLink = new SetContextLink((prevContext, operation) => {
  /*...*/
});

ErrorLink Changes

// Apollo Client 3
onError(({ graphQLErrors, networkError }) => {
  // Handle errors separately
});

// Apollo Client 4
new ErrorLink(({ error }) => {
  if (CombinedGraphQLErrors.is(error)) {
    // Handle GraphQL errors
  } else if (error) {
    // Handle other errors
  }
});

Migration Tools

Automated Codemod

Apollo Client 4.0 provides a comprehensive codemod to automate migration:

# Basic usage
npx @apollo/client-codemod-migrate-3-to-4 src

# TypeScript projects (run separately)
npx @apollo/client-codemod-migrate-3-to-4 --parser ts --extensions ts src
npx @apollo/client-codemod-migrate-3-to-4--parser tsx --extensions tsx src

The codemod handles:

  1. Import updates - Moves React imports to @apollo/client/react
  2. Type migrations - Updates types to new namespaced locations
  3. Link updates - Converts creator functions to classes
  4. Removed exports - Moves to @apollo/client/v4-migration with migration instructions

Breaking Changes Summary

Installation

# RxJS is now a peer dependency
npm install @apollo/client graphql rxjs

ApolloClient Constructor

  • link option is now required (no more implicit HttpLink creation)
  • uri, headers, credentials removed - use HttpLink directly
  • name and version moved to clientAwareness option
  • resolvers moved to LocalState constructor
  • connectToDevTools replaced with devtools.enabled
  • disableNetworkFetches renamed to prioritizeCacheValues

Type System

  • Removed TContext and TCacheShape generics
  • Types moved to namespaces (see migration guide for full list)
  • Custom context via module augmentation

Observable Changes

  • Requires calling .pipe() for transformations
  • Use RxJS operators instead of method chaining

Testing

  • MockedProvider now has realistic delays by default (20-50ms)
  • createMockClient removed - use MockLink directly

Performance & Build Improvements

  • Modern JavaScript: No downlevel transpilation for modern features
  • No Polyfills: Cleaner bundles, bring your own if needed
  • Development Mode: Controlled via export conditions, not global __DEV__
  • ESM Support: Proper exports field for better module resolution
  • Source Maps: Fixed and improved for better debugging

Deprecations & Removals

Removed Packages/Exports

  • React render prop componen...
Read more

@apollo/client-graphql-codegen@1.0.0

21 Aug 18:10
c6ec3eb
Compare
Choose a tag to compare

Major Changes

  • #12617 ea633a1 Thanks @jerelmiller! - Introduce a new GraphQL Codegen plugin aimed at creating resolver types for LocalState. This plugin is similar to @graphql-codegen/typescript-resolvers but tailored to provide types that work with LocalState.

    To use the plugin, install @apollo/client-graphql-codegen and add the following to your codegen config:

    // codegen.ts
    
    const config: CodegenConfig = {
      // ...
      generates: {
        "./path/to/local/resolvers.ts": {
          schema: ["./path/to/localSchema.graphql"],
          plugins: ["typescript", "@apollo/client-graphql-codegen/local-state"],
          // ...
        },
      },
    };

    This will generate a Resolvers type in the generated file that can be used to provide type information to LocalState.

    import type { Resolvers } from "./path/to/resolvers-types.ts";
    
    const localState = new LocalState<Resolvers>({
      // ...
    });

    It is also recommended to add the following config:

    // codegen.ts
    import type { LocalStatePluginConfig } from "@apollo/client-graphql-codegen/local-state";
    
    const config: CodegenConfig = {
      // ...
      generates: {
        "./path/to/local/resolvers.ts": {
          config: {
            // Ensures you return a `__typename` for any `@client` fields that
            // return object or array types
            nonOptionalTypename: true,
    
            // Required if your localSchema extends existing schema types.
            baseTypesPath: "./relative/path/to/base/schema/types",
    
            // If you provide a `context` function to customize the context value,
            // provide the path or type here.
            contextType: "./path/to/contextValue#ContextValue",
          } satisfies LocalStatePluginConfig,
        },
      },
    };

    NOTE: It is recommended that the schema file passed to the schema option is your local schema, not your entire app schema in order to only generate resolver types for your local fields, otherwise the plugin will generate resolver types for your entire remote schema as well.

  • #12723 1f9ed72 Thanks @jerelmiller! - Version bump only for codegen to release as rc.

@apollo/client-codemod-migrate-3-to-4@1.0.0

21 Aug 18:10
c6ec3eb
Compare
Choose a tag to compare

Major Changes

  • #12727 b845906 Thanks @jerelmiller! - Add a codemod that renames old import locations from 3.x entrypoint to their 4.x entrypoint.

    Run the codemod using the following command:

    npx @apollo/client-codemod-migrate-3-to-4 --parser tsx ./src/**/*.{ts,tsx}

    The codemod supports .js, .jsx, .ts, and .tsx files.

  • #12851 32bc830 Thanks @phryneas! - Add a new clientSetup codemod step which applies the following steps from the migration guide to your Apollo Client setup code:

    • Moves uri, headers and credentials to the link option and creates a new HttpLink instance
    • Moves name and version into a clientAwareness option
    • Adds a localState option with a new LocalState instance, moves resolvers, and removes typeDefs and fragmentMatcher options
    • Changes the connectToDevTools option to devtools.enabled
    • Renames disableNetworkFetches to prioritizeCacheValues
    • If dataMasking is enabled, adds a template for global type augmentation to re-enable data masking types
    • Adds the incrementalHandler option and adds a template for global type augmentation to accordingly type network responses in custom links

Minor Changes

Patch Changes

  • #12846 71ccfb5 Thanks @phryneas! - Add a new legacyEntryPoints transformation step that moves imports from old legacy entry points like @apollo/client/main.cjs or @apollo/client/react/react.cjs to the new entry points like @apollo/client or @apollo/client/react.

  • #12775 454ec78 Thanks @jerelmiller! - Don't export gql from @apollo/client/react entrypoint. Import from @apollo/client instead.

  • #12858 6440e8b Thanks @phryneas! - adjust the clientSetup codemod so that it removes the TCacheShape type argument from all ApolloClient usages (types and constructor calls).

@apollo/client@4.0.0-rc.13

20 Aug 21:17
776ac59
Compare
Choose a tag to compare
Pre-release

Major Changes

@apollo/client-codemod-migrate-3-to-4@1.0.0-rc.3

20 Aug 21:17
776ac59
Compare
Choose a tag to compare

Major Changes

  • #12851 32bc830 Thanks @phryneas! - Add a new clientSetup codemod step which applies the following steps from the migration guide to your Apollo Client setup code:
    • Moves uri, headers and credentials to the link option and creates a new HttpLink instance
    • Moves name and version into a clientAwareness option
    • Adds a localState option with a new LocalState instance, moves resolvers, and removes typeDefs and fragmentMatcher options
    • Changes the connectToDevTools option to devtools.enabled
    • Renames disableNetworkFetches to prioritizeCacheValues
    • If dataMasking is enabled, adds a template for global type augmentation to re-enable data masking types
    • Adds the incrementalHandler option and adds a template for global type augmentation to accordingly type network responses in custom links

Patch Changes

  • #12846 71ccfb5 Thanks @phryneas! - Add a new legacyEntryPoints transformation step that moves imports from old legacy entry points like @apollo/client/main.cjs or @apollo/client/react/react.cjs to the new entry points like @apollo/client or @apollo/client/react.

@apollo/client@4.0.0-rc.12

15 Aug 20:53
0ead2cc
Compare
Choose a tag to compare
Pre-release

Minor Changes

  • #12838 b005561 Thanks @phryneas! - Add an entrypoint at @apollo/client/v4-migration that includes removed values and types. Each export includes doc blocks on how to migrate away from the removed type.

@apollo/client-codemod-migrate-3-to-4@1.0.0-rc.2

15 Aug 08:37
d8431ca
Compare
Choose a tag to compare

Minor Changes

@apollo/client@4.0.0-rc.11

14 Aug 16:38
2c4fd8b
Compare
Choose a tag to compare
Pre-release

Major Changes

  • #12840 83e132a Thanks @phryneas! - If you use an incremental delivery handler, you now have to explicitly opt into adding the chunk types to the ApolloLink.Result type.

    import { Defer20220824Handler } from "@apollo/client/incremental";
    
    declare module "@apollo/client" {
      export interface TypeOverrides extends Defer20220824Handler.TypeOverrides {}
    }
  • #12841 65b503f Thanks @jerelmiller! - Remove the DataMasking interface exported from @apollo/client and @apollo/client/masking.

@apollo/client@4.0.0-rc.10

13 Aug 10:48
7a14c90
Compare
Choose a tag to compare
Pre-release

Major Changes

  • #12837 7c49fdc Thanks @jerelmiller! - You must now opt in to use GraphQL Codegen data masking types when using Apollo Client's data masking feature. By default, Apollo Client now uses an identity type to apply to masked/unmasked types.

    If you're using GraphQL Codegen to generate masked types, opt into the GraphQL Codegen masked types using declaration merging on the TypeOverides interface.

    import { GraphQLCodegenDataMasking } from "@apollo/client/masking";
    
    declare module "@apollo/client" {
      export interface TypeOverrides
        extends GraphQLCodegenDataMasking.TypeOverrides {}
    }
  • #12837 7c49fdc Thanks @jerelmiller! - The types mode for data masking has been removed. Adding a types mode to the DataMasking interface has no effect. Remove the mode key in the module where you declare the DataMasking type for the @apollo/client module.

    As a result, the Masked and MaskedDocumentNode types have also been removed since these have no effect when types are preserved.