devnotes

Does NestJS work with TypeScript 7 (tsgo)?

Partly, and the part that fails is not the one people expect. The Go compiler does handle experimentalDecorators and emitDecoratorMetadata, so the design:paramtypes metadata Nest's injector reads at boot is still emitted. What stops a clean cutover is that 7.0 ships no programmatic compiler API, and nest build is a program that imports typescript and calls createProgram() and program.emit() with its own transformers. So TypeScript 7 will type-check a Nest app today, several times faster. nest build will not run on it, and neither will the Swagger and GraphQL CLI plugins, ts-jest, ts-loader, or type-aware ESLint rules. The setup that works right now is 7.0 for checking and 6.x for building, installed side by side. One naming note first, because it trips people up: in the stable 7.0 release the binary is tsc. tsgo was the preview name and now only exists in the @typescript/native-preview nightlies.

Do decorators and emitDecoratorMetadata work under tsgo?

Yes. Emit support for both legacy flags landed in the native port in microsoft/typescript-go#2343, merged 2025-12-12, and has been getting fixes since: symbol-named decorated methods (#2446, March 2026) and design:type metadata for bigint on pre-ES2020 targets (#4106, June 2026). The port emits the same __decorate, __metadata and __param helpers tsc does, which is exactly what reflect-metadata and Nest's DI container read.

If you hit a post saying decorators don't compile in the native port, check its date. The TypeScript team's own December 2025 progress note said downlevel emit went "as far back as the es2021 target, and with no support for compiling decorators", and that line was written around the time the PR merged. It's stale.

One thing worth being honest about: nobody has published a byte-for-byte diff of the two compilers' metadata output across a real Nest app with entities, guards and custom param decorators. Build both, boot the app, run the e2e suite. DI failures from missing metadata are loud, so this check is cheap.

Why can't nest build use tsgo?

Because the Go compiler is a CLI, and nest build wants a library. The Nest CLI loads the typescript package and drives it directly:

// @nestjs/cli, lib/compiler/compiler.ts
const createProgram = tsBinary.createIncrementalProgram || tsBinary.createProgram;
const program = createProgram.call(ts, { rootNames, projectReferences, options });
const emitResult = program.emit(undefined, undefined, undefined, undefined, {
  before, after, afterDeclarations,   // <- CLI plugins hook in here
});

None of those exist in 7.0. The release post is blunt about it: "TypeScript 7.0 is here, it does not ship with an API," with a new and different API expected in 7.1.

There's a second-order trap. The CLI's TypeScript loader resolves from process.cwd() first, so it picks up whatever typescript your project has installed in preference to its own bundled copy. Install 7.0 into a Nest project and nest build doesn't report a type error, it fails reaching for a function that isn't there. As of @nestjs/cli 11.0.24 the supported builders are tsc, swc and webpack; there is no tsgo builder, and the request for one is nestjs/nest#15620.

Which Nest plugins and dev dependencies break?

Anything that reads your AST. The Swagger and GraphQL CLI plugins are ordinary TypeScript transformers, and they take a ts.Program:

// @nestjs/swagger, lib/plugin/compiler-plugin.ts
export const before = (options?: Record<string, any>, program?: ts.Program) => ...

Those plugins are why your DTOs get @ApiProperty for free. Without a compiler API there is nowhere for them to run, so this isn't a version bump you can wait out per-package.

Then check devDependencies. A stock nest new project ships four more API consumers before you add anything: ts-jest, ts-loader, ts-node and typescript-eslint. That covers your test transform, webpack builds, seed scripts and lint. Swapping the test transform to @swc/jest removes one of them and is a good idea regardless of TypeScript 7, since ts-jest type-checks every test file on every run.

What in a NestJS tsconfig is now a hard error?

baseUrl is the one that catches Nest projects, because the CLI generated it. The warning has been showing up since TypeScript 6.0 (nestjs/nest#15883, opened 2025-11-05), and in 7.0 it stops being a warning. The fix is not ignoreDeprecations, which is itself gone: delete baseUrl and rewrite paths as relative to the tsconfig's own directory.

{
  "compilerOptions": {
    "baseUrl": "./",                       // remove
    "paths": { "@app/*": ["src/*"] }       // becomes "./src/*"
  }
}

Also removed in 7.0 and worth grepping across a monorepo's base tsconfig, not just the root one: moduleResolution of node or node10 (use nodenext or bundler), module of amd, umd, systemjs or none, target: es5, and downlevelIteration. Projects generated by Nest 11 are mostly clear already, since the starter moved to nodenext and ES2023; anything older carries the old defaults. A single pass that reports both the dead tsconfig flags and the Compiler-API consumers in your dependency tree: npx tsgo-ready.

What's the setup that works today?

Two compilers, each doing the job it can do. For a Nest project the direction of the swap is forced: the package literally named typescript has to stay on 6.x, because that's the one nest build, ts-jest, ts-loader and typescript-eslint resolve and import. TypeScript publishes a compatibility package for exactly this, and the alias is the team's own recommendation:

{
  "devDependencies": {
    "typescript": "npm:@typescript/typescript6@^6.0.2"
  },
  "scripts": {
    "typecheck": "npx -y -p typescript@7 tsc --noEmit -p tsconfig.build.json",
    "build": "nest build",
    "test": "jest"
  }
}

Running the 7.0 checker through npx -p keeps it out of node_modules/typescript, which is the whole point; installing it there is what breaks the build. Put typecheck in CI where the speed pays off and leave everything else on 6.x. If what you actually want is faster builds rather than faster checks, nest build -b swc already exists and already works, at the cost of no type-checking during the build. Pair it with the check above and you have both.

What's still unresolved

Three things, and pretending otherwise would be guessing:

Notes from fernforge, which maintains tsgo-ready. Checked 2026-07-20 against the TypeScript 7.0 release announcement (2026-07-08), microsoft/typescript-go PR #2343 (merged 2025-12-12), and the published source of @nestjs/cli 11.0.24.