Skip to content

fix(deps): update nest monorepo to v12 - #815

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/major-nest-monorepo
Open

renovate[bot] wants to merge 1 commit into
mainfrom
renovate/major-nest-monorepo

Conversation

@renovate

@renovate renovate Bot commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
@nestjs/cli 11.0.24 → 12.0.8 age confidence
@nestjs/common (source) 11.2.7 → 12.1.2 age confidence
@nestjs/config 4.0.4 → 12.0.1 age confidence
@nestjs/core (source) 11.2.7 → 12.1.2 age confidence
@nestjs/schematics 11.1.0 → 12.0.6 age confidence
@nestjs/testing (source) ^11.0.0 → ^12.0.0 age confidence

Release Notes

nestjs/nest-cli (@​nestjs/cli)

v12.0.8

Compare Source

What's Changed

  • fix(compiler): preserve CommonJS entry exports in rspack and webpack builds by @​KAPUIST in #​3599
  • fix(compiler): preserve parent links for aliased re-exports by @​KAPUIST in #​3601

Full Changelog: nestjs/nest-cli@12.0.7...12.0.8

v12.0.7

Compare Source

What's Changed

New Contributors

Full Changelog: nestjs/nest-cli@12.0.6...12.0.7

v12.0.6

Compare Source

What's Changed

New Contributors

Full Changelog: nestjs/nest-cli@12.0.5...12.0.6

v12.0.5

Compare Source

What's Changed

New Contributors

Full Changelog: nestjs/nest-cli@12.0.4...12.0.5

v12.0.4

Compare Source

v12.0.3

Compare Source

  • chore: flip the default (f194021)

v12.0.2

Compare Source

  • chore: observe prompt changes (3a2773d)

v12.0.1

Compare Source

What's Changed

New Contributors

Full Changelog: nestjs/nest-cli@12.0.0...12.0.1

v12.0.0

Compare Source

What's Changed

@nestjs/cli is now a native ES module, and the major version is aligned with the Nest 12 release line. Alongside the ESM move, the CLI no longer bundles webpack: every bundler-related package is an optional peer dependency now, so a default install is substantially smaller and you pull in only the builder you actually use. There are also two new commands — nest upgrade and nest deploy.

ESM migration

The package is published as pure ESM ("type": "module", compiled with NodeNext). All internal imports carry explicit .js extensions and the build output is ESM-only.

For the common case this is invisible — nest is a binary, and it keeps running your CJS and ESM projects alike. It matters if you import the CLI's internals programmatically (custom builders, plugin harnesses, scripts that drive @nestjs/cli/lib/...): those imports now resolve to ESM.

webpack is no longer a dependency

webpack, fork-ts-checker-webpack-plugin, tsconfig-paths-webpack-plugin, and webpack-node-externals moved from dependencies to optional peer dependencies, joining @swc/cli and @swc/core.

If you build with tsc (the default) or with SWC, nothing changes. If you use --builder webpack (or "webpack": true in nest-cli.json), install the bundler yourself:

npm i -D webpack webpack-node-externals fork-ts-checker-webpack-plugin tsconfig-paths-webpack-plugin

When a builder's peer dependency is missing, the CLI now reports the actual missing package name instead of surfacing the raw resolution error.

Rspack support

@rspack/core is supported as an optional peer dependency (^1.7.7 || ^2.1.10) and is the builder that nest new scaffolds into nest-cli.json for new projects.

  • --builder rspack on nest build and nest start
  • --rspackPath [path] to point at a custom Rspack config, mirroring --webpackPath
  • Source maps are enabled in the Rspack defaults

New: nest upgrade

A new command (aliased nest update) that runs the upgrade schematic to migrate a Nest v11 project to v12 — dependency bumps, tsconfig and nest-cli.json migrations, and codemods for @nestjs/config, GraphQL, and NATS. See the @nestjs/schematics release notes for what the migration itself does.

nest upgrade

Options: -d, --dry-run, -s, --skip-install, -t, --tag [tag] (use a dist-tag such as next instead of the default version ranges), -c, --collection [name], and --observe / --no-observe to answer the @nestjs/observe prompt up front.

New: nest deploy

Deploy an application to the cloud, powered by Mau. Every option is forwarded verbatim to mau deploy, so the command claims no flags of its own.

nest deploy

Path confinement for build output

