Shared Prisma Client extensions

You can share your Prisma Client extensions with other users, either as packages or as code snippets, and import extensions that other users create into your Prisma projects.

Share Prisma Client extensions

When you want to create extensions that will work for other users, and not just for your specific schema, use the $all prefix, such as $allModels. Extensions that use $all apply generally, not just to a named component of a specific schema.

You do not need to use the $all prefix with the client component, because the client component always applies generally.

For example, a generic extension might take the following form:

const xprisma = prisma.$extends({
model: {
$allModels: {
// new method
findOrCreate(...) { } // code for the new method goes inside the brackets
}
}
})

Package an extension

Use Prisma.defineExtension to make your extensions shareable. You can use it to package a feature that you want to share with other users. When someone wants to use your extension in their project, they can apply the extension to a Prisma Client instance with prisma.$extends.

You can also use Prisma.defineExtension to move an extension to another file in your project. When you do this, you benefit from auto-completion and type checks.

To package an extension, you might use the following code:

import { Prisma } from '@prisma/client'
export default Prisma.defineExtension({
model: {
$allModels: {
// new method
findOrCreate(...) { } // code for the new method goes inside the brackets
}
}
})

You can then share the extension on npm. When you choose a package name, we recommend that you use the prisma-extension-<package-name> convention, to make it easier to find and install.

Call a client-level method from your packaged extension

In the following situations, you need to refer to a Prisma Client instance that your extension wraps:

  • When you want to use a client-level method, such as $queryRaw, in your packaged extension.
  • When you want to chain multiple $extends calls in your packaged extension.

However, when someone includes your packaged extension in their project, your code cannot know the details of the Prisma Client instance.

You can refer to this client instance as follows:

Prisma.defineExtension((client) => {
// The Prisma Client instance that the extension user applies the extension to
return client.$extends({})
})

For example:

export default Prisma.defineExtension((client) => {
return client.$extends({
query: {
$allModels: {
async findOrCreate({ args, query, operation }) {
return (await client.$transaction([query(args)]))[0]
},
},
},
})
})

Improve the type safety and developer experience of your shared extensions

You can improve the type-safety and developer experience of your shared extensions with the type utilities on model components.

Install a packaged extension

In your project, you can install any Prisma Client extension that another user has published to npm. To do so, run the following command:

$npm install prisma-extension-<package-name>

For example, if the package name for an available extension is prisma-extension-find-or-create, you could install it as follows:

$npm install prisma-extension-find-or-create

To import the find-or-create extension from the example above, and wrap your client instance with it, you could use the following code. This example assumes that the extension name is findOrCreate.

import findOrCreate from 'prisma-extension-find-or-create'
const xprisma = prisma.$extends(findOrCreate)
const user = await xprisma.user.findOrCreate({ ... })
xprisma.user.findOrCreate()

When you call a method in an extension, use the constant name from your $extends statement, not prisma. In the above example,xprisma.user.findOrCreate works, but prisma.user.findOrCreate does not, because the original prisma is not modified.

Edit this page on GitHub