Is there an existing issue for this?
Current behavior
nest build exits with code 0 but produces no dist/ directory, no errors, no warnings. The build appears to succeed silently but emits zero files.
The behavior is flaky — sometimes it works (when no .tsbuildinfo exists), sometimes it silently skips emit (when a stale .tsbuildinfo is present). deleteOutDir: true in nest-cli.json makes it worse because it removes dist/ before emit, but the incremental compiler thinks nothing changed.
This affects nest build and nest start --watch (which reports "Found 0 errors" but dist/main.js doesn't exist).
Running tsc --project tsconfig.build.json directly works every time.
Minimum reproduction code
https://gist.github.com/ReemX/c9ad51f31a9abd5ed0d9b8678ddbc832
Steps to reproduce
- Create a new NestJS project:
nest new repro --strict
- Install TypeScript 6:
npm i typescript@6
- Add
"incremental": true to tsconfig.build.json compilerOptions (or inherit it from an extended config)
- Run
npx nest build
- Check
dist/ — it does not exist
Expected behavior
nest build should emit compiled JavaScript files to dist/ (same as tsc -p tsconfig.build.json).
Package version
11.0.17
NestJS version
11.1.17
Node.js version
22.18.0
In which operating systems have you tested?
Other
Root cause: In lib/compiler/compiler.js (line 21), the CLI prefers ts.createIncrementalProgram over ts.createProgram:
const createProgram = tsBinary.createIncrementalProgram || tsBinary.createProgram;
With TypeScript 6, createIncrementalProgram with incremental: true returns a program whose .emit() reports emitSkipped: false and diagnostics: [] but writes zero files to disk. The same call with createProgram works correctly.
Verification script (save as verify.js):
const ts = require('typescript');
const configPath = require('path').join(process.cwd(), 'tsconfig.build.json');
const { options, fileNames, projectReferences } = ts.getParsedCommandLineOfConfigFile(configPath, undefined, ts.sys);
const prog = ts.createIncrementalProgram({ rootNames: fileNames, projectReferences, options });
const result = prog.emit();
console.log('emitSkipped:', result.emitSkipped); // false
console.log('emittedFiles:', result.emittedFiles); // [] — empty!
console.log('dist exists:', require('fs').existsSync('dist')); // false
Workaround: Set "incremental": false in tsconfig.build.json.
This may also warrant a bug report on the TypeScript side (microsoft/TypeScript) since createIncrementalProgram silently succeeding with no output seems like a TS 6 regression.
Is there an existing issue for this?
Current behavior
nest buildexits with code 0 but produces nodist/directory, no errors, no warnings. The build appears to succeed silently but emits zero files.The behavior is flaky — sometimes it works (when no
.tsbuildinfoexists), sometimes it silently skips emit (when a stale.tsbuildinfois present).deleteOutDir: trueinnest-cli.jsonmakes it worse because it removesdist/before emit, but the incremental compiler thinks nothing changed.This affects
nest buildandnest start --watch(which reports "Found 0 errors" butdist/main.jsdoesn't exist).Running
tsc --project tsconfig.build.jsondirectly works every time.Minimum reproduction code
https://gist.github.com/ReemX/c9ad51f31a9abd5ed0d9b8678ddbc832
Steps to reproduce
nest new repro --strictnpm i typescript@6"incremental": truetotsconfig.build.jsoncompilerOptions (or inherit it from an extended config)npx nest builddist/— it does not existExpected behavior
nest buildshould emit compiled JavaScript files todist/(same astsc -p tsconfig.build.json).Package version
11.0.17
NestJS version
11.1.17
Node.js version
22.18.0
In which operating systems have you tested?
Other
Root cause: In
lib/compiler/compiler.js(line 21), the CLI prefersts.createIncrementalProgramoverts.createProgram:With TypeScript 6,
createIncrementalProgramwithincremental: truereturns a program whose.emit()reportsemitSkipped: falseanddiagnostics: []but writes zero files to disk. The same call withcreateProgramworks correctly.Verification script (save as
verify.js):Workaround: Set
"incremental": falseintsconfig.build.json.This may also warrant a bug report on the TypeScript side (
microsoft/TypeScript) sincecreateIncrementalProgramsilently succeeding with no output seems like a TS 6 regression.