NestJS v12 is Now Available.

Kamil Mysliwiec | Trilon Consulting
Kamil Mysliwiec

Today I am thrilled to announce the official release of NestJS 12. This is the most significant platform update in years — spanning the framework, the CLI, the default tooling, and the documentation. There are far too many changes to list here, but let's take a high-level look at some of the most exciting ones!

In case you're not familiar with NestJS, it is a TypeScript Node.js framework that helps you build enterprise-grade efficient and scalable Node.js applications.

Published by Edewaa Foster

Let's dive right in! 🐈

NestJS is now ESM-first

The headline change in v12 is that the NestJS core packages now ship as ESM.

This has been one of the most requested changes in the history of the project, and it finally aligns Nest with the direction the entire Node.js and TypeScript ecosystem has been moving toward for years.

‼️ The important nuance is that this transition is optional for your application code. Modern Node.js supports require(esm), which means existing CommonJS projects can upgrade to the v12 packages and keep working without a rewrite. ‼️

To make the upgrade itself as smooth as possible, the CLI ships with a brand-new upgrade flow:

# If you installed the CLI globally, run:
$ npm i -g @nestjs/cli@latest @nestjs/schematics@latest
$ npm i @nestjs/cli@latest @nestjs/schematics@latest
$ nest upgrade

Running this command will update your Nest dependencies while preserving your existing module format. Note that nest upgrade does not convert your source files to ESM — your CommonJS project stays a CommonJS project, and everything keeps working thanks to require(esm). Nobody is being forced into ESM overnight.

If you do want to move your own project to ESM as well, that migration is entirely optional — we cover what it involves at the bottom of this article.

CJS or ESM? The CLI lets you choose

When you generate a new project with nest new, the CLI will now ask whether you want a CommonJS or an ESM project — and the default tooling differs depending on that choice:

  • new ESM projects use Vitest and oxlint by default
  • the CJS schematic continues to generate Jest and eslint-based projects

This split is intentional. It gives teams a way to adopt the modern stack on new services while keeping existing codebases untouched. Existing Jest-based projects can continue to use Jest without any forced migration — the @nestjs/testing package remains runner-agnostic, so it works the same regardless of which test runner you pick.

Rspack replaces webpack

Webpack-centric workflows are now deprecated in the Nest CLI, and Rspack becomes the default bundler for monorepos. The --webpack and --webpackPath flags are marked as deprecated, and a new --rspackPath flag lets you point at a custom Rspack configuration.

If your setup depends on webpack-specific plugins or behavior, this is the area you should evaluate first when upgrading.

One point worth calling out: tsc remains the default compiler for standard projects. The build pipeline is evolving, but the TypeScript compiler is not going away.

The CLI also picked up a number of smaller quality-of-life improvements along the way, including new --emit-declarations, --no-type-check, --silent, and --parallel options for nest build and nest start, a new includeLibraryAssets property in nest-cli.json, and a brand-new nest deploy command.

Standard Schema support

One of the most interesting framework-level additions in v12 is first-class Standard Schema support.

Route parameter decorators such as @Body(), @Query(), and @Param() now accept a schema option, which takes any Standard Schema compatible object. This opens the door to validation flows built on libraries like Zod, Valibot, and ArkType:

@Post()
create(@Body({ schema: createCatSchema }) createCatDto: CreateCatDto) {
return this.catsService.create(createCatDto);
}

Or with Zod directly in the decorator:

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

Under the hood, this is powered by the new StandardSchemaValidationPipe, and the same idea extends to the response side with the StandardSchemaSerializerInterceptor, making schema-driven request and response handling consistent across your application.

The @nestjs/config package follows the same direction: the validationSchema option now accepts any Standard Schema compatible object instead of being Joi-only. If you want to keep using Joi, that's perfectly fine too — just make sure to upgrade to Joi v18+ and move library-specific settings to validationOptions.libraryOptions.

Just to be clear, this is not a replacement for class-validator! It is an additional option that allows teams to use a schema-first approach without having to rely on decorators or class-based validation. Our documentation still suggests class-validator as the default for most use cases, but the new schema support is a welcome addition for teams that prefer a different approach.

Structured logging

The ConsoleLogger now treats plain objects passed as additional arguments as structured parameters:

this.logger.log('User signed in', { userId: 1, method: 'oauth' });

In JSON mode, these parameters are nested under a params key by default, or spread onto the root object when you enable the flattenParams option — which makes the built-in logger play much nicer with log aggregation platforms without any third-party wrappers.

