From prisma-skills
This skill should be used when the user asks to "migrate Prisma to custom output", "fix Prisma monorepo hoisting", "upgrade prisma-client-js to prisma-client", "move Prisma out of node_modules", or encounters "stale Prisma types after deploy", "prisma-client-js deprecated", or build failures where PrismaClient types are missing models in a Turborepo/monorepo. Guides the migration from deprecated prisma-client-js (node_modules output) to prisma-client (custom output directory) in Prisma 7.
npx claudepluginhub pwarnock/pwarnock-cc-plugins --plugin prisma-skillsThis skill uses the workspace's default tool permissions.
Migrate a Prisma 7 project from the deprecated `prisma-client-js` generator (which outputs to `node_modules/.prisma/client/`) to the `prisma-client` generator with a custom output directory. This eliminates an entire class of monorepo bugs caused by stale nested `node_modules` copies.
Provides key facts and breaking changes for Prisma ORM v7 upgrades. Use before client generation, schema changes, or v7 troubleshooting.
Updates Claude on Prisma 5.19+ to 7.3 changes: v7 ESM rewrite, prisma-client generator, driver adapters, prisma.config.ts, TypedSQL, SQL comments. Load before Prisma projects.
Provides expert guidance on Prisma ORM schema design, migrations, query optimization, relations modeling, and database operations for PostgreSQL, MySQL, SQLite.
Share bugs, ideas, or general feedback.
Migrate a Prisma 7 project from the deprecated prisma-client-js generator (which outputs to node_modules/.prisma/client/) to the prisma-client generator with a custom output directory. This eliminates an entire class of monorepo bugs caused by stale nested node_modules copies.
Citations:
With prisma-client-js, the generated client lives in node_modules/.prisma/client/. In monorepos, this causes:
node_modules/@prisma/client/ copies in workspace packages that declare @prisma/client as a dependency. prisma generate writes to root, but TypeScript resolves through the nested copy.node_modules between deploys. After schema changes or Prisma upgrades, the cached nested copies contain stale types.Property 'X' does not exist on type 'PrismaClient' when the model IS in the schema.With prisma-client, the generated client lives in a directory controlled by the project (e.g., packages/db/src/generated/prisma/). No node_modules resolution games.
Check the schema file for the deprecated pattern:
# DEPRECATED — needs migration
generator client {
provider = "prisma-client-js"
# no output directive — defaults to node_modules
}
Check for nested .prisma directories:
find packages -path '*/node_modules/.prisma' -type d
If either is true, proceed with migration.
Change the generator block in the schema file (usually prisma/schema.prisma):
generator client {
provider = "prisma-client"
output = "<relative-path-to-output>"
}
The output path is relative to the schema file. Common patterns:
| Schema location | DB package location | Output value |
|---|---|---|
prisma/schema.prisma | packages/db/src/ | "../packages/db/src/generated/prisma" |
packages/db/prisma/schema.prisma | packages/db/src/ | "../src/generated/prisma" |
schema.prisma (root) | src/ | "./src/generated/prisma" |
.gitignoreAdd the new generated output directory and remove the old node_modules-based entry:
# Prisma generated client (output of `prisma generate`)
<path-to-generated-dir>
prisma generatebunx prisma generate # or npx/pnpm exec
Verify output appears at the configured path.
Change all imports in the database package from @prisma/client to the generated path:
// Before
import { PrismaClient } from '@prisma/client'
import { Prisma } from '@prisma/client'
// After
import { PrismaClient } from './generated/prisma/client'
import { Prisma } from './generated/prisma/client'
The database package barrel (index.ts) should re-export everything downstream needs:
export { prisma } from './client'
export { Prisma, PrismaClient } from './generated/prisma/client'
export type { YourModel, YourEnum } from './generated/prisma/client'
Re-exporting PrismaClient allows seed files and CLI scripts to construct their own instances when needed.
@prisma/client as a Runtime DependencyDo NOT remove @prisma/client from dependencies. The generated client internally imports @prisma/client/runtime/client for the Prisma runtime engine. What changes is that your code no longer imports PrismaClient or types from @prisma/client — you import from the generated path instead. But the package itself must remain installed.
{
"dependencies": {
"@prisma/adapter-pg": "^7.4.0",
"@prisma/client": "^7.4.0",
"pg": "^8.17.1"
}
}
Why it works locally without it: Bun/npm/pnpm hoist @prisma/client to root node_modules (transitively via prisma CLI). But CI's Vite import analysis resolves from the package directory context, where it may not be found if not declared as a direct dependency.
Files that construct their own PrismaClient (seeds, scripts) need updated imports:
// Before
import { PrismaClient } from '@prisma/client'
// After — use relative path to generated dir
import { PrismaClient } from '../../packages/db/src/generated/prisma/client'
// Or import through the DB package (if it re-exports PrismaClient)
import { PrismaClient } from '@baptize/db'
If the project had workarounds for nested .prisma cleanup, remove them. The postinstall only needs:
"postinstall": "DATABASE_URL=${DATABASE_URL:-placeholder} prisma generate || true"
# Regenerate from scratch
rm -rf <generated-output-dir>
bunx prisma generate
# Type check
bunx tsc --noEmit
# Tests
bunx vitest run
# Confirm no stale imports
grep -rn "from '@prisma/client'" packages/ apps/ src/
Vercel's build command should still run prisma generate — it writes to the source tree, not node_modules, so caching issues are eliminated:
cd ../.. && DATABASE_URL=placeholder bunx prisma generate && bunx turbo build
@prisma/adapter-pg (and other adapters) remain as regular npm dependencies — only @prisma/client is removed. The adapter is imported normally:
import { PrismaPg } from '@prisma/adapter-pg'
When re-exporting model types from the DB package, use export type for types and export for runtime values:
// Runtime values
export { prisma } from './client'
export { Prisma, PrismaClient } from './generated/prisma/client'
// Type-only exports
export type { User, Organization } from './generated/prisma/client'
'use step' functions that dynamically import @baptize/db work unchanged — the import resolves through the workspace package, which now internally uses the generated path:
'use step'
const { prisma } = await import('@baptize/db') // no change needed
references/migration-checklist.md — Step-by-step checklist with verification commandsreferences/troubleshooting.md — Common errors and fixes during migrationexamples/schema-generator.prisma — Correct generator block examplesexamples/db-package-index.ts — Barrel exports from generated pathThe singleton client pattern (with lazy proxy and PrismaPg adapter) is documented inline in Step 4 above. The only import change is PrismaClient from the generated path instead of @prisma/client.