← Back to Blog

Where Prisma ORM Generates Client Code (and Why)

Nikolas Burk
Will Madden
Nikolas Burk, Will Madden
May 23, 2025
Updated July 6, 2026

Since Prisma ORM v7, Prisma Client is generated into a folder you choose inside your project source, such as src/generated/prisma. The output option is required, and the generated code is treated like regular application code. Earlier versions generated the client into node_modules by default. This post explains how the current setup works, why the original default existed, and how to migrate if you are still on the old generator.

Where Prisma Client lives today

In Prisma ORM v7, the default generator is prisma-client. It requires an explicit output path and writes the generated client into your project source tree:

// prisma/schema.prisma
generator client {
  provider = "prisma-client"           // rust-free and ESM
  output   = "../src/generated/prisma" // required
}

datasource db {
  provider = "postgresql"
}

Project configuration, including your database connection, lives in prisma.config.ts:

// prisma.config.ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
  },
  datasource: {
    url: env("DATABASE_URL"),
  },
});

The fastest way to get a DATABASE_URL is Prisma Postgres, the managed PostgreSQL database that integrates natively with Prisma ORM. A single command provisions a database and gives you the connection string to put in your .env file:

npm create db

After running prisma generate, you import the client from the output location instead of @prisma/client. The rust-free client talks to your database through a driver adapter, so install the one for your database (npm install @prisma/adapter-pg for PostgreSQL) and pass it to the constructor:

import { PrismaClient } from "./generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";

const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });

That's the whole model: the generated client is part of your application code, your build tools see it like any other source file, and nothing in node_modules is modified after installation.

Why Prisma ORM generates code at all

Since its initial release, Prisma ORM has used code generation to produce a database client (called "Prisma Client") that's tailored to your database schema. Prisma Client is auto-generated from the Prisma schema so that it knows the structure of your models and can provide custom, type-safe queries for them.

Code generation isn't the most conventional method in the TypeScript ecosystem, and Prisma ORM was one of the first popular libraries to rely on it. The payoff is a client API that matches your schema exactly, with autocomplete and compile-time guarantees for every query.

Why the client used to live in node_modules

To keep things familiar for developers, earlier versions of Prisma ORM generated Prisma Client into the node_modules folder by default, because that's how developers typically integrate third-party libraries into their applications. A custom location was always possible via the output field, but the default gave Prisma ORM unified behavior across frameworks and usage contexts.

Generating Prisma Client into node_modules led to a magical "it just works™️" developer experience for most people … except when it didn't.

Many tools across the JS/TS ecosystem assume that the node_modules directory is only modified by your package manager (npm, pnpm, yarn etc.). With Prisma ORM, however, you need to re-generate Prisma Client after every database schema change so the generated code reflects the latest state of your database. That requirement, combined with the node_modules default, violated the assumption of many tools in the ecosystem.

Because of this, we (and others in the community) had to put workarounds in place to keep the DX smooth:

  • The TS language server doesn't watch for changes in node_modules, so the Prisma VS Code extension rebooted the TS language server any time you ran prisma generate.
  • The @prisma/nextjs-monorepo-workaround-plugin package existed solely to ensure files were copied properly from node_modules when Prisma ORM was used in monorepos with Next.js.
  • Dockerfiles needed dedicated COPY steps for node_modules/.prisma and node_modules/@prisma so the generated client survived multi-stage builds.

Workarounds existed in various shapes and forms, from dedicated packages to hardcoded code paths. They all traced back to the same core issue: generated code living in a folder that tools expect to be immutable.

What changed in Prisma ORM v7

As part of making the DX of Prisma ORM simpler and more predictable by removing magical behavior and unnecessary abstraction layers, Prisma ORM v7 made the prisma-client generator the default and made the output path required. The old prisma-client-js generator, with its node_modules generation, is in maintenance mode.

This approach has several benefits:

  • The generated code is treated like regular application code. You have full control over it and decide how it becomes part of your application bundle.
  • More predictability. File watchers, linters, and bundlers react to prisma generate like they would to any other source change, so the old workarounds are no longer needed.
  • Compliance with ecosystem assumptions. Your package manager is the only thing that touches node_modules.