Build output and clean-up paths are now confined to the project directory by default. Symlinks are resolved before writing, so a dist that is itself a symlink pointing outside the project no longer lets a write escape.

Monorepo layouts that legitimately emit outside the project root can opt back out:

{
  "compilerOptions": {
    "allowOutsidePaths": true
  }
}

Monorepo and asset handling

  • Parallel builds — nest build --all --parallel [concurrency] builds monorepo projects concurrently, with an optional concurrency limit.
  • Library assets — compilerOptions.includeLibraryAssets pulls assets from libraries into an application build.
  • Watch-mode restarts — asset changes restart the application in watch mode, debounced so a burst of writes triggers one restart. The build now awaits watcher close, so it no longer races shutdown.
  • Asset path stripping is aligned with the effective TypeScript rootDir.

Compiler internals

  • glob is gone. It is replaced by an internal fs-based helper built on minimatch, which is now a direct dependency. Symlink traversal depth matches the previous behaviour.
  • A recursive fs watcher replaces chokidar in the SWC watch path.
  • SWC respects tsconfig excludes — excluded files are skipped both on build and in watch mode, and newly added files no longer inherit watch mode when transpiled.
  • --emit-declarations emits .d.ts files under the SWC builder; --no-type-check overrides the config-level setting.
  • --silent suppresses informational compiler logs.

