Upgrade to Prisma ORM 5

Prisma ORM 5.0.0 introduces a number of changes, including the usage of our new JSON Protocol, . A full list of these changes can be found .

This guide explains how upgrading might affect your application and gives instructions on how to handle breaking changes within Prisma ORM 5.

Upgrade the prisma and @prisma/client packages to Prisma ORM 5

To upgrade to Prisma ORM 5 from an earlier version, you need to update both the prisma and @prisma/client packages.

npm
yarn
pnpm
$npm install @prisma/client@5
$npm install -D prisma@5

Before you upgrade, check each breaking change below to see how the upgrade might affect your application.

Version changes

Prisma ORM 5 includes some minimum version changes for Node.js, TypeScript, and PostgreSQL. To use Prisma version 5.0.0 and up, you will need to have at least the minimum versions below: See our system requirements for all minimum version requirements.

Node.js minimum version change

From Prisma ORM version 5.0.0, the minimum version of Node.js supported is 16.13.0. If your project uses an earlier version of Node.js, you will need to upgrade it.

Node.js v16.x is reaching in order to coincide with the end-of-life of OpenSSL 1.1.1. For that reason, we recommend upgrading to the current Node.js LTS, v18.x. Please note that Prisma ORM 5 will be the last major version of Prisma ORM to support Node.js v16.

TypeScript minimum version change

From Prisma ORM version 5.0.0, the minimum version of TypeScript supported is 4.7. If your project uses an earlier version of TypeScript, you will need to upgrade it.

PostgreSQL minimum version change

From Prisma ORM version 5.0.0, the minimum version of PostgreSQL supported is 9.6. If your project uses an earlier version of PostgreSQL, you will need to upgrade it.

While Prisma ORM supports PostgreSQL versions 9.6 and above, we strongly recommend updating to a version that is currently supported and still receiving updates. Please check to determine which versions are currently supported.

Prisma Client embedded SQLite version updated

With Prisma ORM version 5.0.0, we have upgraded the embedded version of SQLite from 3.35.4 to 3.41.2. We did not see any breaking changes and don't anticipate any changes needed in user projects, but if you are using SQLite, especially with raw queries that might go beyond Prisma ORM's functionality, make sure to check .

Primary changes

This section gives an overview of the main breaking changes in Prisma ORM 5.

Removal of rejectOnNotFound parameter

With Prisma ORM 5, the deprecated parameter rejectOnNotFound has been removed. Depending on if your project used rejectOnNotFound per query or globally, there will be be different ways of updating your code.

If you are using the rejectOnNotFound parameter on a per-query basis, then follow our steps for updating your code at the query level.

If instead you have set up the rejectOnNotFound parameter at the client level, you will need to follow the steps for updating your code at the client level.

jsonProtocol out of Preview

The jsonProtocol preview feature is now Generally Available. This new protocol leads to when compared to our previous GraphQL-based protocol. When upgrading to Prisma ORM 5, make sure to remove jsonProtocol from your preview features, if added.

Prisma ORM 4 and lower:

generator client {
provider = "prisma-client-js"
previewFeatures = ["jsonProtocol"]
}

Prisma ORM 5:

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

Please review our jsonProtocol changes guide to learn how to update your app to account for the new protocol in Prisma ORM 5. You will need to:

Removal of array shortcuts

Prisma ORM 5 drops support for a number of "array shortcuts". These shortcuts were a way to add a single element as a value to an array-based operator instead of wrapping that one element in an array. To make our typings more consistent and logical and to conform to the new JSON Protocol, we now require array values for these operators.

In most cases, the fix will be as simple as wrapping the existing value in an array. The shortcuts removed in Prisma ORM 5 are:

While OR, in, and notIn operators are affected, AND and NOT are not affected by this change.

cockroachdb provider is now required when connecting to a CockroachDB database

With Prisma ORM version 5.0.0, we require the cockroachdb provider to be used when connecting to CockroachDB databases. Previously, we had accepted postgresql as well, but we are removing that option.

If you were using native database types and also the postgresql provider, you will need to baseline your database from PostgreSQL to CockroachDB:

  1. Backup your existing schema.prisma file (e.g. use version control)
  2. Update your datasource provider from postgresql to cockroachdb
  3. Use npx prisma db pull --force in order to overwrite your existing Prisma schema file (including native types) to those that are on your CockroachDB instance.
  4. Review changes between your Prisma schema backup and the new Prisma schema generated by db pull. You can either use the new schema as is, or update it to include your preferred spacing, comments, etc.
  5. Delete your existing migrations. We will be performing a baseline in order to make your local setup agree with your existing CockroachDB instance.
  6. Perform the baselining steps. After these steps, you'll have migrated successfully from the postgresql provider to the cockroachdb provider!

Removal of runtime/index.js from generated client

The runtime/index.js file has been removed from Prisma Client.

Using public APIs from @prisma/client/runtime

Importing from @prisma/client/runtime is no longer available in Prisma ORM 5. If you were using public APIs available in this namespace before, you can instead import Prisma and access them. For example:

import { Decimal, NotFoundError } from '@prisma/client/runtime'
const num = new Decimal(24.454545)
const notFound = new NotFoundError()

will need to be changed to

import { Prisma } from '@prisma/client'
const num = new Prisma.Decimal(24.454545)
const notFound = new Prisma.NotFoundError()

Using private APIs for a specific runtime

We highly discourage the use of internal private APIs as they can change without warning and are not guaranteed to be supported. If your usage requires a private API that was previous available

Generated type changes

Changes to RelationFilterInput to account for nullability

Prior to Prisma ORM 5, there was a long-standing bug that caused nullable reverse relations to not be marked as nullable in our generated types. For example, take the following schema:

