Overview

Prisma 7 (released 2025-11-19) makes the Rust-free prisma-client generator the default, requires a driver adapter to connect, and removes the $use middleware API. Upgrading from Prisma 5 or 6 is mechanical but touches the schema, the client construction, and every import that pulled from @prisma/client. Do the steps in order; the generator swap must happen before regeneration. For the concepts behind each step, see prisma-driver-adapters and prisma-client-extensions.

Swap the generator and add a required output path

Change the generator block in schema.prisma from prisma-client-js to prisma-client, and add an output inside your source tree.

generator client {
  provider = "prisma-client"
  output   = "../src/generated/prisma"
}
  • prisma-client-js is the legacy generator. prisma-client is the Rust-free default.
  • output is required now and must live in your source tree, not node_modules. Pick a stable path like src/generated/prisma. See prisma-schema.
  • Remove driverAdapters from previewFeatures; adapters are GA in Prisma 7.

Gitignore the generated directory and keep postinstall

The generated client moved out of node_modules, so the ignore target moves with it.

# .gitignore
/src/generated/prisma
  • Add the new output directory to .gitignore. Do not commit generated code.
  • Keep prisma generate wired into postinstall so CI and fresh installs emit a current client. See prisma-client.
  • Run npx prisma generate after the generator swap before you build.

Install a driver adapter and pass it to the client

new PrismaClient() without an adapter throws in Prisma 7. Install the adapter for your engine and pass it in.

npm install @prisma/adapter-pg pg   # Postgres
import { PrismaClient } from "../src/generated/prisma/client"
import { PrismaPg } from "@prisma/adapter-pg"
 
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL })
export const prisma = new PrismaClient({ adapter })
  • Choose the adapter that matches your database. See prisma-driver-adapters.
  • The adapter owns the connection string; drop any datasources URL override that duplicated it.

Fix every import path

Imports of PrismaClient and the Prisma namespace move from @prisma/client to the generator’s output path.

// Before
import { PrismaClient, Prisma } from "@prisma/client"
 
// After
import { PrismaClient, Prisma } from "./generated/prisma/client"
  • Update raw-query helpers too: Prisma.sql, Prisma.join, and Prisma.raw are unchanged in behavior but import from the new path. See prisma-raw-queries.
  • A project-wide find-and-replace of the import specifier handles most of this.

Replace removed $use middleware with $extends

$use was deprecated in v4.16.0 and removed in v6.14.0. Any remaining prisma.$use(...) call must become a client extension.

// Before: removed middleware
// prisma.$use(async (params, next) => { ... })
 
// After: query-component extension
const prisma = base.$extends({
  query: {
    post: {
      findMany({ args, query }) {
        args.where = { ...args.where, deletedAt: null }
        return query(args)
      },
    },
  },
})
  • Port each middleware to a query component scoped to the model and operation it touched. See prisma-client-extensions.
  • After all five steps, run your test suite. Most breakages are import paths or a forgotten adapter.