Machine-readable error codes

HttpExceptionOptions now accepts an errorCode property that gets serialized into the error response:

throw new BadRequestException('Invalid payload', {
errorCode: 'CATS-0001',
});

This gives API consumers a stable, machine-readable identifier to program against, instead of having to parse human-readable error messages.

Route conflict diagnostics

The core router can now detect shadowed and duplicate routes for you. Two new application options, routeConflictPolicy and routeResolutionStrategy, let you decide how the framework should react when one route unintentionally shadows another — a class of bugs that has historically been painful to track down in larger applications.

Native observability with @nestjs/observe

NestJS 12 ships alongside the new official @nestjs/observe SDK, which integrates natively with the framework through the new instrument application option. It hooks into Nest's own request lifecycle — controllers, interceptors, resolvers, queue consumers — rather than bolting a generic Node.js agent onto the process. Once enabled, it automatically instruments incoming requests, background jobs, errors, logs, and traces, with no exporter to configure and no schema to design.

The integration boils down to creating the module once and passing the matching instrument hook to NestFactory.create():

// app.module.ts
export const { ObserveModule, ObserveInstrument } = createObserveModule();
@Module({
imports: [
ObserveModule.forRoot({
appKey: process.env.OBSERVE_APP_KEY,
appSecret: process.env.OBSERVE_APP_SECRET,
serviceId: 'cats-app',
}),
],
})
export class AppModule {}
// main.ts
const app = await NestFactory.create(AppModule, {
instrument: ObserveInstrument,
});

Once the application receives traffic, everything starts appearing in your project's dashboard within moments:

The NestJS Observe project dashboard

Distributed tracing is built in as well — a single user action that fans out across multiple services shows up as one correlated trace waterfall:

Trace waterfall in NestJS Observe

To learn more, check out the new Observability section in the official documentation.

Microservices improvements

As with every major release, the microservices package received a lot of attention:

  • NATS v3 support: the underlying nats package has been replaced with the new official @nats-io/transport-node client. Note that deserializers now receive the full message object (read the payload via msg.json()).
  • Kafka regexp patterns: @MessagePattern() and @EventPattern() now accept regular expressions, so a single handler can subscribe to multiple topics.
  • Pre-request hooks: run custom logic right before a message handler is invoked.
  • gRPC exception filters: a dedicated exception filter with status-specific exception classes, bringing gRPC error handling in line with the HTTP experience.

GraphQL and WebSockets

On the GraphQL side, GraphiQL is now the default IDE (the legacy playground option is deprecated), and support for the long-unmaintained subscriptions-transport-ws has been removed in favor of graphql-ws.

WebSocket gateways also gained two long-awaited capabilities: request-scoped gateways are now supported, and disconnect handlers finally receive the disconnect reason.

Some other valuable updates

  • Express-based applications now support graceful shutdown, draining in-flight requests before the process exits.
  • The termination behavior when lifecycle hooks reject has been improved, and hooks are now called following the component hierarchy. See the migration guide for details.
  • PipeTransform signatures are now more type-safe, and ArgumentMetadata accepts a generic parameter.
  • NestJS 12 requires Node.js v20.19+ or v22.12+ to run your applications.
  • And many more! Check out the full release notes here

A brand-new nestjs.com (and docs!)

NestJS 12 also arrives together with the first major redesign of the NestJS website in roughly nine years — cleaner, faster, and easier to navigate.

Design by Jakub Staron

The refresh isn't limited to the landing page either — the official documentation received the same design treatment, with a cleaner reading experience and improved navigation across the (ever-growing) documentation surface.

While the redesign is separate from the technical changes landing in the framework itself, it represents the same broader direction: modernizing the project while keeping the core values that made NestJS popular — productivity, scalability, and a structured approach to building backend applications.

Migration from Nest v11

Upgrading is easier than ever. Install the latest CLI and run the new upgrade command:

# If you installed the CLI globally, run:
$ npm i -g @nestjs/cli@latest @nestjs/schematics@latest
$ npm i @nestjs/cli@latest @nestjs/schematics@latest
$ nest upgrade

The nest upgrade command updates your Nest dependencies while preserving your project's existing module format (CommonJS or ESM). For everything else — lifecycle hook ordering, NATS imports, Joi v18, custom pipes — refer to the detailed guidelines available here. Also, make sure to get rid of all deprecation messages that may appear in your console.

