diff --git a/website/pages/_meta.ts b/website/pages/_meta.ts
index 9024a4a64e..7bf4b6e9cd 100644
--- a/website/pages/_meta.ts
+++ b/website/pages/_meta.ts
@@ -3,6 +3,16 @@ const meta = {
type: 'page',
title: 'Documentation',
},
+ 'upgrade-guides': {
+ type: 'menu',
+ title: 'Upgrade Guides',
+ items: {
+ 'v16-v17': {
+ title: 'v16 to v17',
+ href: '/upgrade-guides/v16-v17',
+ },
+ },
+ },
'api-v16': {
type: 'menu',
title: 'API',
diff --git a/website/pages/upgrade-guides/v16-v17.mdx b/website/pages/upgrade-guides/v16-v17.mdx
new file mode 100644
index 0000000000..00b8a27343
--- /dev/null
+++ b/website/pages/upgrade-guides/v16-v17.mdx
@@ -0,0 +1,187 @@
+---
+title: Upgrading from v16 to v17
+sidebarTitle: v16 to v17
+---
+
+import { Tabs } from 'nextra/components';
+import { Callout } from 'nextra/components'
+
+
+ Currently GraphQL v17 is in alpha, this guide is based on the alpha release and is subject to change.
+
+
+# Breaking changes
+
+## Default values
+
+GraphQL schemas allow default values for input fields and arguments. Historically, GraphQL.js did not rigorously validate or coerce these
+defaults during schema construction, leading to potential runtime errors or inconsistencies. For example:
+
+- A default value of "5" (string) for an Int-type argument would pass schema validation but fail at runtime.
+- Internal serialization methods like astFromValue could produce invalid ASTs if inputs were not properly coerced.
+
+With the new changes default values will be validated and coerced during schema construction.
+
+```graphql
+input ExampleInput {
+ value: Int = "invalid" # Now triggers a validation error
+}
+```
+
+This goes hand-in-hand with the deprecation of `astFromValue` in favor of `valueToLiteral` or `default: { value: }`.
+
+```ts
+// Before (deprecated)
+const defaultValue = astFromValue(internalValue, type);
+// After
+const defaultValue = valueToLiteral(externalValue, type);
+```
+
+If you want to continue using the old behavior, you can use `defaultValue` in your schema definitions. The new
+behavior will be exposed as `default: { literal: }`.
+
+## GraphQLError constructor arguments
+
+The `GraphQLError` constructor now only accepts a message and options object as arguments. Previously, it also accepted positional arguments.
+
+```diff
+- new GraphQLError('message', 'source', 'positions', 'path', 'originalError', 'extensions');
++ new GraphQLError('message', { source, positions, path, originalError, extensions });
+```
+
+## `createSourceEventStream` arguments
+
+The `createSourceEventStream` function now only accepts an object as an argument. Previously, it also accepted positional arguments.
+
+```diff
+- createSourceEventStream(schema, document, rootValue, contextValue, variableValues, operationName);
++ createSourceEventStream({ schema, document, rootValue, contextValue, variableValues, operationName });
+```
+
+## `execute` will error for incremental delivery
+
+The `execute` function will now throw an error if it sees a `@defer` or `@stream` directive. Use `experimentalExecuteIncrementally` instead.
+If you know you are dealing with incremental delivery requests, you can replace the import.
+
+```diff
+- import { execute } from 'graphql';
++ import { experimentalExecuteIncrementally as execute } from 'graphql';
+```
+
+## Remove incremental delivery support from `subscribe`
+
+In case you have fragments that you use with `defer/stream` that end up in a subscription,
+use the `if` argument of the directive to disable it in your subscription operation
+
+## `subscribe` return type
+
+The `subscribe` function can now also return a non-Promise value, previously this was only a Promise.
+This shouldn't change a lot as `await value` will still work as expected. This could lead to
+some typing inconsistencies though.
+
+## Remove `singleResult` from incremental results
+
+You can remove branches that check for `singleResult` in your code, as it is no longer used.
+
+## Node support
+
+Dropped support for Node 14 (subject to change)
+
+## Removed `TokenKindEnum`, `KindEnum` and `DirectiveLocationEnum` types
+
+We have removed the `TokenKindEnum`, `KindEnum` and `DirectiveLocationEnum` types,
+use `Kind`, `TokenKind` and `DirectiveLocation` instead. https://github.com/graphql/graphql-js/pull/3579
+
+## Removed `graphql/subscription` module
+
+use `graphql/execution` instead for subscriptions, all execution related exports have been
+unified there.
+
+## Removed `GraphQLInterfaceTypeNormalizedConfig` export
+
+Use `ReturnType` if you really need this
+
+## Empty AST collections will be undefined
+
+Empty AST collections will be presented by `undefined` rather than an empty array.
+
+## `Info.variableValues`
+
+The shape of `Info.variableValues` has changed to be an object containing
+`sources` and `coerced` as keys.
+
+A Source contains the `signature` and provided `value` pre-coercion for the
+variable. A `signature` is an object containing the `name`, `input-type` and
+`defaultValue` for the variable.
+
+## Stream directive can't be on multiple instances of the same field
+
+The `@stream` directive can't be on multiple instances of the same field,
+this won't pass `validate` anymore.
+
+See https://github.com/graphql/graphql-js/pull/4342
+
+## Stream initialCount becomes non-nullable
+
+The `initialCount` argument of the `@stream` directive is now non-nullable.
+
+See https://github.com/graphql/graphql-js/pull/4322
+
+## GraphQLSchemas converted to configuration may no longer be assumed valid
+
+The `assumeValid` config property exported by the `GraphQLSchema.toConfig()` method now passes through the original
+flag passed on creation of the `GraphQLSchema`.
+Previously, the `assumeValid` property would be to `true` if validation had been run, potentially concealing the original intent.
+
+See https://github.com/graphql/graphql-js/pull/4244 and https://github.com/graphql/graphql-js/issues/3448
+
+## `coerceInputValue` returns `undefined` on error
+
+`coerceInputValue` now aborts early when an error occurs, to optimize execution speed on the happy path.
+Use the `validateInputValue` helper to retrieve the actual errors.
+
+## Removals
+
+- Removed deprecated `getOperationType` function, use `getRootType` on the `GraphQLSchema` instance instead
+- Removed deprecated `getVisitFn` function, use `getEnterLeaveForKind` instead
+- Removed deprecated `printError` and `formatError` utilities, you can use `toString` or `toJSON` on the error as a replacement
+- Removed deprecated `assertValidName` and `isValidNameError` utilities, use `assertName` instead
+- Removed deprecated `assertValidExecutionArguments` function, use `assertValidSchema` instead
+- Removed deprecated `getFieldDefFn` from `TypeInfo`
+- Removed deprecated `TypeInfo` from `validate` https://github.com/graphql/graphql-js/pull/4187
+
+## Deprecations
+
+- Deprecated `astFromValue` use `valueToLiteral` instead, when leveraging `valueToLiteral` ensure
+ that you are working with externally provided values i.e. the SDL provided defaultValue to a variable.
+- Deprecated `valueFromAST` use `coerceInputLiteral` instead
+- Deprecated `findBreakingChanges()` and `findDangerousChanges()`. Use `findSchemaChanges()` instead, which can also be used to find safe changes.
+- Deprecated `serialize`. `parseValue`, and `parseLiteral` properties on scalar type configuration. Use `coerceOutputValue`, `coerceInputValue`, and `coerceInputLiteral` instead.
+
+## Experimental Features
+
+### Experimental Support for Incremental Delivery
+
+- [Spec PR](https://github.com/graphql/graphql-spec/pull/1110) / [RFC](https://github.com/graphql/graphql-wg/blob/main/rfcs/DeferStream.md)
+- enabled only when using `experimentalExecuteIncrementally()`, use of a schema or operation with `@defer`/`@stream` directives within `execute()` will now throw.
+- enable early execution with the new `enableEarlyExecution` configuration option for `experimentalExecuteIncrementally()`.
+
+### Experimental Support for Fragment Arguments
+
+- [Spec PR](https://github.com/graphql/graphql-spec/pull/1081)
+- enable with the new `experimentalFragmentArguments` configuration option for `parse()`.
+- new experimental `Kind.FRAGMENT_ARGUMENT` for visiting
+- new experimental `TypeInfo` methods and options for handling fragment arguments.
+- coerce AST via new function `coerceInputLiteral()` with experimental fragment variables argument (as opposed to deprecated `valueFromAST()` function).
+
+## Features
+
+- Added `hideSuggestions` option to `execute`/`validate`/`subscribe`/... to hide schema-suggestions in error messages
+- Added `abortSignal` option to `graphql()`, `execute()`, and `subscribe()` allows cancellation of these methods;
+ the `abortSignal` can also be passed to field resolvers to cancel asynchronous work that they initiate.
+- `extensions` support `symbol` keys, in addition to the normal string keys.
+- Added ability for resolver functions to return async iterables.
+- Added `perEventExecutor` execution option to allows specifying a custom executor for subscription source stream events, which can be useful for preparing a per event execution context argument.
+- Added `validateInputValue` and `validateInputLiteral` helpers to validate input values and literals, respectively.
+- Added `replaceVariableValues` helper to replace variables within complex scalars uses as inputs. Internally, this allows variables embedded within complex scalars to finally use the correct default values.
+- Added new `printDirective` helper.