nest-server-updating
Installation
SKILL.md
@lenne.tech/nest-server Update Knowledge Base
This skill provides knowledge and resources for updating @lenne.tech/nest-server. For automated execution, use the lt-dev:nest-server-updater agent via /lt-dev:backend:update-nest-server.
Important: After updating nest-server, also check if @lenne.tech/nuxt-extensions in projects/app/ needs a compatible update, as nuxt-extensions is aligned with nest-server.
Gotchas
- Crossing the jest→vitest boundary — At some point on the upstream
nest-server-startertimeline the test runner migrated from jest+ts-jest to vitest+unplugin-swc (check the starter'spackage.jsonfor the current truth — ifvitest-e2e.config.tsexists, the boundary is behind you). Updating an existing project across that boundary needs more than apnpm install: every@Propwhose property is a TypeScript union ('a' | 'b',null | string, an alias for either) must addtype: String(ortype: Objectfor record-likes), everyimport * as supertestmust become a default import, everyjest.*call must becomevi.*, andjest-e2e.json+babel.config.jsmust be removed. Without these, vitest fails with "Cannot determine a type for the X field" from Mongoose, or "is not a function" from supertest. The full recipe lives in themodernizing-toolchainskill — apply Phases 2 and 3 before runningpnpm test. A project still on jest when it reaches 12.x must migrate first: the NestJS 12 packages are ESM-only, and jest loads them only on Node 24.9+ (ERR_REQUIRE_ASYNC_MODULEbelow that). - The 12.0 step (NestJS 12, TypeScript 6) breaks builds without a single source change —
11.43.x-to-12.0.x.mdis the guide; four things in it catch most projects. (1) Raise every NestJS-family pin andtypescripttogether with nest-server (pnpm run updateraises the pins the project already declares): one@nestjs/*package left on 11 installs a second NestJS copy, and the build fails withClass 'X' incorrectly extends base class 'CoreX'. (2) TypeScript 6 turnsstricton, resolvesrootDirto the tsconfig's directory and defaultstypesto[], sotsconfig.jsonneeds"strict": false,"types": ["node", "vitest/globals"]and arootDirthestart:prodpath expects; an explicit"moduleResolution": "node"is error TS5107. (3)@nestjs/{jwt,mongoose,passport,schedule,swagger,terminus}resolve only from their package root, so a deep…/dist/…import fails withTS2307orERR_PACKAGE_PATH_NOT_EXPORTED. (4) A subclass that redeclares its constructor no longer inherits the parent's@Optional()flags; the symptom isNest can't resolve dependencies of the XService (…, ?). nest-server itself is an ES module from 12.0 on, like every@nestjs/*package, and CommonJS projects stay CommonJS: Node loads them all throughrequire(esm), which is why the Node floor matters (22.12+, nest-server'sengines.nodenames the exact one). A vendor-mode project has one more required step: its dev start moves from ts-node to the framework's loader (node -r ./src/core/modules/migrate/helpers/ts-compiler.js src/main.ts, guide §14), because the 12.x core imports./x.jsand ts-node cannot load it; without itpnpm startfails withCannot find module './core.module.js'while build,migrate:*and tests pass (details innest-server-core-vendoring). - ESM projects are optional, never part of the update — Converting a project to
"type": "module"(guide §17 "Converting a project to ESM") is worth it only for a package that loads from an ES module alone (top-levelawait,ERR_REQUIRE_ASYNC_MODULEunderrequire(esm)) or to matchnest new. Do it as its own step after the update is green, withlt server convert-esm --noConfirmin the API project or a workspace root withprojects/api(--dry-runpreviews; it refuses nest-server below 12 and, unless--force, a dirty git tree, so the conversion is one diff). What has no exact rewrite (a named import from a CommonJS package, a decorated field on an import cycle, a leftoverrequire) comes with file:line and exit 1: fix it by hand (generating-nest-servers→ ESM rules) and run the same command again, which on an ESM project re-checks without a clean tree. It ends with build, start of the BUILT server,migrate:listand dev start, because vitest passes code that Node's ESM loader refuses; with--skip-verify, or by the guide's steps on a CLI without the command, start the built server yourself. useDefineForClassFieldsmismatch — When migrating to vitest, both thetsconfig.jsoncompilerOptions.useDefineForClassFieldsand the swc plugin invitest-e2e.config.tsmust be set totrue. Mixing them (e.g. swc=false, ts=true) silently breaks NestJS DI:securityCheckgets the wrongcurrentUser, so usersignUpreturnscreatedBy: nulleven though the override service set it. There is no error, only test failures that look like business logic regressions.- Minor version bumps are treated as MAJOR —
@lenne.tech/nest-serverfollows a "stepwise update" policy even on minor versions. Jumping from7.5.xdirectly to7.9.xin one step is likely to miss breaking changes that were introduced sub-minor. Always run the update step-by-step viapnpm run update, even if the version gap looks small. pnpm run updaterequires the target version inpackage.jsonFIRST — The update script reads the current/target frompackage.json. Running it before bumping the version does nothing or produces confusing errors. Order: (1) bumppackage.json→ (2)pnpm install→ (3)pnpm run update.nuxt-extensionsalignment breaks silently —@lenne.tech/nuxt-extensionsis version-aligned with@lenne.tech/nest-server. Updating nest-server to7.19.0without also updating nuxt-extensions to7.19.xleaves the frontend consuming an outdated API contract. Types generated viagenerate-typesmay still pass locally but break at runtime on production.- Migration guides are cumulative — read ALL between old and new version — If you jump from
7.12to7.19, migration guides for7.13,7.14,7.15,7.16,7.17,7.18,7.19ALL apply. Don't skip reading them — each introduces non-trivial behavior changes. - Starter project is the ground truth for constellations — When a migration is ambiguous (e.g., which package.json override to add, which config value to change), check
nest-server-starter's currentpackage.jsonvia GitHub raw. It reflects the canonical working constellation for the target version.