You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
--template nest scaffolds NestJS 11 (CJS-style imports, no @nestjs/cli, tsdown build) and never closes the Prisma 8 pool on shutdown; should target NestJS 12 ESM #108
--template nest still scaffolds NestJS 11, does not install the Nest CLI, and never closes the Prisma 8 connection pool on shutdown. NestJS 12 (ESM-only) has been the current major for months and is what @nestjs/cli new produces today, so the template is the one place where "official Prisma + NestJS" and "official NestJS" disagree.
The docs page "How to use Prisma ORM with NestJS" (docs.prisma.io/docs/guides/frameworks/nestjs) sends every NestJS user to this template, so it is effectively the Prisma 8 NestJS guide.
NestJS 11 vs 12. The generated package.json pins ^11.1.17, so a user who scaffolds today and later runs nest g from a globally installed Nest 12 CLI gets schematics that emit .js-suffixed ESM imports into a project whose existing files are extensionless. npx --no-install nest build fails in the generated project (could not determine executable to run) because @nestjs/cli is not a dependency.
Extensionless imports only work because of tsdown. With "type": "module" in package.json, import { AppModule } from "./app.module" is not valid for Node; it works here only because tsdown resolves and bundles it. The moment someone swaps the build for tsc/nest build (the standard Nest workflow), every import breaks. NestJS 12 avoids this by spelling .js everywhere; the template should too.
No db.close() on shutdown.src/prisma/db.ts exports a long-lived postgres<Contract>(...) client and PrismaService just wraps it (readonly db = db). Nothing implements OnApplicationShutdown, and main.ts never calls app.enableShutdownHooks(), so a SIGTERM under a process manager or in a container leaves the pg.Pool to be killed rather than drained. The Prisma 8 runtime reference (references/runtime.md) is explicit that servers must close exactly once, on shutdown. This is the one NestJS-specific thing a template has to get right, since Prisma 7 users are used to enableShutdownHooks / $disconnect and will look for the equivalent.
Composer/Alchemy weight. The nest template pulls in @prisma/composer, @prisma/composer-prisma-cloud and alchemy@2.0.0-beta.74 (which brings the Cloudflare runtime) into a plain Node/Express server. That is fine as an opt-in, but it makes the scaffold a poor starting point for the majority of Nest users who deploy to their own infrastructure, and it is why install takes minutes on a cold cache. Related: Scaffolds pin the ORM exactly but install prisma@latest, so every ORM bump opens a mismatch window #101 (ORM pin vs prisma@latest mismatch window) shows how sensitive the template's dependency block is; fewer moving parts would help there too.
What I expected
A NestJS template that is a superset of npx @nestjs/cli@latest new, so the Nest CLI, schematics, and build all keep working:
@nestjs/* at ^12, plus @nestjs/cli, @nestjs/schematics, @nestjs/testing in devDependencies.
"build": "nest build", "prebuild": "prisma contract emit", "start:dev": "nest start --watch", "start:prod": "node dist/main". Keep tsdown only if a single-file bundle is needed for Composer deploys, as a separate build:composer script.
A PrismaModule that owns the lifecycle. Either of these is fine; I verified the first one end to end (build, unit + e2e tests, CRUD routes, db.transaction, clean exit on SIGTERM) on Nest 12.0.3 + @prisma/orm-postgres@8.0.0-rc.11:
or keep the current PrismaService { readonly db = db } class and add implements OnApplicationShutdown { onApplicationShutdown() { return db.close(); } } plus enableShutdownHooks().
Composer/Alchemy deps behind a flag (--deploy already exists) rather than in the base template.
Reproduction
npm create prisma@latest -- nest-ref --template nest --provider postgres --yes --skills none
cd nest-ref
npm ls @nestjs/core # 11.2.5
npm view @nestjs/core version # 12.0.3
npx --no-install nest build # npm error could not determine executable to run
grep -n 'from "./' src/*.ts # extensionless imports in a "type": "module" package
grep -rn 'close\|enableShutdownHooks\|OnApplicationShutdown' src/ ||echo"no teardown"
Summary
--template neststill scaffolds NestJS 11, does not install the Nest CLI, and never closes the Prisma 8 connection pool on shutdown. NestJS 12 (ESM-only) has been the current major for months and is what@nestjs/cli newproduces today, so the template is the one place where "official Prisma + NestJS" and "official NestJS" disagree.The docs page "How to use Prisma ORM with NestJS" (docs.prisma.io/docs/guides/frameworks/nestjs) sends every NestJS user to this template, so it is effectively the Prisma 8 NestJS guide.
Generated today with
create-prisma@0.13.1:What the template produces
npx @nestjs/cli@12 new)@nestjs/core/common/platform-express^11.1.17(resolves to 11.2.5)@nestjs/cli,@nestjs/schematics,@nestjs/testingnest build,nest g resource,nest start --watchall work"type": "module"but every relative import is extensionless (from "./app.module"), i.e. CommonJS spelling.jsextensions (from './app.module.js'),module: nodenexttsdownbundling todist/server.mjs, with a custom externals list for optional Nest peer depsnest build(tsc),dist/main.jstsx watch src/main.tsnest start --watch^5.9.3^6.0.2db.close()never called, noenableShutdownHooks)@prisma/composer,@prisma/composer-prisma-cloud,alchemy(Cloudflare runtime),@prisma/devNotes on the rows that matter most:
NestJS 11 vs 12. The generated
package.jsonpins^11.1.17, so a user who scaffolds today and later runsnest gfrom a globally installed Nest 12 CLI gets schematics that emit.js-suffixed ESM imports into a project whose existing files are extensionless.npx --no-install nest buildfails in the generated project (could not determine executable to run) because@nestjs/cliis not a dependency.Extensionless imports only work because of tsdown. With
"type": "module"inpackage.json,import { AppModule } from "./app.module"is not valid for Node; it works here only because tsdown resolves and bundles it. The moment someone swaps the build fortsc/nest build(the standard Nest workflow), every import breaks. NestJS 12 avoids this by spelling.jseverywhere; the template should too.No
db.close()on shutdown.src/prisma/db.tsexports a long-livedpostgres<Contract>(...)client andPrismaServicejust wraps it (readonly db = db). Nothing implementsOnApplicationShutdown, andmain.tsnever callsapp.enableShutdownHooks(), so a SIGTERM under a process manager or in a container leaves thepg.Poolto be killed rather than drained. The Prisma 8 runtime reference (references/runtime.md) is explicit that servers must close exactly once, on shutdown. This is the one NestJS-specific thing a template has to get right, since Prisma 7 users are used toenableShutdownHooks/$disconnectand will look for the equivalent.Composer/Alchemy weight. The nest template pulls in
@prisma/composer,@prisma/composer-prisma-cloudandalchemy@2.0.0-beta.74(which brings the Cloudflare runtime) into a plain Node/Express server. That is fine as an opt-in, but it makes the scaffold a poor starting point for the majority of Nest users who deploy to their own infrastructure, and it is why install takes minutes on a cold cache. Related: Scaffolds pin the ORM exactly but install prisma@latest, so every ORM bump opens a mismatch window #101 (ORM pin vsprisma@latestmismatch window) shows how sensitive the template's dependency block is; fewer moving parts would help there too.What I expected
A NestJS template that is a superset of
npx @nestjs/cli@latest new, so the Nest CLI, schematics, and build all keep working:@nestjs/*at^12, plus@nestjs/cli,@nestjs/schematics,@nestjs/testingindevDependencies.tsconfig.jsonwithmodule: "nodenext"/moduleResolution: "nodenext"(Nest 12 default) and relative imports spelled with.js. This currently requiresdb.tsto import./contract.jsrather than./contract.d; that is tracked inprisma orm initsilently rewrites an existing tsconfig.json (nodenext→preserve/bundler); generateddb.tsimports./contract.d, which does not resolve undernodenextorm#30358, and the template can just use the working spelling."build": "nest build","prebuild": "prisma contract emit","start:dev": "nest start --watch","start:prod": "node dist/main". Keeptsdownonly if a single-file bundle is needed for Composer deploys, as a separatebuild:composerscript.A
PrismaModulethat owns the lifecycle. Either of these is fine; I verified the first one end to end (build, unit + e2e tests, CRUD routes,db.transaction, clean exit on SIGTERM) on Nest 12.0.3 +@prisma/orm-postgres@8.0.0-rc.11:or keep the current
PrismaService { readonly db = db }class and addimplements OnApplicationShutdown { onApplicationShutdown() { return db.close(); } }plusenableShutdownHooks().Composer/Alchemy deps behind a flag (
--deployalready exists) rather than in the base template.Reproduction
Environment:
create-prisma@0.13.1, Node 24.11.1, npm 11.6.2, macOS 15.6. Generatedpackage.jsonresolves to@nestjs/core@11.2.5,@prisma/orm-postgres@8.0.0-rc.11,prisma@8.0.0-rc.15,typescript@5.9.3,tsdown@0.22.14.Related
db.close()on shutdown) and consider shipping@prisma/orm-nestjsorm#30359: request for a documented NestJS integration pattern /@prisma/orm-nestjs. If that lands, this template should use it.prisma orm initsilently rewrites an existing tsconfig.json (nodenext→preserve/bundler); generateddb.tsimports./contract.d, which does not resolve undernodenextorm#30358:orm initrewritesnodenexttsconfigs becausedb.tsimports./contract.d.--skip-install(parity withprisma orm init --skip-install): no way to scaffold files without installing dependencies #107:--skip-install, which would have made inspecting this template much cheaper.