Back to Blog
Migrating from Prisma v5 to v7 (Without Breaking Production)
backendprismadatabasemigration

Migrating from Prisma v5 to v7 (Without Breaking Production)

A practical migration guide from Prisma v5 to v7 — what breaks, how to fix it, and what performance changes to expect.

Prisma v7 is not just a version bump. It changes how datasource URLs are configured, how Prisma Client is generated, and how the client connects to your database at runtime.

In this guide, I'll cover a practical migration path from Prisma v5 to v7, what breaks, how to fix it, and what performance changes to expect.

Before you start

Prerequisites — check these before touching any code:

  • Node.js ≥ 18.18 (Prisma v7 drops older LTS lines). Use node -v to confirm.
  • TypeScript ≥ 5.1 recommended. Older versions may cause type-recursion issues with the new generated client.
  • MongoDB users — Prisma v7 does not support MongoDB yet. Stay on v6 until official support lands.
  • Package managernpm, pnpm, and yarn all work, but make sure lockfiles are committed before you start upgrading.

Common terms used in this guide

  • Prisma Client: The generated type-safe database client your app imports.
  • Driver Adapter: The DB driver bridge Prisma v7 now requires (for example @prisma/adapter-pg).
  • prisma.config.ts: New config entry point where datasource URLs now belong.
  • Generated Output Path: Where Prisma client files are generated (no longer defaulting to node_modules with new generator).

1. Why move to v7?

  • Better architecture for modern runtimes.
  • Smaller deployment footprint (especially with the new client path).
  • Cleaner separation between schema and environment config.
  • Future-proofing: prisma-client-js is legacy direction; prisma-client is the forward path.

2. Breaking changes you must handle

2.1 Datasource URL is no longer in schema.prisma

Before (v5 style):

datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")
  directUrl = env("DIRECT_URL")
}

After (v7 style):

datasource db {
  provider = "postgresql"
}

And move URL config to prisma.config.ts:

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

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

Which URL variable? Most apps use DATABASE_URL for the main runtime connection and DIRECT_URL (or a shadow-database URL) specifically for migrations. In prisma.config.ts, set the url to whatever your app uses at runtime — typically DATABASE_URL. If you run migrations through a separate direct connection, configure that in your migration scripts or CI, not here.

2.2 Generator changes (prisma-client-js → prisma-client)

Before:

generator client {
  provider = "prisma-client-js"
}

After:

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

Now imports must come from generated path, not @prisma/client:

// before
import { PrismaClient } from "@prisma/client";

// after
import { PrismaClient } from "../generated/prisma/client";

2.3 Driver adapter is required at runtime

For PostgreSQL:

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

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

export const prisma = new PrismaClient({ adapter });

2.4 Platform requirements increased

Make sure your runtime/toolchain is compatible — Node ≥ 18.18 and TypeScript ≥ 5.1 are expected. Check the Prisma system requirements page for the latest specifics.

2.5 Also changed in v7

These won't block the core migration, but they will bite you later if you ignore them:

  • Middleware removed — If you use prisma.$use(), it no longer exists. Replace middleware with client extensions ($extends), which offer the same hook points with better type safety.
  • Auto-seeding removedprisma migrate dev and prisma migrate reset no longer run your seed script automatically. Run prisma db seed explicitly after migrations.

2.6 ESM and module format

Prisma v7's new generator and prisma.config.ts lean towards ESM conventions. If your project is heavily CommonJS, plan the module-format changes early — you may need to adjust tsconfig.json ("module", "moduleResolution") and potentially add "type": "module" in package.json or use .mts extensions. Check Prisma's docs for ESM-specific guidance before you start rewriting imports.


3. Migration flow (safe order)

  1. Upgrade packages (prisma, client package, adapter/driver).
  2. Move datasource URL config into prisma.config.ts.
  3. Update generator to prisma-client with output.
  4. Regenerate client (prisma generate).
  5. Rewrite imports to generated client path.
  6. Update Prisma bootstrap to use adapter.
  7. Run:
prisma validate
prisma db pull    # or prisma migrate ... as needed
tsc --noEmit
# full build + smoke test

4. Performance expectations after migration

What usually improves:

  • Startup/deploy ergonomics.
  • Better control over runtime driver behavior.
  • Leaner generated-client usage pattern.

What to watch carefully:

  • Connection pooling behavior is now from your DB driver (pg, etc.), not old Prisma defaults.
  • Query performance can improve, but measure before/after with your own workloads.
  • If you see new timeout behavior, tune pool options explicitly.

5. Common migration errors and fixes

Argument "url" is missing in datasource

Means Prisma config isn't being resolved by editor/CLI. Fix prisma.config.ts env loading and restart Prisma language server.

PrismaClient ... requires adapter or accelerateUrl

You created client without adapter in v7 architecture. Pass adapter in new PrismaClient({ adapter }).

Build crash / TypeScript recursion after upgrade

  • Simplify overly deep Prisma generic types.
  • Remove old runtime-library type imports.

6. CI/CD changes you should have

In pipeline before build/deploy:

npm ci
npm run prisma:pull:prod
npm run prisma:generate:prod
npm run build

If generated client folder is not committed, CI must always generate it.


Rollback plan

Before you cut over to production, have a way back:

  • Keep a branch pinned to Prisma v5 with the old schema and client setup. If something goes wrong, you can revert package versions and redeploy from this branch within minutes.
  • Don't delete the old generated client path until your CI is fully green and production has been stable for at least a few days.
  • Lockfile discipline — commit your lockfile before the upgrade so a git revert on the version bump actually restores the exact dependency tree.

This matches the "config first, validate aggressively" approach — you want the safety net in place before you need it.


Checklist

Low Priority

  • Standardize one Prisma bootstrap file for whole app.
  • Remove legacy @prisma/client imports once generated-path migration is done.
  • Keep docs for team onboarding updated.

Medium Priority

  • Add migration smoke tests for critical queries.
  • Benchmark key APIs before/after migration.
  • Tune DB pool settings for production traffic.

High Priority

  • Ensure prisma.config.ts is correct and env-resolvable in local + CI.
  • Ensure adapter-based client init is used everywhere.
  • Block deploy if prisma validate or tsc --noEmit fails.
  • Confirm rollback plan before production cutover.

7. Benefits we saw after migration

After completing the migration across our product codebase, here's what actually changed:

  • Smaller deploy size — the new prisma-client generator produces a leaner output compared to the old prisma-client-js. Our deploy artifact dropped noticeably.
  • Faster cold starts — deploy artifacts often shrink and cold starts can improve because the new client generation model changes what gets packaged and how connections are handled. Serverless and edge deployments benefit the most.
  • Full control over connection pooling — with the driver adapter (pg Pool), we now own the pool config entirely. No more guessing what Prisma's internal pool is doing. We tuned max, idleTimeoutMillis, and connectionTimeoutMillis to match our traffic patterns.
  • Cleaner separation of concerns — moving the datasource URL out of schema.prisma into prisma.config.ts means the schema is truly environment-agnostic. No more env("DATABASE_URL") scattered in schema files.
  • Simpler debugging — since the runtime driver is now a standard pg Pool, we can attach listeners, log queries, and inspect connections the same way we would in any Node.js app — no Prisma-specific workarounds.
  • Future-proof architecture — the prisma-client generator is the forward path. Staying on prisma-client-js means you'll eventually hit a dead end when new features only land in the new generator.

Prisma v7 migration is very manageable once you treat it as an architecture shift, not just a package upgrade. Do config first, client generation second, runtime adapter third, then validate aggressively.

Links / References

Design & Developed by Dhruv Vasisht
© 2026. All rights reserved.