yarn @nestjs/cli 12.0.0
Release 12.0.0

2 hours ago

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 buildsnest build --all --parallel [concurrency] builds monorepo projects concurrently, with an optional concurrency limit.
  • Library assetscompilerOptions.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.

Don't miss a new cli release

NewReleases is sending notifications on new releases.