Moving your own project to ESM (optional)

As mentioned earlier, upgrading to v12 does not require converting your project to ESM — and nest upgrade intentionally won't rewrite your source files. But if you do want to go all-in on ESM, the migration comes down to a few well-defined steps:

  • add "type": "module" to your package.json
  • set "module": "nodenext" and "moduleResolution": "nodenext" in your tsconfig.json
  • add explicit .js extensions to your relative imports (e.g., './app.module.js')
  • replace __dirname with import.meta.dirname
// main.ts (ESM project)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js'; // 👈 note the explicit extension
const app = await NestFactory.create(AppModule);
await app.listen(3000);

Take your time with this one — there's no deadline. CommonJS projects remain fully supported, and you can migrate service by service whenever it makes sense for your team. The migration guide walks through the full process.

Enjoy v12!

We're excited to see how you use the latest version of NestJS.

Make sure to follow Nest on X @nestframework to stay up to date with all the latest announcements!


Enterprise Consulting & Support

Our official NestJS Enterprise Consulting includes a broad range of services to empower your team.

We work alongside you to meet your deadlines while avoiding costly tech debt. Challenging issue? We've got you covered.

  • Providing technical guidance & architectural reviews
  • Mentoring team members
  • Addressing security & performance concerns
  • Performing in-depth code reviews
  • Long-term support (LTS) & upgrade assistance

Our goal is to help you get to market faster. Nest core team members will help you utilize best practices and choose the right strategy for unique goals. You can learn more on the enterprise.nestjs.com.


Support the NestJS Project

Nest is an MIT-licensed open source project with its ongoing development made possible thanks to the support by the community and our sponsors. Thank you!

This framework is a result of the long days, sleepless nights, and busy weekends. And we fully rely on the goodness ❤️ of the people. If you want to join them, you can read more here.


Thank you

To all backers, sponsors, contributors, and community, thank you once again! This product is for you. And this is only the beginning of the long 🚀 story.

Become a Backer or Sponsor to Nest by donating to our open collective. ❤


Learn NestJS - Official NestJS Courses 📚

Level-up your NestJS and Node.js ecosystem skills in these incremental workshop-style courses, from the NestJS Creator himself, and help support the NestJS framework! 🐈

🚀 The NestJS Fundamentals Course is now LIVE and 25% off for a limited time!

🎉 NEW - NestJS Course Extensions now live!
#NestJS
#NodeJS

Share this Post!

📬 Trilon Newsletter

Stay up to date with all the latest Articles & News!

More from the Trilon Blog .

Kamil Mysliwiec | Trilon Consulting
Kamil Mysliwiec

NestJS v12 is Coming: What's New

NestJS 12 is shaping up to be a major release with a number of important changes, including ESM support, a new schema-first validation approach, and a redesigned website.

Read More
Mark Pieszak | Trilon Consulting
Mark Pieszak

Voice AI Integration with ElevenLabs and NestJS

Learn how to utilize ElevenLabs in NestJS projects by setting up text-to-speech, AI dubbing, real-time streaming, and much more!

Read More
Mirsad Halilčević | Trilon Consulting
Mirsad Halilčević

NestJS & DrizzleORM: A Great Match

A deep dive into using DrizzleORM with NestJS with multiple connections, in a manner similar to TypeORM!

Read More

What we do at Trilon .

At Trilon, our goal is to help elevate teams - giving them the push they need to truly succeed in today's ever-changing tech world.

Trilon - Consulting

Consulting .

Let us help take your Application to the next level - planning the next big steps, reviewing architecture, and brainstorming with the team to ensure you achieve your most ambitious goals!

Trilon - Development and Team Augmentation

Development .

Trilon can become part of your development process, making sure that you're building enterprise-grade, scalable applications with best-practices in mind, all while getting things done better and faster!

Trilon - Workshops on NestJS, Node, and other modern JavaScript topics

Workshops .

Have a Trilon team member come to YOU! Get your team up to speed with guided workshops on a huge variety of topics. Modern NodeJS (or NestJS) development, JavaScript frameworks, Reactive Programming, or anything in between! We've got you covered.

Trilon - Open-source contributors

Open-source .

We love open-source because we love giving back to the community! We help maintain & contribute to some of the largest open-source projects, and hope to always share our knowledge with the world!

Explore more

Write us a message .

Let's talk about how Trilon can help your next project get to the next level.

Rather send us an email? Write to:

hello@trilon.io
© 2019-2025 Trilon.