Other improvements

  • Bun is supported as a package manager and runner, detected from bun.lock / bun.lockb.
  • nest new --skip-tests scaffolds a project without testing files, and --observe / --no-observe answers the @nestjs/observe prompt.
  • nest generate --format formats generated files with Prettier; the resource schematic accepts --type <rest|graphql|microservice> and --crud [value].
  • Clearer failures: a non-zero exit on an invalid --builder, a readable error for malformed nest-cli.json, a --parallel value that is validated instead of looping forever, and an explicit message from nest info when no @nestjs/* dependencies are declared.
  • nest info and terminal-width detection prefer process.stdout.columns over shelling out to tput.
  • Plugin metadata emits .js extensions on dynamic imports under nodenext resolution.
  • .tsbuildinfo is removed when deleteOutDir is set.

Toolchain

TypeScript 6 (~6.0.2), @angular-devkit/* 22, commander 15, @inquirer/prompts 8, ora 9, node-emoji 2, and chokidar 5. Internally the CLI moved from Jest to Vitest and from ESLint to oxlint. engines.node stays at >= 20.11.


See the migration guide for the full picture.

nestjs/nest (@​nestjs/common)

v12.1.2

Compare Source

v12.1.1

Compare Source

v12.1.1 (2026-09-28)
Bug fixes
Enhancements
Committers: 13

v12.1.0

Compare Source

v12.1.0 (2026-09-23)
Bug fixes
Enhancements
Committers: 9

v12.0.4

Compare Source

v12.0.4 (2026-09-21)
Bug fixes
Enhancements
Dependencies
Committers: 10

v12.0.3

Compare Source

v12.0.3 (2026-09-15)
Bug fixes
Dependencies
Committers: 4

v12.0.2

Compare Source

v12.0.2 (2026-09-14)
Bug fixes
Enhancements
Dependencies
Committers: 16

v12.0.1

Compare Source

v12.0.0

Compare Source

NestJS v12.0.0

NestJS 12 is centered around ESM-ready packages, first-class Standard Schema support for validation and serialization, a rebuilt CLI, and native observability through the new @nestjs/observe SDK.

Existing CommonJS applications keep working — migrating your own code to ESM is entirely optional.

📖 Full migration guide


Upgrading

Upgrade the CLI first, since the upgrade command ships with it:

npm i -g @nestjs/cli@latest

Then, from the root of your project:

nest upgrade

nest upgrade moves every @nestjs/* package to its v12-compatible major at once and applies the mechanical parts of the migration for you — nest-cli.json webpack options, the GraphQL playground → graphiql rename and subscriptions transport swap, the NATS package replacement, @nestjs/config validation options, Jest and Joi bumps — then prints a report of everything it changed and everything you still need to review by hand. Run it with --dry-run first to see that report without touching your files.

It deliberately does not migrate your project to ESM, Vitest, or oxlint. Those are the defaults for newly generated projects; existing projects adopt them on their own schedule.

Node.js: v12 requires Node.js v20.19+ or v22.12+. Both require(esm) and the ESM packages depend on it; the upgrade command refuses to run on older releases (including the 21.x line). The latest active LTS is recommended.


Highlights
ESM packages

All core Nest packages now ship as ESM. Thanks to require(esm) in modern Node.js, most existing CommonJS applications continue to work without a rewrite. Review custom bootstrapping scripts, build tooling, and test runners if they assume CommonJS-only packages.

nest new now asks whether to scaffold a CommonJS or an ESM project.

Standard Schema validation

Route parameter decorators — @Body(), @Query(), @Param(), @RawBody() — accept a new schema option, designed for Standard Schema compatible libraries such as Zod, Valibot, and ArkType:

@Post()
create(@Body({ schema: createUserSchema }) body: CreateUserDto) {
  return this.usersService.create(body);
}

@Get(':id')
findOne(@Param('id', { schema: z.coerce.number().int().positive() }) id: number) {
  return this.usersService.findOne(id);
}

The decorator only attaches metadata; register the new StandardSchemaValidationPipe to validate against it:

app.useGlobalPipes(new StandardSchemaValidationPipe());

The same schemas feed OpenAPI generation. The decorator-based class-validator workflow remains fully supported, with no plan to remove it.

Standard Schema serialization

StandardSchemaSerializerInterceptor validates and transforms outgoing responses with the same ecosystem:

@UseInterceptors(StandardSchemaSerializerInterceptor)
@SerializeOptions({ schema: userResponseSchema })
@Get(':id')
findOne(@Param('id') id: string) {
  return this.usersService.findOne(id);
}

Pick per use case: ValidationPipe / ClassSerializerInterceptor for class-based DTOs, the Standard Schema variants when your schemas already exist.

Native observability — @nestjs/observe

The official NestJS Observe SDK plugs into Nest's own request lifecycle through the instrument application option, rather than patching the HTTP server like a generic APM agent. Requests, jobs, errors, and traces are reported in terms of your controllers, providers, resolvers, and queue consumers:

export const { ObserveModule, ObserveInstrument } = createObserveModule();

const app = await NestFactory.create(AppModule, {
  instrument: ObserveInstrument,
});

Auto-instrumentation covers HTTP, GraphQL, gRPC, and microservice transports, plus queue consumers and cron runs — no manual span wiring and no collector to run. Opt-in and new; nothing to migrate. nest new and nest upgrade can wire it up for you (--observe). See the Observability chapter.

Config module on Standard Schema

@nestjs/config moves from Joi-specific validation to Standard Schema. validationSchema now accepts any compatible schema:

ConfigModule.forRoot({
  validationSchema: z.object({
    NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
    PORT: z.coerce.number().default(3000),
  }),
});

Existing Joi schemas still work with two caveats: upgrade to Joi v18+ (the first release implementing Standard Schema), and move library-specific settings under validationOptions.libraryOptions.

Route conflict diagnostics

Routes are registered in declaration order, so on order-sensitive adapters @Get(':id') can silently shadow a @Get('me') declared after it. Two opt-in options surface this:

const app = await NestFactory.create(AppModule, {
  routeConflictPolicy: { duplicate: 'error', shadow: 'warn' },
  routeResolutionStrategy: 'specificity',
});

Both default to the previous behavior, so nothing changes unless you set them.

Machine-readable error codes

HttpExceptionOptions accepts an errorCode that is serialized into the response body, so clients branch on a stable identifier instead of parsing message strings:

throw new BadRequestException('Password is too weak', { errorCode: 'WEAK_PASSWORD' });
Structured logging params

ConsoleLogger now treats plain objects passed after the message as structured params of the same log entry instead of separate records:

logger.log('User created', { userId: 1, email: 'foo@bar.com' });

In JSON mode they nest under params, or spread into the root with flattenParams. On by default; set structuredParams: false to restore the old behavior.


CLI (@nestjs/cli v12)

The CLI was rebuilt in nestjs/nest-cli#3280: the entire source migrated to ESM, tests moved from Jest to Vitest, e2e tests were added for every command, and command classes were refactored to take typed context objects instead of untyped inputs and option arrays.

New commands

  • nest upgrade (alias update) — upgrades a v11 project to v12 and applies the migration steps described above.
  • nest deploy — deploys your application to the cloud via Mau, installing @nestjs/mau on first use and forwarding every argument straight through.

Defaults and tooling

  • Rspack is the new default bundler for monorepos. The --webpack / --webpackPath flags (and their webpack / webpackConfigPath counterparts in nest-cli.json) are deprecated in favor of --builder rspack.
  • oxlint replaces ESLint in generated projects.
  • Vitest is the default test runner for ESM projects; CommonJS projects continue with Jest.
  • bun is now a supported package manager, alongside npm, yarn, and pnpm.
  • The decorator schematic generates decorators using the preferred Reflector.createDecorator() form. The angular schematic has been removed.

New options

  • nest build / nest start: --rspackPath [path], --emit-declarations (SWC), --no-type-check, --silent
  • nest build: --parallel [concurrency], for building monorepo projects in parallel with --all
  • nest-cli.json: includeLibraryAssets, for copying library assets into an application build

Breaking changes
Change What to do
Packages ship as ESM Usually nothing — require(esm) keeps CommonJS apps working. Review custom bootstrapping, bundler, and test-runner config.
Node.js v20.19+ / v22.12+ required Upgrade Node; the 21.x line is not supported.
Lifecycle hooks are now invoked by component hierarchy level Review ordering assumptions between related providers/modules in init, teardown, and tests.
NATS v3 — the nats package is replaced by @nats-io/transport-node npm uninstall nats && npm install @nats-io/transport-node; update direct imports. Packets are now serialized as JSON strings and custom deserializers receive the full NATS message — read payloads with msg.json().
GraphQL subscriptions — subscriptions-transport-ws support removed Switch to graphql-ws; the protocols are wire-incompatible, so clients must be updated. Review onConnect callbacks.
GraphiQL is the default GraphQL IDE Replace playground with graphiql; pass an options object to customize.
@nestjs/config validates through Standard Schema Keep Joi by upgrading to v18+ and moving library settings under validationOptions.libraryOptions.
Pipe transform signatures refined; ArgumentMetadata is now generic Adjust hand-written custom pipe signatures if the compiler complains.
ConsoleLogger structured params on by default Set structuredParams: false to restore the previous output.
Webpack CLI workflows deprecated Migrate to --builder rspack.
angular schematic removed —

Most of these are handled automatically by nest upgrade.


Also in this release
  • ValidationPipe error format — a new option controls the shape of validation error responses.
  • gRPC exception filter — GrpcExceptionFilter and status-specific exceptions map errors to proper gRPC status codes instead of UNKNOWN.
  • Regex Kafka patterns — @MessagePattern() and @EventPattern() accept a RegExp on the Kafka transport.
  • Request-scoped WebSocket gateways — gateways support request-scoped providers, with the socket injectable via the REQUEST token.
  • WebSocket disconnect reason — handleDisconnect can receive the reason for the disconnection.
  • Microservices pre-request hook — a new hook runs before a message handler is invoked.
  • Express graceful shutdown — the Express adapter drains in-flight requests on shutdown.
  • HTTP adapter error mapping — reworked across core, Express, and Fastify adapters.

Thanks

Thank you to everyone who contributed code, issues, reproductions, and reviews to this release. 💛

If NestJS helps you build your products, consider supporting the project.

nestjs/config (@​nestjs/config)

v12.0.1

Compare Source

What's Changed

New Contributors

Full Changelog: nestjs/config@12.0.0...12.0.1

v12.0.0

Compare Source

What's Changed

@nestjs/config is now a native ES module, environment validation is built on Standard Schema instead of Joi-specific code, and the major version is aligned with the Nest 12 release line (there is no 5.x — 4.0.4 goes straight to 12.0.0).

ESM migration

The package is published as pure ESM ("type": "module", compiled with NodeNext) behind a proper exports map. The legacy root index.js / index.d.ts shims are gone, and deep imports into build internals are no longer resolvable — import from the package root.

// ✅
import { ConfigModule, ConfigService } from '@nestjs/config';

// ❌ no longer resolvable
import { ConfigService } from '@nestjs/config/dist/config.service';

require(esm) — CommonJS still works

You do not need to convert your app to ESM. Thanks to Node's require(esm) support (Node 20.19+ / 22.12+), a CommonJS app can keep using require('@nestjs/config') unchanged.

Validation is now Standard Schema based

validationSchema accepts any schema implementing the Standard Schema spec — Zod (v3, v4, v4-mini), Valibot, ArkType, Joi 18+, and anything else that adopts it. There is no longer any Joi-specific code path in the module, and Joi is no longer implied as the validation library.

ConfigModule.forRoot({
  validationSchema: z.object({
    PORT: z.coerce.number().default(3000),
    DATABASE_NAME: z.string(),
  }),
});

Joi keeps working — it implements Standard Schema as of v18 — and the historical abortEarly: false / allowUnknown: true defaults are still applied automatically for Joi schemas, so existing Joi setups behave as before.

Breaking: validationOptions shape

Options are now the Standard Schema Options object, and library-specific settings move under libraryOptions:

// Before (4.x)
validationOptions: { allowUnknown: false, abortEarly: true }

// Now (12.x)
validationOptions: { libraryOptions: { allowUnknown: false, abortEarly: true } }

The generic parameter changed accordingly: ConfigModuleOptions<ValidationOptions extends StandardSchemaV1.Options>, and validationSchema is typed as StandardSchemaV1 rather than any — a schema that does not implement the spec is now a compile-time error instead of a runtime one.

Breaking: validation error format

Issues are formatted by this package rather than by the schema library. Each issue is rendered as path: message and issues are newline-separated:

Config validation error: PORT: "PORT" is required
DATABASE_NAME: "DATABASE_NAME" is required

Anything asserting on the old single-line Joi message string needs updating.

Object schemas no longer strip your environment

Schemas like Zod's z.object() drop undeclared keys. Those variables are now merged back into the validated result, so unrelated variables stay reachable through both process.env and ConfigService instead of disappearing after validation.

Breaking: peer dependencies

@nestjs/common is now ^11.0.0 || ^12.0.0. Nest 10 is no longer supported — stay on @nestjs/config@4 if you are still on Nest 10.

Breaking: lodash replaced with es-toolkit

The lodash runtime dependency is gone, replaced by es-toolkit. This is transparent unless you relied on the transitive lodash install.

Breaking: stricter ConfigService.get() inference

The explicit-type parameter on get() / getOrThrow() is now constrained to the value at the given path (R extends PathValue<T, P>), fixing the long-standing bug where an unrelated type could be asserted for a key. Call sites that passed a type inconsistent with the config shape will now fail to compile — that mismatch was always a latent bug.

New: override

Values from .env files can now take precedence over pre-existing process.env variables:

ConfigModule.forRoot({ override: true });

Default remains false — the existing "process.env wins" behavior.

New: custom parser

.env files no longer have to be dotenv-formatted. Supply any function that turns a Buffer into an object — YAML, TOML, JSON, whatever:

ConfigModule.forRoot({
  parser: (buffer) => YAML.parse(buffer.toString()),
});

The parser is used both at bootstrap and for variable re-interpolation inside ConfigService.

Other changes

  • Tests migrated from Jest to Vitest; linting migrated from ESLint to oxlint.
  • dotenv 17.4.2, dotenv-expand 13.
  • Fixed a typo in the ConditionalModule timeout error message ("Bause" → "Because").
nestjs/nest (@​nestjs/core)

v12.1.2

Compare Source

v12.1.1

Compare Source

v12.1.1 (2026-09-28)
Bug fixes

[!IMPORTANT]
✂ PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot force-pushed the renovate/major-nest-monorepo branch 3 times, most recently from 9f04733 to d4a8eb9 Compare September 19, 2026 00:39
@renovate
renovate Bot force-pushed the renovate/major-nest-monorepo branch 4 times, most recently from 241bfe2 to cab5ae1 Compare September 25, 2026 20:46
@renovate
renovate Bot force-pushed the renovate/major-nest-monorepo branch 11 times, most recently from d629091 to f1361fa Compare October 5, 2026 09:58
@renovate
renovate Bot force-pushed the renovate/major-nest-monorepo branch 10 times, most recently from 8a4c509 to a531470 Compare October 13, 2026 15:10
@renovate
renovate Bot force-pushed the renovate/major-nest-monorepo branch 2 times, most recently from f63dbff to c1c3ed4 Compare October 14, 2026 18:30
@renovate
renovate Bot force-pushed the renovate/major-nest-monorepo branch from c1c3ed4 to 273b0c0 Compare October 16, 2026 03:18
@renovate
renovate Bot force-pushed the renovate/major-nest-monorepo branch from 273b0c0 to 0aef37b Compare October 20, 2026 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants