What's Changed
@nestjs/graphql, @nestjs/apollo and @nestjs/mercurius are now native ES modules, and this major targets the Nest 12 release line.
ESM migration
All three packages are published as pure ESM ("type": "module", compiled with NodeNext) behind a proper exports map. Deep imports into build internals are no longer resolvable — import from the package root:
// ❌ no longer resolvable
import { GraphQLModule } from '@nestjs/graphql/dist/graphql.module';
// ✅
import { GraphQLModule } from '@nestjs/graphql';The one deep entry point that remains public is the CLI plugin:
// ✅ still supported
import { before } from '@nestjs/graphql/plugin';require(esm) — CommonJS still works
You do not need to convert your app to ESM. Thanks to Node's require(esm) support, a CommonJS Nest app can keep require()-ing these packages unchanged. The @nestjs/graphql/plugin entry additionally ships a CJS shim (plugin.cjs), so ts-patch/ttypescript setups and nest-cli.json plugin registration continue to work as before.
GraphQL Playground has been removed
@apollo/server-plugin-landing-page-graphql-playground is gone — GraphiQL is the only built-in landing page. GraphiQL is enabled by default outside production, so most apps need no configuration at all.
playground survives as a deprecated boolean alias; the object form (playground settings) is no longer accepted:
// ❌ no longer supported
GraphQLModule.forRoot({ playground: { settings: { 'editor.theme': 'light' } } });
// ✅ boolean alias still works
GraphQLModule.forRoot({ playground: true });
// ✅ preferred
GraphQLModule.forRoot({ graphiql: true });
// or with options
GraphQLModule.forRoot({ graphiql: { url: '/graphql' } });Resolution order is graphiql → playground → default (GraphiQL when NODE_ENV !== 'production', Apollo's default landing page otherwise).
subscriptions-transport-ws has been removed
The unmaintained subscriptions-transport-ws transport is dropped; graphql-ws is the only supported subscriptions protocol. The subscriptions-transport-ws key is no longer part of SubscriptionConfig, and installSubscriptionHandlers: true now registers graphql-ws:
// ❌ no longer supported
GraphQLModule.forRoot({
subscriptions: { 'subscriptions-transport-ws': { path: '/graphql' } },
});
// ✅
GraphQLModule.forRoot({
subscriptions: { 'graphql-ws': { path: '/graphql' } },
});Clients still speaking the legacy graphql-ws subprotocol (Apollo Client 2, older subscriptions-transport-ws clients) must migrate to the graphql-transport-ws protocol.
Features
- Explicit
@ArgsType()names —@ArgsType('MyArgs')lets you name the generated type instead of relying on the class name. - Resolver decorator host — register decorators applied to every resolver method from a single place (also available in 13.4.3+).
Bug fixes
fix(schema): map incoming field data back to the property name (#1096)fix(@nestjs/graphql): preserve federation directives inautoSchemaFilefix(@nestjs/graphql): keep resolvers required when skipping argsfix(graphql): makeinfonullablefix(graphql,apollo): ensure extensions are added to resolved fieldsfix(apollo): respectuseGlobalPrefixon a custom subscription path
Upgrading
npm i @nestjs/graphql@14 @nestjs/apollo@14- Bump
@nestjs/common/@nestjs/coreto v12. - Replace any
playground: { ... }object config withgraphiql. - Replace
subscriptions['subscriptions-transport-ws']withsubscriptions['graphql-ws'], and migrate clients to thegraphql-transport-wsprotocol. - Replace deep
@nestjs/graphql/dist/...imports with root imports.
No source changes are required for CommonJS apps beyond the above.