model User {
id Int @id
addressId Int @unique
address Address @relation(fields: [addressId], references: [id])
post Post[]
}
model Address {
id Int @id
user User?
}
model Post {
id Int @id
userId Int
user User @relation(fields: [userId], references: [id])
}

In the generated types, Address.user and Post.user would use the same type, UserRelationFilter. This is obviously unintended as Address.user is nullable while Post.user is not. In Prisma ORM 5, the type of Address.user would be UserNullableRelationFilter, resolving this issue.

If you import generated types in your code, you will need to update instances like this to utilize the new Nullable types.

Changes to UncheckedUpdateManyInput to avoid name collisions

In certain instances it was possible for name collisions to occur when one model had two foreign keys to two other models that had the same property name for the reverse relation. As an example, the following schema:

model Invoice {
InvoiceId Int @id @default(autoincrement())
invoice_items InvoiceItem[]
}
model InvoiceItem {
InvoiceLineId Int @id @default(autoincrement())
InvoiceItemInvoiceId Int @map("InvoiceId")
invoices Invoice @relation(fields: [InvoiceItemInvoiceId], references: [InvoiceId])
TrackId Int
tracks Track @relation(fields: [TrackId], references: [TrackId])
}
model Track {
TrackId Int @id @default(autoincrement())
Name String
invoice_items InvoiceItem[]
}

Would lead to conflicting names between the two relations on InvoiceItem. The reverse relations, that is Invoice.invoice_items and Track.invoice_items would both get the type InvoiceItemUncheckedUpdateManyWithoutInvoice_itemsInput. In Prisma ORM 5, this is resolved and Prisma Client will generate InvoiceItemUncheckedUpdateManyWithoutInvoicesInput and InvoiceItemUncheckedUpdateManyWithoutTracksInput respectively.

If you import generated types in your code, you will need to update instances like this to the corrected types.

Other changes

The following changes may cause an application to initially throw an error message after upgrading to Prisma ORM 5. Fortunately, they are easy to solve, as the underlying functionality has been removed for a while or the change is a simple string replace.

Removal of deprecated Prisma CLI flags

Several deprecated CLI flags have been removed. All following flags are from previous APIs and are no longer needed:

  • --preview-feature used in db execute, db seed, and db diff
  • --experimental and --early-access-feature used in migrate
  • --force/-f used in db push
  • --experimental-reintrospection and --clean used in db pull

The outdated use of db push --force can be replaced with the newer implementation db push --accept-data-loss.

All other flags are from previous APIs and are no longer needed.

Removal of the beforeExit hook from the library engine

The beforeExit hook has been removed from the Prisma ORM library engine. While this functionality is still required for the Prisma ORM binary engine in order to run last minute queries or perform shutdown related operations, it provides no benefit over native Node.js exit hooks in the library engine. Instead of this hook we recommend using built-in Node.js exit events.

The following code with Prisma ORM 4:

const exitHandler = () => {
// your exit handler code
}
prisma.$on('beforeExit', exitHandler)

Could become:

const exitHandler = () => {
// your exit handler code
}
process.on('exit', exitHandler)
process.on('beforeExit', exitHandler)
process.on('SIGINT', exitHandler)
process.on('SIGTERM', exitHandler)
process.on('SIGUSR2', exitHandler)

If you're using the beforeExit hook in NestJS, you can upgrade to Prisma ORM 5 by removing the custom enableShutdownHooks method in your service:

"prisma.service.ts"
1@Injectable()
2export class PrismaService extends PrismaClient implements OnModuleInit {
3 async onModuleInit() {
4 await this.$connect()
5 }
6
- async enableShutdownHooks(app: INestApplication) {
- this.$on('beforeExit', async () => {
- await app.close()
- })
- }
12}

Instead, use the built-in enableShutdownHooks method in NestJS if you need to handle lifecycle events:

"main.ts"
- prismaService.enableShutdownHooks(app)
+ app.enableShutdownHooks()

Removal of deprecated prisma2 executable

When we released Prisma ORM 2, the prisma2 executable was used in order to differentiate from Prisma 1. In a later release, the prisma2 cli took over the prisma executable name.

Needless to say, the prisma2 executable has been deprecated for some time and is now removed. If your scripts use Prisma CLI as prisma2, please replace it with simply prisma.

Removal of deprecated experimentalFeatures property

The previewFeatures field of the generator block used to be called experimentalFeatures. We are removing that deprecated property.

In Prisma ORM 5, you will need to update references of experimentalFeatures to previewFeatures manually or use the new code action in the Prisma VSCode extension.

migration-engine renamed to schema-engine

The engine responsible for commands like prisma migrate and prisma db has been renamed from migration-engine to schema-engine to better describe its use. For many users, no changes will be required. However, if you need to explicitly include or exclude this engine file, or refer to the engine name for any other reason, you will need to update your code references.

Example with the Serverless Framework

One example we have seen is projects using the Serverless Framework. In these instances, you will need to update any patterns that reference migration-engine to instead reference schema-engine.

package:
patterns:
- '!node_modules/.prisma/client/libquery_engine-*'
- 'node_modules/.prisma/client/libquery_engine-rhel-*'
- '!node_modules/prisma/libquery_engine-*'
- '!node_modules/prisma/migration-engine-*'
- '!node_modules/prisma/schema-engine-*'

The recommended rule from our documentation is not affected by this change as it excludes all non desired engine files.

package:
patterns:
- '!node_modules/.prisma/client/libquery_engine-*'
- 'node_modules/.prisma/client/libquery_engine-rhel-*'
- '!node_modules/prisma/libquery_engine-*'
- '!node_modules/@prisma/engines/**'

Enjoy Prisma ORM 5!