diff --git a/apollo-client-4-blog-post.md b/apollo-client-4-blog-post.md new file mode 100644 index 00000000000..cccb893b89a --- /dev/null +++ b/apollo-client-4-blog-post.md @@ -0,0 +1,96 @@ +# Apollo Client 4.0: a leaner and cleaner GraphQL client with no compromises + +Today, we're thrilled to announce the release of Apollo Client 4.0, a milestone release that delivers significant improvements in bundle size, TypeScript support, and developer experience. After extensive community feedback and months of iteration through release candidates, version 4.0 represents our most refined and performant Apollo Client yet. + +The JavaScript ecosystem has evolved dramatically since Apollo Client 3.0's release. Modern build tools offer sophisticated tree-shaking, the state of the art of TypeScript has significantly improved, and applications demand smaller bundles to meet Core Web Vitals targets. Apollo Client 4.0 embraces these changes while maintaining the developer experience you love. + +## Dramatically Smaller Bundles + +Bundle size has been a top concern in community feedback, and we've taken it seriously. Apollo Client 4.0 introduces opt-in architecture for features that not everyone needs. The most impactful change is making local state management opt-in. If you're not using `@client` directives for local state, you no longer carry that code in your bundle. This same principle extends to other commonly-unused features like `HttpLink`, which is no longer bundled by default when you're using custom terminating links. When you do need these features, importing them explicitly gives you the same powerful functionality, but only when you actually use it. + +We've also modernized our build targets. Apollo Client 4.0 ships JavaScript transpiled for browsers from 2023 and Node.js 20+, taking advantage of native language features instead of polyfills. Combined with proper ESM support and improved tree-shaking, most applications will see a **20-30%** reduction in Apollo Client's bundle size contribution. For teams fighting to stay under performance budgets, this improvement alone makes upgrading worthwhile. + +## TypeScript That Helps + +We've completely reimagined our TypeScript architecture based on a simple principle: types should be discoverable where you use them. Instead of hunting through documentation for type names, types now live alongside their APIs through namespaces. When you import `useQuery`, you get `useQuery.Options` and `useQuery.Result` right there. It's a small change that makes a big difference in day-to-day development. + +But the improvements go deeper. Apollo Client 4.0 now enforces required variables at the type level — if your query has required variables, TypeScript won't let you forget them. The fragile `TContext` generic has been replaced with module augmentation for defining custom context types across your link chain. And with the new `TypeOverrides` interface, you can customize how Apollo Client handles partial data, streaming responses, and more, all while maintaining type safety. + +```typescript +import { useQuery } from "@apollo/client/react"; + +// Variables are now required when the query needs them +function UserProfile({ userId }: { userId: string }) { + // TypeScript error if variables are missing when required! + const { data, dataState } = useQuery(USER_QUERY, { + variables: { id: userId } // Required by TypeScript + }); + + if (dataState === 'complete') { + // TypeScript knows data is fully populated + return ; + } + // ... +} + +// Define context types once for your entire app +declare module "@apollo/client" { + interface DefaultContext { + authToken?: string; + requestId?: number; + } +} +``` + +Speaking of `dataState`, this new property solves one of the most common TypeScript frustrations with Apollo Client. Previously, determining whether `data` was partial, complete, or missing required checking multiple flags. Now, `dataState` gives you a single source of truth with four clear states: `empty`, `partial`, `streaming`, and `complete`. TypeScript can narrow types based on these states, eliminating runtime errors from accessing undefined data. + +## More Intuitive Error Handling + +Error handling in Apollo Client 3 often required developers to dig through nested properties in order to grasp what went wrong. Apollo Client 4.0 replaces the monolithic `ApolloError` with specific error classes that tell you exactly what happened. GraphQL errors from your server are now clearly distinguished from network failures or parsing errors. Each error type has static methods for type checking, making error handling both more intuitive and more type-safe. + +```typescript +import { CombinedGraphQLErrors } from "@apollo/client"; + +// Clear, specific error handling +if (CombinedGraphQLErrors.is(error)) { + error.errors.forEach(e => console.log(e.message)); +} else if (error) { + console.error("Network error:", error.message); +} +``` + +This clarity extends throughout the API. Hooks like `useLazyQuery` now have clearer boundaries about what options go where — initial options on the hook, execution options on the execute function. The `loading` state actually means loading now, with `notifyOnNetworkStatusChange` defaulting to `true` so refetches are properly reflected in your UI. + +## Built for Modern JavaScript + +Apollo Client 4.0 fully embraces modern JavaScript standards. We've migrated from `zen-observable` to RxJS, giving you access to a massive ecosystem of operators and debugging tools. RxJS is now a peer dependency, so you control the version and can share a single instance across your entire application. + +The move to ESM-first packaging isn't just about following trends, it delivers real benefits. Your bundler can now analyze and optimize Apollo Client code just like your own application code. Dead code elimination works properly, dynamic imports are supported, and you get better debugging with proper source maps. For teams using Vite, Webpack 5, or other modern bundlers, the improvement in build times and bundle optimization is immediately noticeable. + +React has never been required to use Apollo Client, but in prior versions our exported modules could sometimes muddy the waters in a way that confused non-React users. Apollo Client 4.0 addresses this friction point by making all top-level exported members completely free of React dependencies. React remains a first-class citizen with all the hooks and patterns you're familiar with, they just live in `@apollo/client/react` now. + +## A Smooth Migration Path + +We know that major version upgrades can be daunting, especially for large codebases. That's why we've invested heavily in migration tooling. Our comprehensive codemod handles the mechanical changes automatically—updating imports, converting link creator functions to classes, and migrating deprecated APIs. For most applications, you can run the codemod and be 90% done with your migration in minutes. + +```bash +npx apollo-client-codemod-migrate-3-to-4 src +``` + +The remaining changes are typically intentional breaking changes that require human judgment, like updating error handling or choosing whether to adopt new features like the `LocalState` class. Our migration guide walks through each change with clear examples and explanations. + +## Looking Forward + +Apollo Client 4.0 is more than a bundle size reduction or API cleanup—it's a foundation for the next generation of GraphQL development. We're already seeing significant performance improvements from teams using the React Compiler-optimized hooks. The framework-agnostic core opens possibilities for deeper framework integrations. And the cleaner TypeScript architecture makes it easier for us to add new features without breaking existing code. + +This release wouldn't have been possible without extensive community feedback and contributions. Thank you to everyone who tested release candidates, reported issues, and helped shape Apollo Client 4.0 into what it is today. + +Ready to upgrade? Install Apollo Client 4.0 today: + +```bash +npm install @apollo/client@latest graphql rxjs +``` + +For detailed upgrade instructions, check out our [migration guide](https://www.apollographql.com/docs/react/migrating/apollo-client-4-migration). For the complete list of changes, see the [changelog](https://github.com/apollographql/apollo-client/blob/main/CHANGELOG.md). + +Happy querying! diff --git a/release-notes-v2.md b/release-notes-v2.md new file mode 100644 index 00000000000..adb32615580 --- /dev/null +++ b/release-notes-v2.md @@ -0,0 +1,334 @@ +# 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`) +- **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:** + +```typescript +// 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 + +```typescript +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: + +```typescript +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: + +```typescript +import { LocalState } from "@apollo/client/local-state"; + +const client = new ApolloClient({ + cache, + localState: new LocalState({ + resolvers: { + Query: { + myField: () => "Hello World", + }, + }, + }), +}); +``` + +**Resolver Context Changes:** + +```typescript +// 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: + +```typescript +import { prerenderStatic } from "@apollo/client/react/ssr"; + +// Works with React 19's prerender APIs +const html = await prerenderStatic(, { + client, +}); +``` + +### React Compiler Support + +Pre-compiled React hooks optimized by the React Compiler: + +```typescript +// 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: + +```typescript +// 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 + +```typescript +// 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: + +```bash +# 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 + +```bash +# 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 components (`@apollo/client/react/components`) +- Higher-order components (`@apollo/client/react/hoc`) +- `@apollo/client/react/parser` +- `@apollo/client/utilities/globals` + +## Upgrade Path + +1. **Update to Apollo Client 3.14** first for deprecation warnings +2. **Install peer dependencies**: `npm install rxjs` +3. **Run the codemod** to automate import and type updates +4. **Update ApolloClient initialization** (explicit `HttpLink`, `LocalState` if needed) +5. **Review error handling** - update to use new error classes +6. **Test thoroughly** - especially SSR, error handling, and local state + +## Resources + +- [Migration Guide](https://www.apollographql.com/docs/react/migrating/apollo-client-4-migration) +- [Changelog](https://github.com/apollographql/apollo-client/blob/main/CHANGELOG.md) + +## Acknowledgments + +Apollo Client 4.0 represents years of community feedback and contributions. Thank you to all our contributors, early adopters, and the entire GraphQL community for making this release possible. diff --git a/release-notes.md b/release-notes.md new file mode 100644 index 00000000000..827d1211781 --- /dev/null +++ b/release-notes.md @@ -0,0 +1,269 @@ +# Apollo Client v4.0 Release Notes + +Apollo Client v4 contains comprehensive improvements to error handling, TypeScript support, and developer experience. This release modernizes the codebase and reduces bundle size while maintaining the powerful GraphQL client capabilities you rely on. + +## Major Themes + +### Enhanced Error Handling + +Apollo Client v4 introduces more precise error abstractions that replace the monolithic `ApolloError` class. + +**Key Changes:** +- **Specialized Error Classes**: Errors are now categorized into distinct types: + - `CombinedGraphQLErrors` for GraphQL errors (replacing `graphqlErrors`) + - Network errors are passed through directly as-is (no wrapper class) + - `CombinedProtocolErrors` for transport-level errors +- **Type-Safe Error Handling**: Use `instanceof` checks to handle specific error types +- **Improved Error Wrapping**: String errors are automatically wrapped in `Error` instances, and non-error objects are wrapped in `UnconventionalError` with a `cause` property + +**Migration Example:** +```typescript +// Apollo Client v3 +if (error instanceof ApolloError) { + console.log(error.graphQLErrors); + console.log(error.networkError); +} + +// Apollo Client v4 +if (error instanceof CombinedGraphQLErrors) { + console.log(error.graphQLErrors); +} else if (error instanceof CombinedProtocolErrors) { + console.log(error.protocolErrors); +} else { + // Network errors and other errors are passed through as-is + console.log(error.message); +} +``` + +### TypeScript Improvements + +Apollo Client v4 improves type safety and developer experience through its type definitions. + +**dataState Type System Overhaul:** +- The `TData` generic is no longer modified by the `DataState` generic +- Type narrowing is now more precise and predictable +- New type signature pattern: `QueryRef` instead of `QueryRef, TVariables>` + +**Context Type Extensions:** +- Define types for `context` passed to the link chain using declaration merging +- Built-in support for `HttpLink.ContextOptions` and `BatchHttpLink.ContextOptions` + +**Namespace Organization:** +- Link types now live on the `ApolloLink` namespace +- MockLink types moved to the `MockLink` namespace +- Cleaner, more discoverable API surface + +**Type Override System:** +- New `DataValue` namespace with `Complete`, `Streaming`, and `Partial` types +- Support for data masking type overrides +- Extensible type system for custom implementations + +### The New `dataState` Property + +The `dataState` property provides clear visibility into the completeness of your 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:** +- **Type Narrowing**: The `dataState` property helps TypeScript narrow the type of the `data` property +- **Clear Data Status**: No more guessing about whether your data is complete or partial +- **Better Developer Experience**: Available on `ObservableQuery` and all React hooks returning `data` + +**Example:** +```typescript +const { data, dataState } = useQuery(MY_QUERY); + +if (dataState === 'complete') { + // TypeScript knows data is fully typed here + console.log(data.allFields); +} else if (dataState === 'partial') { + // TypeScript knows data might be missing fields + console.log(data?.someField); +} +``` + +### `@defer` Support Evolution + +Apollo Client v4 introduces a pluggable incremental delivery system for the `@defer` directive. This gives developers the flexibility to define which incremental delivery protocol to use without sacrificing compatibility with any further specification changes. Please note that Apollo Client 4.0 intentionally does not specifcy a default implementation since incremental delivery is still not merged into the draft GraphQL specification. Users must opt into a specific protocol version. + +**Pluggable Implementation:** +- Configure incremental delivery through the `incrementalHandler` option +- Available handlers: + - `NotImplementedHandler` (default) + - `Defer20220824Handler` (Apollo Router format) + - `GraphQL17Alpha2Handler` (alias for Defer20220824Handler, for GraphQL 17.0.0-alpha.2 compatibility) + +**HTTP Multipart Improvements:** +- Stricter error handling for connection issues +- Better handling of non-WhatWG response bodies +- Improved reliability for long-running deferred queries + +### Local State Management Enhancements + +Local state management in Apollo Client v4 has been revamped for modularity, reliability and type safety. + +**Resolver System Overhaul:** +- Resolvers have been moved from `ApolloClient` to a new `LocalState` class +- The `resolvers` option on `ApolloClient` has been replaced with a `localState` option +- Errors thrown in resolvers now set the field to `null` and add to the `errors` array +- Remote results are dealiased before being passed to resolvers +- New `context` function for customizing `requestContext` +- `Resolvers` generic provides autocompletion and type checking + +**Breaking Change - Resolver Migration:** +Resolvers must now be configured through the `LocalState` class: +```typescript +// Apollo Client v3 +const client = new ApolloClient({ + cache, + resolvers: { /* ... */ } +}); + +// Apollo Client v4 +import { LocalState } from '@apollo/client/local-state'; + +const client = new ApolloClient({ + cache, + localState: new LocalState({ + resolvers: { /* ... */ } + }) +}); +``` + +**Breaking Change - Resolver Context:** +The resolver `context` argument (3rd argument) has been restructured: +```typescript +// Apollo Client v3 +const resolver = (parent, args, context, info) => { + const { cache } = context; +}; + +// Apollo Client v4 +const resolver = (parent, args, context, info) => { + const { client, requestContext, phase } = context; + const cache = client.cache; +}; +``` + +**New Codegen Plugin:** + +This release introduces the `@apollo/client-graphql-codegen` package for creating resolver types for GraphQL Code Generator. It is tailored specifically for `LocalState` usage and allows for type-safe resolver development. + +## Additional Improvements + +### React Integration Changes + +**React Exports Migration:** +All React-related exports have moved to dedicated entrypoints: +- Main exports: `@apollo/client/react` +- Testing utilities: `@apollo/client/testing/react` +- Note: `gql` should be imported from `@apollo/client`, not from `@apollo/client/react` + +In previous versions, users sometimes inadvertently imported React modules through seemingly unrelated paths. In v4 we resolve these footguns to make it more transparent when React-only modules are being imported. + +**React Compiler Support (Experimental):** +Apollo Client v4 ships with React Compiler-optimized hooks available at `@apollo/client/react/compiled`. This experimental feature provides: +- Pre-compiled React hooks optimized by the React Compiler +- Drop-in replacement for standard React hooks +- Potential performance improvements in React 19+ applications +- Same API surface as `@apollo/client/react` + +To use the compiled hooks: +```typescript +// Instead of importing from @apollo/client/react +import { useQuery, useMutation } from '@apollo/client/react/compiled'; + +// Use exactly the same as before - the API is identical +const { data, loading } = useQuery(MY_QUERY); +``` + +Note: This is an experimental optimization. The standard `@apollo/client/react` hooks remain the recommended default for most applications. + +### Modern Package Format + +- Ships both ESM and CJS formats +- Modern runtime target (browserslist: "since 2023, node >= 20, not dead") +- Improved tree-shaking with proper `exports` field +- Development/production export conditions instead of `globalThis.__DEV__` +- Fixed source maps for better debugging + +### RxJS as Observable Implementation + +- Migrated from `zen-observable` to RxJS +- RxJS is now a peer dependency +- Full RxJS operator support +- Links using observables must use `.pipe(map())` instead of `.map()` + +### Link System Improvements + +**Class-Based Links:** +All links are now available as classes, with creator functions deprecated: +```typescript +// Apollo Client v3 +const link = createHttpLink({ uri: '/graphql' }); + +// Apollo Client v4 +const link = new HttpLink({ uri: '/graphql' }); +``` + +**Enhanced Client Awareness:** +- `HttpLink` and `BatchHttpLink` automatically send client library information +- New `ClientAwarenessLink` for custom implementations +- Can be disabled with `enhancedClientAwareness: { transport: false }` + +### Cache and Query Enhancements + +- **ObservableQuery Lifecycle**: Queries only registered while they have subscribers +- **fetchMore Improvements**: Better option inheritance and variable handling +- **InMemoryCache**: Fields with empty argument objects stored same as fields without arguments +- **Promise-based API Cleanup**: Removed `loading` and `networkStatus` from promise resolutions + +### Testing Improvements + +**MockLink Enhancements:** +- Default `delay` configuration (global and per-instance) +- New `realisticDelay` helper for realistic network simulation +- Improved variable matching with callback support + +**Testing Utilities:** +- Internal utilities moved to `@apollo/client/testing/internal` +- Cleaner, more stable testing API + +### Network and Fetch Requirements + +- Requires WhatWG ReadableStream specification compliance +- No longer supports Node Streams or Async Iterators as `Response.body` +- Better abort signal handling +- WebSocketLink deprecation warning added +- Full support for `application/graphql-response+json` media type with stricter adherence to the GraphQL over HTTP specification + +### SSR Improvements + +- `disableNetworkFetches` renamed to `prioritizeCacheValues` +- Better handling of fetch policies during SSR +- Improved hydration behavior + +## Breaking Changes Summary + +Apollo Client v4 includes breaking changes that require migration. The most significant include: + +1. **Error System**: Replace `ApolloError` checks with specific error class checks (`CombinedGraphQLErrors`, `CombinedProtocolErrors`, etc.) +2. **React Exports**: Update imports from `@apollo/client` to `@apollo/client/react` (except `gql` which stays in `@apollo/client`) +3. **Link Classes**: Replace creator functions with class constructors +4. **ApolloClient Constructor**: `link` option is now required +5. **Local State**: Move `resolvers` from `ApolloClient` to new `LocalState` class +6. **Resolver Context**: Update resolver signatures to use new context structure +7. **RxJS Migration**: Update observable transformations to use `.pipe()` +8. **Type System**: Update type signatures for `dataState` changes + +## Migration Resources + +For detailed migration guides and examples, visit our documentation at [apollographql.com/docs/react/migrating/apollo-client-4-migration](https://www.apollographql.com/docs/react/migrating/apollo-client-4-migration). + +## Acknowledgments + +This release represents years of work from the Apollo Client team and our amazing community. Thank you to all our contributors who helped make v4 possible!