The new generator also ships without the Rust query engine, supports ESM, and is compatible with various JS runtimes (Node.js, Deno, Bun, Cloudflare Workers, and more). The rust-free client produces up to 90% smaller bundles and executes queries up to 3x faster; the benchmarks tell the full story.

Migrating from prisma-client-js

If your project still uses the prisma-client-js generator, the switch is small:

generator client {
-  provider = "prisma-client-js"
+  provider = "prisma-client"
+  output   = "../src/generated/prisma"
}

Then:

  1. Run npx prisma generate.
  2. Update your imports from @prisma/client to your output location, e.g. ./generated/prisma/client.
  3. Install the driver adapter for your database (npm install @prisma/adapter-pg for PostgreSQL) and construct the client with it: new PrismaClient({ adapter }), as shown above.
  4. Exclude the generated folder from linting and formatting (for example in your ESLint ignore config). The code is generated, so lint findings there don't matter, and tools like the Next.js dev server can otherwise halt on them.

Common errors and how to fix them

"An output path is required for the prisma-client generator": add an output field to your generator block, as shown above. Any location in your source tree works; we suggest ../src/generated/prisma (relative to your schema file).

"PrismaClient needs to be constructed with a non-empty, valid PrismaClientOptions": the prisma-client generator connects through a driver adapter. Install the adapter for your database (for PostgreSQL, @prisma/adapter-pg) and pass it to the constructor: new PrismaClient({ adapter }).

"@prisma/client did not initialize yet. Please run prisma generate": this error comes from importing @prisma/client before the client was generated. Run npx prisma generate (it also runs automatically on npm install via the postinstall hook in many setups). If you're on the prisma-client generator, check that you're importing from your output path instead of @prisma/client.

Lint or type errors inside the generated folder: exclude the output directory from ESLint, Prettier, and any strict tsconfig includes. Generated code is meant to be consumed, and it doesn't need to pass your project's style rules.

Docker builds and monorepos: with the client generated into your source tree, it's bundled with your application like any other module. The COPY node_modules/.prisma steps and the @prisma/nextjs-monorepo-workaround-plugin are no longer needed on the prisma-client generator.

Looking ahead: Prisma Next

Prisma ORM v7 is the production version today. Prisma Next is where the ORM is heading: the next generation, available in Early Access now, becoming Prisma 8 at GA. You describe your models and relationships in a single data contract, Prisma generates the migrations, and you or your coding agent write type-safe queries in terms of your models. Every query returns structured, machine-readable output, and every operation comes with guardrails, so humans and AI agents can iterate quickly without breaking things.

It's also fast. In our published benchmark, a fork of the open-source drizzle-benchmarks suite, Prisma Next reaches roughly 90% of the raw pg driver's speed, holds p95 latency around 4 ms at 6,000 to 7,000 requests/second, and keeps scaling to about 12,500 requests/second, roughly 50% beyond where Prisma 7 tops out. The client ships at about 148.5 KB gzipped, around 9x smaller than Prisma 7's, which translates directly into faster cold starts on serverless and edge.

Prisma Next pairs with Prisma Postgres the same way v7 does: provision a database in one step and connect with a single URL. If you're starting a new project, especially one built with AI coding agents, Prisma Next is the direction to watch.

Wrap-up

Prisma Client now lives where the rest of your code lives. That single decision removed a whole category of workarounds and made Prisma ORM more predictable across bundlers, monorepos, and deploy targets. If you're starting fresh, npm create db gives you a Prisma Postgres database and a ready-to-run v7 setup in one step.

As always, reach out to us on X or join our Discord if you have any feedback or questions!

About the author

Will Madden
Will Madden

Will leads the engineering team behind Prisma's open source ORM and guides its technical direction, with more than 15 years in software and an open source trail stretching back to 2008. He has appeared on podcasts including PodRocket to discuss ORM architecture and direction, and writes about ORM design, engineering leadership, and shipping software other engineers depend on.

Keep reading

Build your next app with Prisma

Start free. Scale when you’re ready.

Try Prisma
Share this article