# Prisma Documentation - Full Content Feed
This file contains the complete Prisma documentation in machine-readable format.
Includes both v7 (current) and v6 documentation.
---
# Introduction to Prisma (/docs)
[**Prisma ORM**](/orm) is an open-source ORM that provides fast, type-safe access to Postgres, MySQL, SQLite, and other databases, and runs smoothly across Node.js, Bun, and Deno.
npm
pnpm
yarn
bun
```bash
npx prisma init --db
```
```bash
pnpm dlx prisma init --db
```
```bash
yarn dlx prisma init --db
```
```bash
bunx --bun prisma init --db
```
[**Prisma Postgres**](/postgres) is a fully managed PostgreSQL database that scales to zero, integrates with [Prisma ORM](/orm) and [Prisma Studio](/studio), and includes a [generous free tier](https://www.prisma.io/pricing).
npm
pnpm
yarn
bun
```bash
npx create-db
```
```bash
pnpm dlx create-db
```
```bash
yarn dlx create-db
```
```bash
bunx --bun create-db
```
}
>
**Need a database?** Get started with your favorite framework and Prisma Postgres.
}>
**Already have a database?** Use Prisma ORM for a type-safe developer experience and automated migrations.
# Caching queries (/docs/accelerate/caching)
Prisma Accelerate provides global caching for read queries using TTL, Stale-While-Revalidate (SWR), or a combination of both. It's included as part of Prisma Postgres, but can also be used with your own database by enabling Accelerate in the [Prisma Data Platform](https://console.prisma.io?utm_source=docs) and [configuring it with your database](/accelerate/getting-started).
# Compare Accelerate (/docs/accelerate/compare)
Prisma Accelerate supports products that serve a global audience, with a global caching system and connection pool that spans multiple regions, providing consistent access to data with low latency no matter where your user (or your database) is located in the world.
The managed connection pool is designed to support serverless infrastructure, capable of handling high volumes of connections and adapting to traffic spikes with ease.
Explore how Prisma Accelerate compares to other global cache and connection pool solutions on the market, and discover what sets it apart.
What makes Accelerate unique? [#what-makes-accelerate-unique]
Prisma Accelerate is chosen and loved by many for a number of key reasons which make Accelerate unique:
* [**Query-Level policies**](/accelerate/compare#accelerate-global-cache): Accelerate is the only solution that offers query-level cache policies, allowing you to control the cache strategy for each query specifically. It is common to have some values that need to be cached for a long time, others that need caching for a short time, and some that should not be cached at all. With Accelerate you can do this, and even set different cache strategies per query.
* [**Global by default**](/accelerate/compare#accelerate-global-cache): Accelerate is globally distributed by default. You never need to worry about where a user is located with respect to your database location.
* [**Fully managed**](/accelerate/compare#management): You don't need to manage a server or worry about uptime. Accelerate is fully managed for you.
* [**Auto-scaling**](/accelerate/compare#performance): Accelerate automatically adjusts resources to match workload demands, providing fast and consistent performance during traffic spikes.
Accelerate global cache [#accelerate-global-cache]
Prisma Accelerate offers a powerful global cache, so you can serve data to your users at the edge — the closest point to where the users are located — no matter where your database is hosted. This not only speeds up the experience for users, but also reduces read load on your database as well by avoiding roundtrips.
| | Accelerate | Hyperdrive | PlanetScale Boost |
| ----------------------------------- | ---------- | ---------- | ----------------- |
| **Fully Managed** | ✅ | ✅ | ✅ |
| **Globally distributed edge infra** | ✅ | ✅ | ✅ |
| **Control cache policy from code** | ✅ | ❌ | ❌ |
| **Query-level cache policies** | ✅ | ❌ | ❌ |
| **Postgres compatible** | ✅ | ✅ | ❌ |
| **MySQL compatible** | ✅ | ❌ | ✅ |
| **MongoDB compatible** | ✅ | ❌ | ❌ |
| **Automatic cache updates** | ❌ | ❌ | ✅ |
**Why are these important?**
* Since Accelerate extends the Prisma client, you can control caching policies directly from your codebase with just an extra line of code. Integration is seamless. Here is an example using the stale-while-revalidating caching strategy:
```jsx
await prisma.user.findMany({
cacheStrategy: {
swr: 60,
},
});
```
* Query level cache policies are critical for serious applications, so that you can control which queries are cached, and the characteristics of the policy. You may want certain data in your app to be cached for several days, other data to be cached for a just a few minutes, and other data to be not cached at all. This is only possible with Prisma Accelerate.
* Automatic cache updates means that the cache is automatically updated when a change in the database occurs. With Accelerate, you are in control of how the cache is invalidated, using [various caching strategies](/accelerate/caching).
Accelerate connection pool [#accelerate-connection-pool]
Prisma Accelerate includes a globally hosted connection pooler, which allows you to handle peak loads without any problem. Using a connection pool is important especially for serverless infrastructure, which by nature is not able to control connection volume to the database on its own. Prisma Accelerate offers a fully managed, globally colocated option, which auto scales to support any workload.
Management [#management]
| | Accelerate | pgbouncer | pgcat | Digital Ocean (pgbouncer) | Neon (pgbouncer) | Supavisor | Hyperdrive |
| ------------------------------ | ---------- | --------- | ----- | ------------------------- | ---------------- | --------- | ---------- |
| **Fully managed** | ✅ | ❌ | ❌ | 🟠 | ✅ | ❌ | ✅ |
| **Globally distributed** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
| **Integrated with ORM client** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **Authenticate with API key** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **Redundancy** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
**Why are these important?**
* If you decide to manage a connection pooler yourself (eg. using pgbouncer or pgcat) you will also be responsible for managing its uptime. If the server crashes, your application may be down until you recover it. Accelerate, as a fully managed solution will be recovered for you transparently, in the unlikely case of any infrastructure issue.
* The hosted pgbouncer option on Digital Ocean is semi-managed, you will need to set it up in your Digital Ocean account, and ensure it is running smoothly at all times.
* Authenticating with an API key can be a helpful security measure, allowing you to decouple database credentials from application secrets. Easily rotate API keys as often as you like, without needing any credential changes in your database
* Redundancy is helpful in the unlikely scenario that your connection pool service goes down. With Accelerate, it is automatically and seamlessly handed over to another server and recovered without any interruption.
Performance [#performance]
| | Accelerate | pgbouncer | pgcat | Digital Ocean (pgbouncer) | Neon (pgbouncer) | Supavisor | Hyperdrive |
| ------------------------------- | ---------- | --------- | ----- | ------------------------- | ---------------- | --------- | ---------- |
| **Auto scaling** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **Globally distributed** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
| **Optimized queries over HTTP** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
| **Isolated compute** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
**Why are these important?**
* Accelerate will automatically scale up and down to suit your application workload, meaning you'll never run out of compute resource. Additionally, this provides important redundancy to protect against any single compute instance failing — in the unlikely event of an instance going down, Accelerate will automatically spawn a new instance.
* Cross-region TCP handshakes between the application server and PgBouncer or the database are costly and time-consuming. If connections are reused only at the PgBouncer layer, the TCP handshake and connection setup still consume unnecessary time on every single request, which undermines the efficiency of connection reuse. Prisma Accelerate improves this by leveraging HTTP, which is more efficient for connection management. It reduces the overhead associated with TCP handshakes, resulting in faster, more responsive interactions between your application and the database.
* Never worry about 'noisy neighbors' with isolated compute resources. Other customers never impact on your own performance.
Database Support [#database-support]
| | Accelerate | pgbouncer | pgcat | Digital Ocean (pgbouncer) | Neon (pgbouncer) | Supavisor | Hyperdrive |
| --------------- | ---------- | --------- | ----- | ------------------------- | ---------------- | --------- | ---------- |
| **PostgreSQL** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| **MySQL** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **PlanetScale** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **CockroachDB** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| **MongoDB** | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
# Connection Pooling (/docs/accelerate/connection-pooling)
Accelerate provides built-in connection pooling to efficiently manage database connections. It's included as part of [Prisma Postgres](/postgres), but you can also use it with your own database by enabling Accelerate in the [Prisma Data Platform](https://console.prisma.io?utm_source=docs) and [connecting it to your database](/accelerate/getting-started).
This page has moved, connection pooling in Prisma Accelerate is now documented in the [Prisma Postgres section](/postgres/database/connection-pooling).
# Evaluating (/docs/accelerate/evaluating)
Prisma Accelerate optimizes database interactions through advanced connection pooling and global edge caching. Its connection pooler is available in 16 regions and helps applications load-balance and scale database requests based on demand.
Considering the information above, we recommend evaluating Accelerate with high volume to see it perform under load.
How Accelerate's connection pool optimizes performance under load [#how-accelerates-connection-pool-optimizes-performance-under-load]
Prisma Accelerate employs a dynamic, serverless connection pooling infrastructure. When a request is made, a connection pool is quickly provisioned for the project in the region assigned while configuring Prisma Accelerate. This connection pool remains active, serving many additional requests while reusing established database connections. The connection pool will disconnect after a period of inactivity, so it’s important to evaluate Prisma Accelerate with a consistent stream of traffic.
**Key Benefits:**
* **Optimized Query Performance:** The serverless connection pooler adapts to the query load, ensuring the database connections are managed efficiently during peak demand.
> Prisma Accelerate’s connection pooler cannot improve the performance of queries in the database. In scenarios where query performance is an issue, we recommend optimizing the Prisma query, applying indexes, or utilizing Accelerate’s edge caching.
* **Maximize Connection Reuse:** Executing a consistent volume of queries helps maintain active instances of Accelerate connection poolers. This increases connection reuse, ensuring faster response times for subsequent queries.
By understanding and harnessing this mechanism, you can ensure that your database queries perform consistently and efficiently at scale.
Evaluating Prisma Accelerate connection pooling performance [#evaluating-prisma-accelerate-connection-pooling-performance]
Below you will find an example of how to evaluate Prisma Accelerate using a sample model:
```prisma
model Notes {
id Int @id @default(autoincrement())
title String
createdAt DateTime @default(now())
updatedAt DateTime? @updatedAt
}
```
```typescript
import { PrismaClient } from "@prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient().$extends(withAccelerate());
function calculateStatistics(numbers: number[]): {
average: number;
p50: number;
p75: number;
p99: number;
} {
if (numbers.length === 0) {
throw new Error("The input array is empty.");
}
// Sort the array in ascending order
numbers.sort((a, b) => a - b);
const sum = numbers.reduce((acc, num) => acc + num, 0);
const count = numbers.length;
const average = sum / count;
const p50 = getPercentile(numbers, 50);
const p75 = getPercentile(numbers, 75);
const p99 = getPercentile(numbers, 99);
return { average, p50, p75, p99 };
}
function getPercentile(numbers: number[], percentile: number): number {
if (percentile <= 0 || percentile >= 100) {
throw new Error("Percentile must be between 0 and 100.");
}
const index = (percentile / 100) * (numbers.length - 1);
if (Number.isInteger(index)) {
// If the index is an integer, return the corresponding value
return numbers[index];
} else {
// If the index is not an integer, interpolate between two adjacent values
const lowerIndex = Math.floor(index);
const upperIndex = Math.ceil(index);
const lowerValue = numbers[lowerIndex];
const upperValue = numbers[upperIndex];
const interpolationFactor = index - lowerIndex;
return lowerValue + (upperValue - lowerValue) * interpolationFactor;
}
}
async function main() {
const timings = [];
// fire a query before going to the loop
await prisma.notes.findMany({
take: 20,
});
// we recommend evaluating Prisma Accelerate with a large loop
const LOOP_LENGTH = 10000;
for (let i = 0; i < LOOP_LENGTH; i++) {
const start = Date.now();
await prisma.notes.findMany({
take: 20,
});
timings.push(Date.now() - start);
}
const statistics = calculateStatistics(timings);
console.log("Average:", statistics.average);
console.log("P50:", statistics.p50);
console.log("P75:", statistics.p75);
console.log("P99:", statistics.p99);
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch((e) => {
await prisma.$disconnect();
process.exit(1);
});
```
Evaluating Prisma Accelerate caching performance [#evaluating-prisma-accelerate-caching-performance]
Prisma Accelerate’s edge cache is also optimized for a high volume of queries. The cache automatically optimizes for repeated queries. As a result, the cache hit rate will increase as the query frequency does. Adding a query result to the cache is also non-blocking, so a short burst of queries might not utilize the cache or a sustained load.
To evaluate Accelerate’s edge caching, you can modify the above script with the below:
```typescript
import { PrismaClient } from "@prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient().$extends(withAccelerate());
function calculateStatistics(numbers: number[]): {
average: number;
p50: number;
p75: number;
p99: number;
} {
if (numbers.length === 0) {
throw new Error("The input array is empty.");
}
// Sort the array in ascending order
numbers.sort((a, b) => a - b);
const sum = numbers.reduce((acc, num) => acc + num, 0);
const count = numbers.length;
const average = sum / count;
const p50 = getPercentile(numbers, 50);
const p75 = getPercentile(numbers, 75);
const p99 = getPercentile(numbers, 99);
return { average, p50, p75, p99 };
}
function getPercentile(numbers: number[], percentile: number): number {
if (percentile <= 0 || percentile >= 100) {
throw new Error("Percentile must be between 0 and 100.");
}
const index = (percentile / 100) * (numbers.length - 1);
if (Number.isInteger(index)) {
// If the index is an integer, return the corresponding value
return numbers[index];
} else {
// If the index is not an integer, interpolate between two adjacent values
const lowerIndex = Math.floor(index);
const upperIndex = Math.ceil(index);
const lowerValue = numbers[lowerIndex];
const upperValue = numbers[upperIndex];
const interpolationFactor = index - lowerIndex;
return lowerValue + (upperValue - lowerValue) * interpolationFactor;
}
}
async function main() {
const timings = [];
// fire a query before going to the loop
await prisma.notes.findMany({
take: 20,
cacheStrategy: {
ttl: 30,
},
});
// we recommend evaluating Prisma Accelerate with a large loop
const LOOP_LENGTH = 10000;
for (let i = 0; i < LOOP_LENGTH; i++) {
const start = Date.now();
await prisma.notes.findMany({
take: 20,
cacheStrategy: {
ttl: 30,
},
});
timings.push(Date.now() - start);
}
const statistics = calculateStatistics(timings);
console.log("Average:", statistics.average);
console.log("P50:", statistics.p50);
console.log("P75:", statistics.p75);
console.log("P99:", statistics.p99);
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch((e) => {
await prisma.$disconnect();
process.exit(1);
});
```
# Examples (/docs/accelerate/examples)
Here is a list of ready-to-run example projects that demonstrate how to use Prisma Accelerate:
| Demo | Description |
| ------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| [`nextjs-starter`](https://github.com/prisma/prisma-examples/tree/latest/accelerate/nextjs-starter) | A Next.js project using Prisma Accelerate's caching and connection pooling |
| [`svelte-starter`](https://github.com/prisma/prisma-examples/tree/latest/accelerate/svelte-starter) | A SvelteKit project using Prisma Accelerate's caching and connection pooling |
| [`solidstart-starter`](https://github.com/prisma/prisma-examples/tree/latest/accelerate/solidstart-starter) | A Solidstart project using Prisma Accelerate's caching and connection pooling |
| [`remix-starter`](https://github.com/prisma/prisma-examples/tree/latest/accelerate/remix-starter) | A Remix project using Prisma Accelerate's caching and connection pooling |
| [`nuxt-starter`](https://github.com/prisma/prisma-examples/tree/latest/accelerate/nuxtjs-starter) | A Nuxt.js project using Prisma Accelerate's caching and connection pooling |
| [`astro-starter`](https://github.com/prisma/prisma-examples/tree/latest/accelerate/astro-starter) | An Astro project using Prisma Accelerate's caching and connection pooling |
| [`accelerate-hacker-news`](https://github.com/prisma/prisma-examples/tree/latest/accelerate/accelerate-hacker-news) | A simple Hacker News clone built with Prisma Accelerate, demonstrating the use of on-demand cache invalidation |
| [`prisma-accelerate-invalidation`](https://github.com/prisma/prisma-accelerate-invalidation) | An app demonstrating how long it takes to invalidate a cached query result using on-demand cache invalidation. |
# Getting started (/docs/accelerate/getting-started)
Prerequisites [#prerequisites]
To get started with Accelerate, you will need the following:
* A [Prisma Data Platform account](https://console.prisma.io)
* A project that uses [Prisma Client](/orm/prisma-client/setup-and-configuration/introduction) `4.16.1` or higher. If your project is using interactive transactions, you need to use `5.1.1` or higher. (We always recommend using the latest version of Prisma.)
* A hosted PostgreSQL, MySQL/MariaDB, PlanetScale, CockroachDB, or MongoDB database
1. Enable Accelerate [#1-enable-accelerate]
Navigate to your Prisma Data Platform project, choose an environment, and enable Accelerate by providing your database connection string and selecting the region nearest your database.
If you require IP allowlisting or firewall configurations with trusted IP addresses, enable Static IP for enhanced security. Learn more on [how to enable static IP for Accelerate in the Platform Console](/accelerate/static-ip).
2. Add Accelerate to your application [#2-add-accelerate-to-your-application]
2.1. Update your database connection string [#21-update-your-database-connection-string]
Once enabled, you'll be prompted to generate a connection string that you'll use to authenticate requests.
Replace your direct database URL with your new Accelerate connection string.
```bash title=".env"
# New Accelerate connection string with generated API_KEY
DATABASE_URL="prisma://accelerate.prisma-data.net/?api_key=__API_KEY__"
# Previous (direct) database connection string
# DATABASE_URL="postgresql://user:password@host:port/db_name?schema=public"
```
Prisma Client reads the `prisma://` URL from `DATABASE_URL` at runtime, while Prisma CLI commands use the connection string defined in `prisma.config.ts`.
Prisma Migrate and Introspection do not work with a `prisma://` connection string. In order to continue using these features add a new variable to the `.env` file named `DIRECT_DATABASE_URL` whose value is the direct database connection string:
```bash title=".env"
DATABASE_URL="prisma://accelerate.prisma-data.net/?api_key=__API_KEY__"
DIRECT_DATABASE_URL="postgresql://user:password@host:port/db_name?schema=public" # [!code ++]
```
Then point `prisma.config.ts` to the direct connection string:
```ts title="prisma.config.ts" showLineNumbers
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: env("DIRECT_DATABASE_URL"),
},
});
```
Migrations and introspections will use the `directUrl` connection string rather than the one defined in `url` when this configuration is provided.
> `directUrl` is useful for you to carry out migrations and introspections. However, you don't need `directUrl` to use Accelerate in your application.
If you are using Prisma with PostgreSQL, there is no need for `directUrl`, as Prisma Migrate and Introspection work with the `prisma+postgres://` connection string.
2.2. Install the Accelerate Prisma Client extension [#22-install-the-accelerate-prisma-client-extension]
💡 Accelerate requires [Prisma Client](/orm/prisma-client/setup-and-configuration/introduction) version `4.16.1` or higher and [`@prisma/extension-accelerate`](https://www.npmjs.com/package/@prisma/extension-accelerate) version `1.0.0` or higher.
💡 Accelerate extension [`@prisma/extension-accelerate`](https://www.npmjs.com/package/@prisma/extension-accelerate) version `2.0.0` and above requires Node.js version `18` or higher.
Install the latest version of Prisma Client and Accelerate Prisma Client extension
npm
pnpm
yarn
bun
```bash
npm install @prisma/client@latest @prisma/extension-accelerate
```
```bash
pnpm add @prisma/client@latest @prisma/extension-accelerate
```
```bash
yarn add @prisma/client@latest @prisma/extension-accelerate
```
```bash
bun add @prisma/client@latest @prisma/extension-accelerate
```
2.3. Generate Prisma Client for Accelerate [#23-generate-prisma-client-for-accelerate]
If you're using Prisma version `5.2.0` or greater, Prisma Client will automatically determine how it should connect to the database depending on the protocol in the database connection string. If the connection string in the `DATABASE_URL` starts with `prisma://`, Prisma Client will try to connect to your database using Prisma Accelerate.
When using Prisma Accelerate in long-running application servers, such as a server deployed on AWS EC2, you can generate the Prisma Client by executing the following command:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
When using Prisma Accelerate in a Serverless or an Edge application, we recommend you to run the following command to generate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate --no-engine
```
```bash
pnpm dlx prisma generate --no-engine
```
```bash
yarn dlx prisma generate --no-engine
```
```bash
bunx --bun prisma generate --no-engine
```
The `--no-engine` flag prevents a Query Engine file from being included in the generated Prisma Client, this ensures the bundle size of your application remains small.
If your Prisma version is below `5.2.0`, generate Prisma Client with the `--accelerate` option:
npm
pnpm
yarn
bun
```bash
npx prisma generate --accelerate
```
```bash
pnpm dlx prisma generate --accelerate
```
```bash
yarn dlx prisma generate --accelerate
```
```bash
bunx --bun prisma generate --accelerate
```
If your Prisma version is below `5.0.0`, generate Prisma Client with the `--data-proxy` option:
npm
pnpm
yarn
bun
```bash
npx prisma generate --data-proxy
```
```bash
pnpm dlx prisma generate --data-proxy
```
```bash
yarn dlx prisma generate --data-proxy
```
```bash
bunx --bun prisma generate --data-proxy
```
2.4. Extend your Prisma Client instance with the Accelerate extension [#24-extend-your-prisma-client-instance-with-the-accelerate-extension]
Add the following to extend your existing Prisma Client instance with the Accelerate extension:
```ts
import { PrismaClient } from "@prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient({
accelerateUrl: process.env.DATABASE_URL,
}).$extends(withAccelerate());
```
If you are going to deploy to an edge runtime (like Cloudflare Workers, Vercel Edge Functions, Deno Deploy, or Supabase Edge Functions), use our edge client instead:
```ts
import { PrismaClient } from "@prisma/client/edge";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient({
accelerateUrl: process.env.DATABASE_URL,
}).$extends(withAccelerate());
```
If VS Code does not recognize the `$extends` method, refer to [this section](/accelerate/more/faq#vs-code-does-not-recognize-the-extends-method) on how to resolve the issue.
Using the Accelerate extension with other extensions [#using-the-accelerate-extension-with-other-extensions]
Since [extensions are applied one after another](/orm/prisma-client/client-extensions#conflicts-in-combined-extensions), make sure you apply them in the correct order. Extensions cannot share behavior and the last extension applied takes precedence.
If you are using [Query Insights](/query-insights) in your application, make sure you apply it *before* the Accelerate extension. For example:
```ts
const prisma = new PrismaClient({
accelerateUrl: process.env.DATABASE_URL,
})
.$extends(withOptimize())
.$extends(withAccelerate());
```
2.5. Use Accelerate in your database queries [#25-use-accelerate-in-your-database-queries]
The `withAccelerate` extension primarily does two things:
* Gives you access to the `cacheStrategy` field within each applicable model method that allows you to define a cache strategy per-query.
* Routes all of your queries through a connection pooler.
No cache strategy to only use connection pool [#no-cache-strategy-to-only-use-connection-pool]
If you simply want to take advantage of Accelerate's connection pooling feature without applying a cache strategy, you may run your query the same way you would have without Accelerate.
By enabling Accelerate and supplying the Accelerate connection string, your queries now use the connection pooler by default.
As of Prisma version `5.2.0` you can use Prisma Studio with the Accelerate connection string.
Invalidate the cache and keep your cached query results up-to-date [#invalidate-the-cache-and-keep-your-cached-query-results-up-to-date]
If your application requires real-time or near-real-time data, cache invalidation ensures that users see the most current data, even when using a large `ttl` (Time-To-Live) or `swr` (Stale-While-Revalidate) [cache strategy](/accelerate/caching). By invalidating your cache, you can bypass extended caching periods to show live data whenever it's needed.
For example, if a dashboard displays customer information and a customer’s contact details change, cache invalidation allows you to refresh only that data instantly, ensuring support staff always see the latest information without waiting for the cache to expire.
To invalidate a cached query result, you can add tags and then use the `$accelerate.invalidate` API.
On-demand cache invalidation is available with our paid plans. For more details, please see our [pricing](https://www.prisma.io/pricing#accelerate).
To invalidate the query below:
```ts
await prisma.user.findMany({
where: {
email: {
contains: "alice@prisma.io",
},
},
cacheStrategy: {
swr: 60,
ttl: 60,
tags: ["emails_with_alice"], // [!code highlight]
},
});
```
You need to provide the cache tag in the `$accelerate.invalidate` API:
```ts
try {
await prisma.$accelerate.invalidate({
// [!code highlight]
tags: ["emails_with_alice"], // [!code highlight]
}); // [!code highlight]
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
// The .code property can be accessed in a type-safe manner
if (e.code === "P6003") {
console.log("You've reached the cache invalidation rate limit. Please try again shortly.");
}
}
throw e;
}
```
# Prisma Accelerate (/docs/accelerate)
[Prisma Accelerate](https://www.prisma.io/accelerate) is a fully managed global connection pool and caching layer for your existing database, enabling query-level cache policies directly from the Prisma ORM.
With 15+ global regions, the connection pool scales your app for a global audience, particularly for serverless deployments that risk connection timeouts during peak times.
Accelerate's global cache, hosted in 300+ locations, ensures a fast experience for users, regardless of your database's location.
You can configure query-level caching strategies directly in your code with Prisma ORM, making setup and tuning easy.
Together, the connection pool and cache allow you to scale effortlessly and handle traffic spikes without infrastructure concerns.
Supported databases [#supported-databases]
Accelerate works with the database you already have, whether it is publicly accessible, or via an IP allowlist.
* PostgreSQL
* MySQL
* MariaDB
* PlanetScale
* CockroachDB
* MongoDB
Getting started [#getting-started]
* [Getting started](/accelerate/getting-started) - Learn how to get up and running with Prisma Accelerate
* [Local development](/accelerate/local-development) - Learn how to use Prisma Accelerate in a development environment
* [Examples](/accelerate/examples) - Check out ready-to-run examples for Prisma Accelerate
# Local development (/docs/accelerate/local-development)
Prisma Accelerate efficiently scales production traffic with integrated connection pooling and a global database cache.
In development environments, you may want to use a local database to minimize expenses. Furthermore, you may consider extending Prisma Client with the Accelerate client extension once so that you can use a local database in development and a hosted database with Accelerate’s connection pooling and caching enabled. This eliminates the need for conditional logic to switch clients between development and production.
This guide will explain how to use Prisma Accelerate client extension in a development environment with a local database.
Using Prisma Accelerate client extension in development and production [#using-prisma-accelerate-client-extension-in-development-and-production]
Accelerate does not work with a local database. However, in a development environment, you can still use Prisma Client with the Accelerate client extension. This setup will not provide Accelerate's connection pooling and caching features.
The following steps outline how to use Prisma ORM and Prisma Accelerate with a local PostgreSQL database.
1. Update the `DATABASE_URL` environment variable with your local database's connection string:
```bash
DATABASE_URL="postgres://username:password@127.0.0.1:5432/localdb"
```
2. Generate a Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
3. Set up Prisma Client with the Accelerate client extension:
```typescript
import { PrismaClient } from "@prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient().$extends(withAccelerate());
```
> The extended instance of Prisma Client will use the local database. Hence, Prisma Accelerate will not be used in your development environment to respond to your Prisma Client queries.
If an Accelerate connection string is used as the `DATABASE_URL` environment variable, Prisma Client will route your queries through Accelerate.
Using Prisma Accelerate locally in an edge function [#using-prisma-accelerate-locally-in-an-edge-function]
When using an edge function, e.g., [Vercel's edge runtime](https://vercel.com/docs/functions/runtimes/edge-runtime), for your development environment, update your Prisma Client import as follows:
```typescript
import { PrismaClient } from "@prisma/client/edge";
```
Generally, edge function environments lack native support for existing APIs enabling TCP-based database connections. Prisma Accelerate provides a connection string that allows querying your database over HTTP, a protocol supported in all edge runtimes.
# Static IP (/docs/accelerate/static-ip)
You can enable static IP for Accelerate when your security setup requires IP allowlisting or if you're implementing firewalls that only permit access from trusted IPs, ensuring controlled and secure database connections.
To enable static IP support for Accelerate within an existing or a new project environment, your workspace will need to be on our Pro or Business plans. Take a look at the [pricing page](https://www.prisma.io/pricing#accelerate) for more information.
Enable static IP in Accelerate [#enable-static-ip-in-accelerate]
You can opt-in to use static IP for Accelerate in the [Platform Console](https://pris.ly/pdp) in two ways:
1. When enabling Accelerate for your project environment: [#1-when-enabling-accelerate-for-your-project-environment]
1. Specify your database connection string and connection pool region.
2. Enable static IP by toggling the **Static IP** switch in the **Network restrictions** section.
3. Click on the **Enable Accelerate** button.
2. For projects already using Accelerate: [#2-for-projects-already-using-accelerate]
1. Navigate to the Accelerate **Settings** tab in the project environment.
2. Enable static IP by toggling the **Static IP** switch in the **Network restrictions** section.
Enabling static IP for Accelerate will provide you with a list of static IPv4 and IPv6 addresses.
Once you have these addresses, configure your database firewall to allow incoming connections only from these IPs and any other trusted IPs that need access to your database.
Since you cannot enable static IP for an existing Accelerate-enabled environment, we recommend opting for static IP when enabling Accelerate in a new environment. Use the same database URL as your existing Accelerate environment to instantly access static IP support for Accelerate.
# Build faster with Prisma + AI (/docs/ai)
In the era of AI, where code is increasingly written by agents, ensuring clarity, type safety, and reliable infrastructure is essential. With 5+ years of leadership in the TypeScript ecosystem, Prisma ORM and Prisma Postgres provide the proven foundation for AI-assisted development.
Get started [#get-started]
Run the following command to bootstrap your database with a prompt:
npm
pnpm
yarn
bun
```bash
npx prisma init --prompt "Create a habit tracker application"
```
```bash
pnpm dlx prisma init --prompt "Create a habit tracker application"
```
```bash
yarn dlx prisma init --prompt "Create a habit tracker application"
```
```bash
bunx --bun prisma init --prompt "Create a habit tracker application"
```
AI Coding Tools [#ai-coding-tools]
Prisma ORM and Prisma Postgres integrate seamlessly with your AI coding tools. Check out our documentation with tips and tricks for working with Prisma in various AI editors.
* [Cursor](/ai/tools/cursor) - Define project-specific rules and use your schema as context to generate accurate queries and code.
* [Windsurf](/ai/tools/windsurf) - Automate your database workflows by generating schemas, queries, and seed data in this AI-powered editor.
* [Github Copilot](/ai/tools/github-copilot) - Get Prisma-aware code suggestions, run CLI commands from chat, and query the Prisma docs.
* [ChatGPT](/ai/tools/chatgpt) - Learn how to connect the Prisma MCP server to ChatGPT to manage your databases with natural language.
Agent Skills [#agent-skills]
AI agents often generate outdated Prisma v6 code. Install Prisma Skills to give your agent accurate, up-to-date v7 knowledge - CLI commands, Client API, upgrade guides, database setup, and Prisma Postgres workflows.
npm
pnpm
yarn
bun
```bash
npx skills add prisma/skills
```
```bash
pnpm dlx skills add prisma/skills
```
```bash
yarn dlx skills add prisma/skills
```
```bash
bunx --bun skills add prisma/skills
```
* [Available skills and setup](/ai/tools/skills) - See all available skills and learn how to install them.
MCP server [#mcp-server]
With Prisma's MCP server, your AI tool can take database actions on your behalf: Provisioning a new Prisma Postgres instance, creating database backups and executing SQL queries are just a few of its capabilities.
```json title="Integrate in AI tool"
{
"mcpServers": {
"Prisma-Remote": {
"url": "https://mcp.prisma.io/mcp"
}
}
}
```
* [Capabilities and tools](/ai/tools/mcp-server#tools) - Discover all the tools that make up the capabilities of the Prisma MCP server.
* [Integrating in AI tools](/ai/tools/mcp-server#integrating-in-ai-tools) - Learn how to integrate Prisma's MCP server in your favorite AI tool, such as Cursor, Claude, Warp, and more.
* [How we built it](https://www.prisma.io/blog/about-mcp-servers-and-how-we-built-one-for-prisma) - Read this technical deep dive about the MCP protocol and how we built the Prisma MCP server.
Vibe Coding Tutorials [#vibe-coding-tutorials]
Build complete, production-ready applications from scratch with AI assistance.
* [Build a Linktree Clone SaaS](/ai/tutorials/linktree-clone) - A complete vibe coding tutorial: build a full Linktree clone SaaS with Next.js, Prisma Postgres, and Clerk auth using AI assistance.
Resources [#resources]
* [Vibe Coding with Limits](https://www.prisma.io/blog/vibe-coding-with-limits-how-to-build-apps-in-the-age-of-ai) - How to Build Apps in the Age of AI
* [Vibe Coding an E-commerce App](https://www.prisma.io/blog/vibe-coding-with-prisma-mcp-and-nextjs) - with Prisma MCP and Next.js
* [Integrating the Vercel AI SDK](/guides/integrations/ai-sdk) - in a Next.js application
Integrations [#integrations]
* [Automate with Pipedream](https://pipedream.com/apps/prisma-management-api) - Connect Prisma Postgres to 2,800+ apps for powerful automation
* [Firebase Studio](/guides/postgres/idx) - Prompt your application with Firebase Studio & Prisma Postgres
# debug (/docs/cli/debug)
The `prisma debug` command prints information helpful for debugging and bug reports.
Available from version 5.6.0 and newer.
Usage [#usage]
```bash
prisma debug [options]
```
Options [#options]
| Option | Description |
| -------------- | -------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
Examples [#examples]
Display debug information [#display-debug-information]
npm
pnpm
yarn
bun
```bash
npx prisma debug
```
```bash
pnpm dlx prisma debug
```
```bash
yarn dlx prisma debug
```
```bash
bunx --bun prisma debug
```
Output:
```text
-- Prisma schema --
Path: /prisma/schema.prisma
-- Local cache directory for engines files --
Path: /.cache/prisma
-- Environment variables --
When not set, the line is dimmed and no value is displayed.
When set, the line is bold and the value is inside the `` backticks.
For general debugging
- CI:
- DEBUG:
- NODE_ENV:
- RUST_LOG:
- RUST_BACKTRACE:
- NO_COLOR:
- TERM: `xterm-256color`
- NODE_TLS_REJECT_UNAUTHORIZED:
- NO_PROXY:
- http_proxy:
- HTTP_PROXY:
- https_proxy:
- HTTPS_PROXY:
For hiding messages
- PRISMA_DISABLE_WARNINGS:
- PRISMA_HIDE_PREVIEW_FLAG_WARNINGS:
- PRISMA_HIDE_UPDATE_MESSAGE:
For downloading engines
- PRISMA_ENGINES_MIRROR:
- PRISMA_BINARIES_MIRROR (deprecated):
- PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING:
- BINARY_DOWNLOAD_VERSION:
For custom engines
- PRISMA_SCHEMA_ENGINE_BINARY:
- PRISMA_MIGRATION_ENGINE_BINARY:
For Prisma Client
- PRISMA_SHOW_ALL_TRACES:
For Prisma Migrate
- PRISMA_SCHEMA_DISABLE_ADVISORY_LOCK:
For Prisma Studio
- BROWSER:
-- Terminal is interactive? --
true
-- CI detected? --
false
```
Use with older versions [#use-with-older-versions]
If using an older Prisma version:
npm
pnpm
yarn
bun
```bash
npx prisma@latest debug
```
```bash
pnpm dlx prisma@latest debug
```
```bash
yarn dlx prisma@latest debug
```
```bash
bunx --bun prisma@latest debug
```
# format (/docs/cli/format)
The `prisma format` command formats your Prisma schema file. It validates, formats, and persists the schema.
Usage [#usage]
```bash
prisma format [options]
```
Options [#options]
| Option | Description |
| -------------- | -------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
Examples [#examples]
Format the default schema [#format-the-default-schema]
npm
pnpm
yarn
bun
```bash
npx prisma format
```
```bash
pnpm dlx prisma format
```
```bash
yarn dlx prisma format
```
```bash
bunx --bun prisma format
```
Output on success:
```text
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Formatted prisma/schema.prisma in 116ms
```
Format a specific schema [#format-a-specific-schema]
npm
pnpm
yarn
bun
```bash
npx prisma format --schema=./alternative/schema.prisma
```
```bash
pnpm dlx prisma format --schema=./alternative/schema.prisma
```
```bash
yarn dlx prisma format --schema=./alternative/schema.prisma
```
```bash
bunx --bun prisma format --schema=./alternative/schema.prisma
```
Error output [#error-output]
If the schema has validation errors, formatting will fail:
```text
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Error: Schema validation error - Error (query-engine-node-api library)
Error code: P1012
error: The preview feature "unknownFeatureFlag" is not known. Expected one of: [...]
schema.prisma:3
|
2 | provider = "prisma-client"
3 | previewFeatures = ["unknownFeatureFlag"]
|
Validation Error Count: 1
```
# generate (/docs/cli/generate)
The `prisma generate` command generates assets like Prisma Client based on the [`generator`](/orm/prisma-schema/overview/generators) and [`data model`](/orm/prisma-schema/data-model/models) blocks defined in your `schema.prisma` file.
Usage [#usage]
```bash
prisma generate [options]
```
How it works [#how-it-works]
1. Inspects the current directory to find a Prisma schema
2. Generates a customized Prisma Client based on your schema into the output directory specified in the generator block
Prerequisites [#prerequisites]
Add a generator definition in your `schema.prisma` file:
```prisma
generator client {
provider = "prisma-client"
output = "./generated"
}
```
Options [#options]
| Option | Description |
| ------------------ | ------------------------------------------------------ |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
| `--sql` | Generate typed SQL module |
| `--watch` | Watch the Prisma schema and regenerate after changes |
| `--generator` | Generator to use (can be provided multiple times) |
| `--no-hints` | Hide hint messages (still outputs errors and warnings) |
| `--require-models` | Do not allow generating a client without models |
Examples [#examples]
Generate Prisma Client [#generate-prisma-client]
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
Output:
```text
✔ Generated Prisma Client to ./node_modules/.prisma/client in 61ms
You can now start using Prisma Client in your code:
import { PrismaClient } from '../prisma/generated/client'
const prisma = new PrismaClient()
```
Generate with a custom schema path [#generate-with-a-custom-schema-path]
npm
pnpm
yarn
bun
```bash
npx prisma generate --schema=./alternative/schema.prisma
```
```bash
pnpm dlx prisma generate --schema=./alternative/schema.prisma
```
```bash
yarn dlx prisma generate --schema=./alternative/schema.prisma
```
```bash
bunx --bun prisma generate --schema=./alternative/schema.prisma
```
Watch mode [#watch-mode]
Automatically regenerate when the schema changes:
npm
pnpm
yarn
bun
```bash
npx prisma generate --watch
```
```bash
pnpm dlx prisma generate --watch
```
```bash
yarn dlx prisma generate --watch
```
```bash
bunx --bun prisma generate --watch
```
Output:
```text
Watching... /home/prismauser/prisma/schema.prisma
✔ Generated Prisma Client to ./node_modules/.prisma/client in 45ms
```
Generate specific generators [#generate-specific-generators]
Run only specific generators:
npm
pnpm
yarn
bun
```bash
npx prisma generate --generator client
```
```bash
pnpm dlx prisma generate --generator client
```
```bash
yarn dlx prisma generate --generator client
```
```bash
bunx --bun prisma generate --generator client
```
Multiple generators:
npm
pnpm
yarn
bun
```bash
npx prisma generate --generator client --generator zod_schemas
```
```bash
pnpm dlx prisma generate --generator client --generator zod_schemas
```
```bash
yarn dlx prisma generate --generator client --generator zod_schemas
```
```bash
bunx --bun prisma generate --generator client --generator zod_schemas
```
Generated assets [#generated-assets]
The `prisma-client` generator creates a customized client for working with your database. You can [customize the output folder](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider) using the `output` field in the generator block.
# CLI Overview (/docs/cli)
The Prisma CLI provides commands for:
* **Project setup**: Initialize new Prisma projects
* **Code generation**: Generate Prisma Client and other artifacts
* **Database management**: Pull schemas, push changes, seed data
* **Migrations**: Create, apply, and manage database migrations
* **Development tools**: Local database servers, schema validation, formatting
Installation [#installation]
The Prisma CLI is available as an npm package. Install it as a development dependency:
npm
pnpm
yarn
bun
```bash
npm install prisma --save-dev
```
```bash
pnpm add prisma --save-dev
```
```bash
yarn add prisma --dev
```
```bash
bun add prisma --dev
```
Usage [#usage]
```bash
prisma [command]
```
Commands [#commands]
| Command | Description |
| --------------------------- | ---------------------------------------------------- |
| [`init`](/cli/init) | Set up Prisma for your app |
| [`dev`](/cli/dev) | Start a local Prisma Postgres server for development |
| [`generate`](/cli/generate) | Generate artifacts (e.g. Prisma Client) |
| [`db`](/cli/db) | Manage your database schema and lifecycle |
| [`migrate`](/cli/migrate) | Migrate your database |
| [`studio`](/cli/studio) | Browse your data with Prisma Studio |
| [`validate`](/cli/validate) | Validate your Prisma schema |
| [`format`](/cli/format) | Format your Prisma schema |
| [`version`](/cli/version) | Display Prisma version info |
| [`debug`](/cli/debug) | Display Prisma debug info |
| [`mcp`](/cli/mcp) | Start an MCP server to use with AI development tools |
Global flags [#global-flags]
These flags are available for all commands:
| Flag | Description |
| ------------------- | ----------------------------------- |
| `--help`, `-h` | Show help information for a command |
| `--preview-feature` | Run Preview Prisma commands |
Using a HTTP proxy [#using-a-http-proxy]
Prisma CLI supports custom HTTP proxies. This is useful when behind a corporate firewall.
Set one of these environment variables:
* `HTTP_PROXY` or `http_proxy`: Proxy URL for HTTP traffic (e.g., `http://localhost:8080`)
* `HTTPS_PROXY` or `https_proxy`: Proxy URL for HTTPS traffic (e.g., `https://localhost:8080`)
# init (/docs/cli/init)
The `prisma init` command bootstraps a fresh Prisma project within the current directory.
Usage [#usage]
```bash
prisma init [options]
```
The command creates a `prisma` directory containing a `schema.prisma` file. By default, the project is configured for [local Prisma Postgres](/postgres/database/local-development), but you can choose a different database using the `--datasource-provider` option.
Options [#options]
| Option | Description |
| ----------------------- | --------------------------------------------------------------------------------------------------------- |
| `-h`, `--help` | Display help message |
| `--db` | Provision a fully managed Prisma Postgres database on the Prisma Data Platform |
| `--datasource-provider` | Define the datasource provider: `postgresql`, `mysql`, `sqlite`, `sqlserver`, `mongodb`, or `cockroachdb` |
| `--generator-provider` | Define the generator provider to use (default: `prisma-client-js`) |
| `--preview-feature` | Define a preview feature to use (can be specified multiple times) |
| `--output` | Define Prisma Client generator output path |
| `--url` | Define a custom datasource URL |
Flags [#flags]
| Flag | Description |
| -------------- | ----------------------------------------------- |
| `--with-model` | Add an example model to the created schema file |
Examples [#examples]
Set up a new Prisma project (default) [#set-up-a-new-prisma-project-default]
Sets up a new project configured for local Prisma Postgres:
npm
pnpm
yarn
bun
```bash
npx prisma init
```
```bash
pnpm dlx prisma init
```
```bash
yarn dlx prisma init
```
```bash
bunx --bun prisma init
```
Specify a datasource provider [#specify-a-datasource-provider]
Set up a new project with MySQL as the datasource provider:
npm
pnpm
yarn
bun
```bash
npx prisma init --datasource-provider mysql
```
```bash
pnpm dlx prisma init --datasource-provider mysql
```
```bash
yarn dlx prisma init --datasource-provider mysql
```
```bash
bunx --bun prisma init --datasource-provider mysql
```
Specify a generator provider [#specify-a-generator-provider]
Set up a project with a specific generator provider:
npm
pnpm
yarn
bun
```bash
npx prisma init --generator-provider prisma-client-js
```
```bash
pnpm dlx prisma init --generator-provider prisma-client-js
```
```bash
yarn dlx prisma init --generator-provider prisma-client-js
```
```bash
bunx --bun prisma init --generator-provider prisma-client-js
```
Specify preview features [#specify-preview-features]
Set up a project with specific preview features enabled:
npm
pnpm
yarn
bun
```bash
npx prisma init --preview-feature metrics
```
```bash
pnpm dlx prisma init --preview-feature metrics
```
```bash
yarn dlx prisma init --preview-feature metrics
```
```bash
bunx --bun prisma init --preview-feature metrics
```
Multiple preview features:
npm
pnpm
yarn
bun
```bash
npx prisma init --preview-feature views --preview-feature metrics
```
```bash
pnpm dlx prisma init --preview-feature views --preview-feature metrics
```
```bash
yarn dlx prisma init --preview-feature views --preview-feature metrics
```
```bash
bunx --bun prisma init --preview-feature views --preview-feature metrics
```
Specify a custom output path [#specify-a-custom-output-path]
Set up a project with a custom output path for Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma init --output ./generated-client
```
```bash
pnpm dlx prisma init --output ./generated-client
```
```bash
yarn dlx prisma init --output ./generated-client
```
```bash
bunx --bun prisma init --output ./generated-client
```
Specify a custom datasource URL [#specify-a-custom-datasource-url]
Set up a project with a specific database URL:
npm
pnpm
yarn
bun
```bash
npx prisma init --url mysql://user:password@localhost:3306/mydb
```
```bash
pnpm dlx prisma init --url mysql://user:password@localhost:3306/mydb
```
```bash
yarn dlx prisma init --url mysql://user:password@localhost:3306/mydb
```
```bash
bunx --bun prisma init --url mysql://user:password@localhost:3306/mydb
```
Add an example model [#add-an-example-model]
Set up a project with an example `User` model:
npm
pnpm
yarn
bun
```bash
npx prisma init --with-model
```
```bash
pnpm dlx prisma init --with-model
```
```bash
yarn dlx prisma init --with-model
```
```bash
bunx --bun prisma init --with-model
```
Provision a Prisma Postgres database [#provision-a-prisma-postgres-database]
Create a new project with a managed Prisma Postgres database:
npm
pnpm
yarn
bun
```bash
npx prisma init --db
```
```bash
pnpm dlx prisma init --db
```
```bash
yarn dlx prisma init --db
```
```bash
bunx --bun prisma init --db
```
This requires authentication with the [Prisma Data Platform Console](https://console.prisma.io).
Generated files [#generated-files]
After running `prisma init`, you'll have the following files:
prisma/schema.prisma [#prismaschemaprisma]
The Prisma schema file where you define your data model:
```prisma
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
}
```
prisma.config.ts [#prismaconfigts]
A TypeScript configuration file for Prisma:
```typescript
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
.env [#env]
Environment variables file for your project:
```bash
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
```
.gitignore [#gitignore]
Git ignore file configured for Prisma projects:
```bash
node_modules
.env
/generated/prisma
```
# mcp (/docs/cli/mcp)
The `prisma mcp` command starts a Model Context Protocol (MCP) server that enables AI development tools to interact with your Prisma project.
Usage [#usage]
```bash
prisma mcp
```
Overview [#overview]
MCP (Model Context Protocol) is a standard for AI tools to interact with development environments. The Prisma MCP server exposes your Prisma schema and database context to AI assistants, enabling them to:
* Understand your data model
* Generate queries and migrations
* Provide context-aware suggestions
See also [#see-also]
* [Prisma MCP Server](/ai/tools/mcp-server)
# studio (/docs/cli/studio)
The `prisma studio` command starts a local web server with a web app to interactively browse and manage your data.
Usage [#usage]
```bash
prisma studio [options]
```
Supported databases
Prisma Studio currently supports PostgreSQL, MySQL, and SQLite. Support for CockroachDB and MongoDB is not available yet but may be added in future releases.
Prerequisites [#prerequisites]
Configure your database connection in `prisma.config.ts`:
```prisma file=schema.prisma
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "sqlite"
}
```
```typescript file=prisma.config.ts
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Options [#options]
| Option | Description | Default |
| ----------------- | ---------------------------------------------------- | -------------- |
| `-h`, `--help` | Display help message | |
| `-p`, `--port` | Port number to start Studio on | `5555` |
| `-b`, `--browser` | Browser to auto-open Studio in | System default |
| `--config` | Custom path to your Prisma config file | |
| `--url` | Database connection string (overrides Prisma config) | |
Examples [#examples]
Start Studio on the default port [#start-studio-on-the-default-port]
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
Start Studio on a custom port [#start-studio-on-a-custom-port]
npm
pnpm
yarn
bun
```bash
npx prisma studio --port 7777
```
```bash
pnpm dlx prisma studio --port 7777
```
```bash
yarn dlx prisma studio --port 7777
```
```bash
bunx --bun prisma studio --port 7777
```
Start Studio in a specific browser [#start-studio-in-a-specific-browser]
npm
pnpm
yarn
bun
```bash
npx prisma studio --browser firefox
```
```bash
pnpm dlx prisma studio --browser firefox
```
```bash
yarn dlx prisma studio --browser firefox
```
```bash
bunx --bun prisma studio --browser firefox
```
Or using the `BROWSER` environment variable:
```bash
BROWSER=firefox prisma studio
```
Start Studio without opening a browser [#start-studio-without-opening-a-browser]
npm
pnpm
yarn
bun
```bash
npx prisma studio --browser none
```
```bash
pnpm dlx prisma studio --browser none
```
```bash
yarn dlx prisma studio --browser none
```
```bash
bunx --bun prisma studio --browser none
```
Start Studio with a custom config file [#start-studio-with-a-custom-config-file]
npm
pnpm
yarn
bun
```bash
npx prisma studio --config=./prisma.config.ts
```
```bash
pnpm dlx prisma studio --config=./prisma.config.ts
```
```bash
yarn dlx prisma studio --config=./prisma.config.ts
```
```bash
bunx --bun prisma studio --config=./prisma.config.ts
```
Start Studio with a direct database connection string [#start-studio-with-a-direct-database-connection-string]
npm
pnpm
yarn
bun
```bash
npx prisma studio --url="postgresql://user:password@localhost:5432/dbname"
```
```bash
pnpm dlx prisma studio --url="postgresql://user:password@localhost:5432/dbname"
```
```bash
yarn dlx prisma studio --url="postgresql://user:password@localhost:5432/dbname"
```
```bash
bunx --bun prisma studio --url="postgresql://user:password@localhost:5432/dbname"
```
# validate (/docs/cli/validate)
The `prisma validate` command validates the [Prisma Schema Language](/orm/prisma-schema/overview) of your Prisma schema file.
Usage [#usage]
```bash
prisma validate [options]
```
Options [#options]
| Option | Description |
| -------------- | -------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
Examples [#examples]
Validate the default schema [#validate-the-default-schema]
npm
pnpm
yarn
bun
```bash
npx prisma validate
```
```bash
pnpm dlx prisma validate
```
```bash
yarn dlx prisma validate
```
```bash
bunx --bun prisma validate
```
Output on success:
```text
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
The schema at /absolute/path/prisma/schema.prisma is valid
```
Validate a specific schema [#validate-a-specific-schema]
npm
pnpm
yarn
bun
```bash
npx prisma validate --schema=./alternative/schema.prisma
```
```bash
pnpm dlx prisma validate --schema=./alternative/schema.prisma
```
```bash
yarn dlx prisma validate --schema=./alternative/schema.prisma
```
```bash
bunx --bun prisma validate --schema=./alternative/schema.prisma
```
Validate with a config file [#validate-with-a-config-file]
npm
pnpm
yarn
bun
```bash
npx prisma validate --config=./prisma.config.ts
```
```bash
pnpm dlx prisma validate --config=./prisma.config.ts
```
```bash
yarn dlx prisma validate --config=./prisma.config.ts
```
```bash
bunx --bun prisma validate --config=./prisma.config.ts
```
Error output [#error-output]
If the schema has validation errors:
```text
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Error: Schema validation error - Error (query-engine-node-api library)
Error code: P1012
error: The preview feature "unknownFeatureFlag" is not known. Expected one of: [...]
schema.prisma:3
|
2 | provider = "prisma-client"
3 | previewFeatures = ["unknownFeatureFlag"]
|
Validation Error Count: 1
```
# version (/docs/cli/version)
The `prisma version` command outputs information about your current Prisma version, platform, and engine binaries.
Usage [#usage]
```bash
prisma version [options]
```
Or use the shorthand:
```bash
prisma -v [options]
```
Options [#options]
| Option | Description |
| -------------- | ----------------------------------------- |
| `-h`, `--help` | Display help message |
| `--json` | Output version information in JSON format |
Examples [#examples]
Display version information [#display-version-information]
npm
pnpm
yarn
bun
```bash
npx prisma version
```
```bash
pnpm dlx prisma version
```
```bash
yarn dlx prisma version
```
```bash
bunx --bun prisma version
```
Output:
```text
Environment variables loaded from .env
prisma : 2.21.0-dev.4
@prisma/client : 2.21.0-dev.4
Current platform : windows
Query Engine : query-engine 2fb8f444d9cdf7c0beee7b041194b42d7a9ce1e6
Migration Engine : migration-engine-cli 2fb8f444d9cdf7c0beee7b041194b42d7a9ce1e6
Format Binary : prisma-fmt 60ba6551f29b17d7d6ce479e5733c70d9c00860e
Default Engines Hash : 60ba6551f29b17d7d6ce479e5733c70d9c00860e
Studio : 0.365.0
```
Display version using shorthand [#display-version-using-shorthand]
npm
pnpm
yarn
bun
```bash
npx prisma -v
```
```bash
pnpm dlx prisma -v
```
```bash
yarn dlx prisma -v
```
```bash
bunx --bun prisma -v
```
Display version as JSON [#display-version-as-json]
npm
pnpm
yarn
bun
```bash
npx prisma version --json
```
```bash
pnpm dlx prisma version --json
```
```bash
yarn dlx prisma version --json
```
```bash
bunx --bun prisma version --json
```
Output:
```json
{
"prisma": "2.21.0-dev.4",
"@prisma/client": "2.21.0-dev.4",
"current-platform": "windows",
"query-engine": "query-engine 60ba6551f29b17d7d6ce479e5733c70d9c00860e",
"migration-engine": "migration-engine-cli 60ba6551f29b17d7d6ce479e5733c70d9c00860e",
"format-binary": "prisma-fmt 60ba6551f29b17d7d6ce479e5733c70d9c00860e",
"default-engines-hash": "60ba6551f29b17d7d6ce479e5733c70d9c00860e",
"studio": "0.365.0"
}
```
# Concepts (/docs/console/concepts)
The Console workflows are based on four main concepts:
* [**User account**](#user-account): In order to use Prisma products, you need to have a Console user account. A *user* will typically create one user account to manage all their workspaces, projects and resources. The *user* can also be invited to join other workspaces to collaborate on the projects in that workspace.
* [**Workspaces**](#workspace): A user account can belong to multiple workspaces. A workspace typically represents a *team* of individuals working together on one or more projects. **Billing is on a workspace level**, i.e. the invoice for a workspace at the end of the month captures all costs associated with the projects in that workspace.
* [**Projects**](#project): A project belongs to a workspace. It typically represents the *application* or *service* a team is working on.
* [**Resources**](#resources): Resources represent the actual services or databases within a project. For example, in Prisma Postgres, each project can contain multiple databases. For Accelerate, resources might correspond to different environments (like `Development`, `Staging`, or `Production`). **Connection strings are provisioned at the resource level**, and products are configured per resource as well (e.g., the database connection string used for Accelerate).
Here is a visual illustration of how these concepts relate to each other:
User account [#user-account]
A user account is the prerequisite for any interactions with Prisma products. You can use it to manage your workspaces (and their projects). A user account can be invited to collaborate on workspaces created by other users as well.
If you need to delete your user account, go [here](/console/more/support#deleting-your-pdp-account).
Workspace [#workspace]
You can create several workspaces. A workspace is an isolated space to host projects. A workspace can have multiple user accounts associated with it so that multiple users can collaborate on the projects in the workspace.
In each workspace, you can:
* view and manage all projects (and their resources) in that workspace.
* manage billing, i.e. select a [subscription plan](https://www.prisma.io/pricing?utm_source=docs\&utm_medium=platform-docs), configure payment methods, or view the invoice history.
* view the usage of your enabled Prisma products across all projects in that workspace.
* invite other users to collaborate in the workspace.
* access the [Optimize dashboard](https://console.prisma.io/optimize?utm_source=docs\&utm_medium=optimize-docs) to measure query performance and receive AI-powered recommendations.
CLI commands [#cli-commands]
List all workspaces:
npm
pnpm
yarn
bun
```bash
npx prisma platform workspace show --early-access
```
```bash
pnpm dlx prisma platform workspace show --early-access
```
```bash
yarn dlx prisma platform workspace show --early-access
```
```bash
bunx --bun prisma platform workspace show --early-access
```
Project [#project]
In each workspace, you can create several projects. A project typically represents an application (a product or service). You typically have one [Prisma schema](/orm/prisma-schema/overview) per project.
In each project, you can:
* view and manage all resources (like databases) in that project.
The number of projects you can create in a workspace depends on the [subscription plan](https://www.prisma.io/pricing?utm_source=docs\&utm_medium=platform-docs) configured in that workspace.
CLI commands [#cli-commands-1]
List all projects in a workspace:
npm
pnpm
yarn
bun
```bash
npx prisma platform project show --workspace $WORKSPACE_ID --early-access
```
```bash
pnpm dlx prisma platform project show --workspace $WORKSPACE_ID --early-access
```
```bash
yarn dlx prisma platform project show --workspace $WORKSPACE_ID --early-access
```
```bash
bunx --bun prisma platform project show --workspace $WORKSPACE_ID --early-access
```
Create a new project:
npm
pnpm
yarn
bun
```bash
npx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
pnpm dlx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
yarn dlx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
bunx --bun prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
Delete a project:
npm
pnpm
yarn
bun
```bash
npx prisma platform project delete --project $PROJECT_ID --early-access
```
```bash
pnpm dlx prisma platform project delete --project $PROJECT_ID --early-access
```
```bash
yarn dlx prisma platform project delete --project $PROJECT_ID --early-access
```
```bash
bunx --bun prisma platform project delete --project $PROJECT_ID --early-access
```
Resources [#resources]
Resources represent the actual services or databases within a project. The type of resources available depends on the Prisma products you're using:
* **For Prisma Postgres**: Each project can contain multiple databases. These databases are the primary resources you'll manage.
* **For Accelerate**: Resources typically correspond to different deployment stages (like `Development`, `Staging`, or `Production`).
In each project, you can:
* Create and manage multiple resources (databases or environments)
* Generate connection strings specific to each resource
* Configure product-specific settings:
* **For Prisma Postgres databases**:
* View database metrics and performance
* Configure connection settings
* Manage database users and permissions
* **For Accelerate resources**:
* Set your database connection string
* Configure the region for connection pooling
* Adjust connection pool size and performance settings
* Set query duration and response size limits
* Enable static IP for secure connections
The number of resources you can create in a project depends on your [subscription plan](https://www.prisma.io/pricing?utm_source=docs\&utm_medium=platform-docs).
CLI commands [#cli-commands-2]
List all environments (resources) in a project:
npm
pnpm
yarn
bun
```bash
npx prisma platform environment show --project $PROJECT_ID --early-access
```
```bash
pnpm dlx prisma platform environment show --project $PROJECT_ID --early-access
```
```bash
yarn dlx prisma platform environment show --project $PROJECT_ID --early-access
```
```bash
bunx --bun prisma platform environment show --project $PROJECT_ID --early-access
```
Create a new environment:
npm
pnpm
yarn
bun
```bash
npx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
pnpm dlx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
yarn dlx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
bunx --bun prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
Delete an environment:
npm
pnpm
yarn
bun
```bash
npx prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
```bash
pnpm dlx prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
```bash
yarn dlx prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
```bash
bunx --bun prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
# Getting Started (/docs/console/getting-started)
This guide walks you through setting up your Console account and creating your first project.
Prerequisites [#prerequisites]
* A GitHub account (for authentication)
* A Prisma project (optional, but recommended)
Step 1: Create your account [#step-1-create-your-account]
1. Go to [console.prisma.io/login](https://console.prisma.io/login)
2. Click **Sign in with GitHub**
3. Authorize Prisma Console to access your GitHub account
You now have a Console account with a default workspace.
Step 2: Set up a workspace [#step-2-set-up-a-workspace]
When you create an account, a default workspace is automatically created for you. You can create additional workspaces for different teams or organizations.
Create a workspace (optional) [#create-a-workspace-optional]
To create an additional workspace:
1. Click the workspace dropdown in the top navigation
2. Click **Create Workspace**
3. Enter a name for your workspace
4. Click **Create**
Using the CLI [#using-the-cli]
List all workspaces:
npm
pnpm
yarn
bun
```bash
npx prisma platform workspace show --early-access
```
```bash
pnpm dlx prisma platform workspace show --early-access
```
```bash
yarn dlx prisma platform workspace show --early-access
```
```bash
bunx --bun prisma platform workspace show --early-access
```
Step 3: Create a project [#step-3-create-a-project]
Projects organize your databases and environments within a workspace.
Using the Console web interface [#using-the-console-web-interface]
1. Navigate to your workspace
2. Click **Create Project**
3. Enter a project name
4. Click **Create**
Using the CLI [#using-the-cli-1]
npm
pnpm
yarn
bun
```bash
npx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
pnpm dlx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
yarn dlx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
bunx --bun prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
Step 4: Create a resource [#step-4-create-a-resource]
Resources are the actual databases or environments within your project.
For Prisma Postgres [#for-prisma-postgres]
1. Navigate to your project
2. Click **Create Database**
3. Enter a database name
4. Select a region
5. Click **Create**
For Accelerate [#for-accelerate]
1. Navigate to your project
2. Click **Create Environment**
3. Enter an environment name (e.g., "production")
4. Click **Create**
Using the CLI [#using-the-cli-2]
npm
pnpm
yarn
bun
```bash
npx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
pnpm dlx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
yarn dlx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
bunx --bun prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
Step 5: Generate a connection string [#step-5-generate-a-connection-string]
Connection strings authenticate your application's requests to Prisma products.
Using the Console web interface [#using-the-console-web-interface-1]
1. Navigate to your resource (database or environment)
2. Click **Connection Strings** tab
3. Click **Create Connection String**
4. Enter a name for the connection string
5. Copy the connection string and store it securely
6. Click **Done**
Using the CLI [#using-the-cli-3]
npm
pnpm
yarn
bun
```bash
npx prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
```bash
pnpm dlx prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
```bash
yarn dlx prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
```bash
bunx --bun prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
Step 6: Use the connection string in your application [#step-6-use-the-connection-string-in-your-application]
Add the connection string to your `.env` file:
```bash
# For Accelerate
DATABASE_URL="prisma://accelerate.prisma-data.net/?api_key=YOUR_API_KEY"
# For Optimize
OPTIMIZE_API_KEY="YOUR_API_KEY"
```
Next steps [#next-steps]
* Learn more about [Console concepts](/console/concepts)
* Explore [database metrics](/console/features/metrics)
* Check out the [CLI reference](/cli/console)
# Console (/docs/console)
Overview [#overview]
The [Console](https://console.prisma.io/login) enables you to manage and configure your projects that use Prisma products, and helps you integrate them into your application:
* [Query Insights](/query-insights): Inspect slow queries, connect Prisma calls to SQL, and apply focused fixes.
* [Prisma Postgres](/postgres): A managed PostgreSQL database that is optimized for Prisma ORM.
Getting started [#getting-started]
To start using Prisma products, you'll need to:
1. Create a Console account
2. Set up a workspace for your team
3. Create a project for your application
4. Generate connection strings for your resources
Learn more in the [Getting Started](/console/getting-started) guide.
Core concepts [#core-concepts]
The Console is organized around four main concepts:
* **[User account](/console/concepts#user-account)**: Your personal account to manage workspaces and projects
* **[Workspaces](/console/concepts#workspace)**: Team-level container where billing is managed
* **[Projects](/console/concepts#project)**: Application-level container within a workspace
* **[Resources](/console/concepts#resources)**: Actual services or databases within a project (databases for Prisma Postgres)
Read more about [Console concepts](/console/concepts).
Console CLI [#console-cli]
In addition to the web interface, the Prisma CLI provides another way to interact with your Console account and manage Prisma products. This can be useful for programmatic access, such as integrating into CI workflows.
Learn more about the [Console CLI commands](/cli/console).
# Guides (/docs/guides)
Welcome to the Guides section! Here you'll find practical, step-by-step guides to help you accomplish specific tasks with Prisma products, including Prisma ORM, Prisma Accelerate, Prisma Postgres, and more.
Browse through our guides using the sidebar navigation or use the search to find specific topics.
Getting started [#getting-started]
* [Next.js](/guides/frameworks/nextjs) - Learn how to use Prisma ORM in a Next.js app and deploy it to Vercel
* [Hono](/guides/frameworks/hono) - Learn how to use Prisma ORM in a Hono app
* [SvelteKit](/guides/frameworks/sveltekit) - Learn how to use Prisma ORM in a SvelteKit app
# Writing guides (/docs/guides/making-guides)
Introduction [#introduction]
This guide shows you how to write guides for Prisma ORM documentation. It covers the required structure, formatting, and style conventions to ensure consistency across all guides. You'll learn about frontmatter requirements, section organization, and writing style.
Prerequisites [#prerequisites]
Before writing a guide, make sure you have:
* A clear understanding of the topic you're writing about
* Access to the Prisma documentation repository
* Familiarity with Markdown and MDX
* Knowledge of the target audience for your guide
Guide structure [#guide-structure]
Required frontmatter [#required-frontmatter]
Every guide must include the following frontmatter at the top of the file:
```mdx
---
title: '[Descriptive title]'
description: '[One-sentence summary of what the guide covers]'
---
```
* `title`: A clear, descriptive title (e.g., "Next.js", "Multiple databases", "GitHub Actions")
* `description`: A one-sentence summary that describes what you'll learn or accomplish
* `image`: A unique header image for social media sharing (coordinate with the design team)
All frontmatter fields should use sentence case.
Required sections [#required-sections]
1. **Introduction** (H2: `##`)
* Brief overview of what the guide covers
* What the reader will learn/accomplish
* Link to any example repositories or related resources on GitHub
2. **Prerequisites** (H2: `##`)
* Required software/tools with version numbers (e.g., "Node.js 20+")
* Required accounts (e.g., "A Prisma Data Platform account")
* Keep it concise - only list what's truly necessary
3. **Main content sections** (H2: `##`)
* Use numbered steps (e.g., "## 1. Set up your project", "## 2. Install and Configure Prisma")
* Use numbered subsections (e.g., "### 2.1. Install dependencies", "### 2.2. Define your Prisma Schema")
* Each step should build on previous steps
* Include all commands and code snippets needed
4. **Next steps** (H2: `##`)
* What to do after completing the guide
* Related guides or documentation (with links)
* Additional resources
Writing style and voice [#writing-style-and-voice]
General principles [#general-principles]
* Write in a clear, conversational tone
* Use active voice and present tense
* Address the reader directly using "you" (e.g., "You'll learn how to...")
* Avoid jargon and explain technical terms when necessary
* Be concise but thorough
* Guide readers step-by-step through the process
Code examples [#code-examples]
* Include complete, runnable code examples
* Use syntax highlighting with language specification
* Include file paths in code block metadata using `title=`
* Use ` ```bash title=".env" ` for `.env` files so inline `# [!code ++]`, `# [!code --]`, and `# [!code highlight]` annotations render correctly
* Reserve ` ```text ` for other plain-text files that do not need Fumadocs code annotations
* Use comments sparingly - only when needed to explain complex logic
* Use ` ```npm ` for package manager commands (auto-converts to pnpm/yarn/bun)
* Use ` ```bash ` for shell commands and `.env` files
* Use ` ```text ` for other plain text files
* Use ` ```typescript `, ` ```prisma `, ` ```json ` for respective languages
Example with file path:
```typescript title="src/lib/prisma.ts"
import { PrismaClient } from "../generated/prisma";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
export default prisma;
```
Example showing changes:
```typescript title="prisma.config.ts"
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Formatting conventions [#formatting-conventions]
* Use backticks for inline code:
* File names: `` `schema.prisma` ``
* Directory names: `` `prisma/` ``
* Code elements: `` `PrismaClient` ``
* Package manager commands: Use ` ```npm ` blocks (see [Package manager commands](#package-manager-commands))
* Use admonitions for important information:
```markdown
:::info
Context or background information
:::
:::note
Important details to remember
:::
:::warning
Critical information or gotchas
:::
:::tip
Helpful suggestions or best practices
:::
```
* Use proper heading hierarchy (never skip levels)
* Use numbered sections (e.g., "## 1. Setup", "### 1.1. Install")
* Link to other documentation pages using relative paths (e.g., `[Database drivers](/orm/core-concepts/supported-databases/database-drivers)`)
Guide categories [#guide-categories]
| Category | Directory | Description | Examples |
| ------------------- | ------------------------------ | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Framework** | `guides/frameworks/` | Integrate Prisma with frameworks | [Next.js](/guides/frameworks/nextjs), [NestJS](/guides/frameworks/nestjs), [SvelteKit](/guides/frameworks/sveltekit) |
| **Deployment** | `guides/deployment/` | Deploy apps and set up monorepos | [Turborepo](/guides/deployment/turborepo), [Cloudflare Workers](/guides/deployment/cloudflare-workers) |
| **Integration** | `guides/integrations/` | Use Prisma with platforms and tools | [GitHub Actions](/guides/integrations/github-actions), [Supabase](/guides/integrations/supabase-accelerate) |
| **Database** | `guides/database/` | Database patterns and migrations | [Multiple databases](/guides/database/multiple-databases), [Data migration](/guides/database/data-migration) |
| **Authentication** | `guides/authentication/` | Authentication patterns with Prisma | [Auth.js + Next.js](/guides/authentication/authjs/nextjs), [Better Auth + Next.js](/guides/authentication/better-auth/nextjs), [Clerk + Next.js](/guides/authentication/clerk/nextjs) |
| **Prisma Postgres** | `guides/postgres/` | Prisma Postgres features | [Vercel](/guides/postgres/vercel), [Netlify](/guides/postgres/netlify), [Viewing data](/guides/postgres/viewing-data) |
| **Migration** | `guides/switch-to-prisma-orm/` | Switch from other ORMs | [From Mongoose](/guides/switch-to-prisma-orm/from-mongoose), [From Drizzle](/guides/switch-to-prisma-orm/from-drizzle) |
Common patterns [#common-patterns]
Package manager commands [#package-manager-commands]
Use ` ```npm ` code blocks for package manager commands. These automatically convert to other package managers (pnpm, yarn, bun) in the UI:
npm
pnpm
yarn
bun
```bash
npm install prisma --save-dev
```
```bash
pnpm add prisma --save-dev
```
```bash
yarn add prisma --dev
```
```bash
bun add prisma --dev
```
Environment variables [#environment-variables]
Show `.env` file examples using ` ```bash title=".env" ` blocks:
```bash title=".env"
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
```
If you need to show changes in an `.env` file, use bash comments for the Fumadocs annotations:
```bash title=".env"
DATABASE_URL="postgresql://user:password@localhost:5432/mydb" # [!code --]
DATABASE_URL="postgresql://user:password@db.example.com:5432/mydb" # [!code ++]
```
Database provider compatibility [#database-provider-compatibility]
Include an info admonition when commands or code are PostgreSQL-specific:
```markdown
:::info
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
:::
```
Prisma Client instantiation [#prisma-client-instantiation]
Show the standard pattern for creating a Prisma Client with database adapters:
```typescript title="lib/prisma.ts"
import { PrismaClient } from "../generated/prisma";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
export default prisma;
```
Include a warning about connection pooling:
```markdown
:::warning
We recommend using a connection pooler (like [Prisma Accelerate](https://www.prisma.io/accelerate)) to manage database connections efficiently.
:::
```
Best practices [#best-practices]
1. **Keep it focused**
* Each guide should cover one main topic
* Break complex topics into multiple guides
* Link to related guides instead of duplicating content
2. **Show don't tell**
* Include practical, real-world examples
* Provide complete, working code samples
* Explain why certain approaches are recommended
3. **Consider the context**
* Explain prerequisites clearly
* Don't assume prior knowledge
* Link to foundational concepts within or outside of our docs when needed
4. **Maintain consistency**
* Follow the established guide structure
* Use consistent terminology
* Match the style of existing guides
5. **Think about maintenance**
* Use version numbers where appropriate
* Avoid time-sensitive references
* Consider future updates when structuring content
Guide template [#guide-template]
Use this template as a starting point for new guides. The template includes common sections and patterns used across Prisma guides.
Basic template structure [#basic-template-structure]
Copy this template for a new guide:
````markdown
---
title: '[Your guide title]'
description: '[One-sentence summary of what you'll learn]'
image: '/img/guides/[guide-name]-cover.png'
---
## Introduction
[Brief overview of what this guide covers and what you'll accomplish. Include a link to an example repository if available.]
## Prerequisites
- [Node.js 20+](https://nodejs.org)
- [Any other prerequisites]
## 1. Set up your project
[Instructions for creating or setting up the project]
```npm
# Example command
npx create-next-app@latest my-app
cd my-app
```
## 2. Install and Configure Prisma
### 2.1. Install dependencies
To get started with Prisma, you'll need to install a few dependencies:
```npm
npm install prisma tsx @types/pg --save-dev
```
```npm
npm install @prisma/client @prisma/adapter-pg dotenv pg
```
:::info
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
:::
Once installed, initialize Prisma in your project:
```npm
npx prisma init --db --output ../generated/prisma
```
:::info
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database.
:::
This will create:
- A `prisma` directory with a `schema.prisma` file
- A Prisma Postgres database
- A `.env` file containing the `DATABASE_URL`
- A `prisma.config.ts` file for configuration
### 2.2. Define your Prisma Schema
In the `prisma/schema.prisma` file, add your models:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
posts Post[] // [!code ++]
} // [!code ++]
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
published Boolean @default(false) // [!code ++]
authorId Int // [!code ++]
author User @relation(fields: [authorId], references: [id]) // [!code ++]
} // [!code ++]
```
### 2.3. Run migrations and generate Prisma Client
Create the database tables:
```npm
npx prisma migrate dev --name init
```
Then generate Prisma Client:
```npm
npx prisma generate
```
## 3. [Integration-specific steps]
[Add framework or platform-specific integration steps here]
## Next steps
Now that you've completed this guide, you can:
- [Suggestion 1]
- [Suggestion 2]
- [Related guide 1](/path/to/guide)
- [Related guide 2](/path/to/guide)
For more information:
- [Prisma documentation](/orm)
- [Related documentation]
````
Adding guides to navigation [#adding-guides-to-navigation]
Guides are organized by category in subdirectories. To add a guide to the navigation, you need to update the appropriate `meta.json` file.
Main categories [#main-categories]
The main guide categories are listed in `meta.json`:
```json title="apps/docs/content/docs/guides/meta.json"
{
"title": "Guides",
"root": true,
"icon": "NotebookTabs",
"pages": [
"index",
"frameworks",
"deployment",
"authentication",
"integrations",
"postgres",
"database",
"switch-to-prisma-orm",
"upgrade-prisma-orm"
]
}
```
Adding a guide to a category [#adding-a-guide-to-a-category]
To add a guide to a category (e.g., `frameworks`), edit the category's `meta.json` file:
```json title="apps/docs/content/docs/guides/frameworks/meta.json"
{
"title": "Frameworks",
"defaultOpen": true,
"pages": [
"nextjs",
"astro",
"nuxt",
"your-new-guide" // [!code ++]
]
}
```
The page name should match your `.mdx` filename without the extension. For example, if your file is `your-new-guide.mdx`, add `"your-new-guide"` to the `pages` array.
Next steps [#next-steps]
After reading this guide, you can:
* Start writing your own guide using the provided template
* Review existing guides in the category you're contributing to
* Coordinate with the design team for a unique header image
* Submit your guide for review
# Using API Clients (/docs/management-api/api-clients)
This guide shows you how to configure popular API clients to work with the Management API using OAuth 2.0 authentication.
Postman [#postman]
Postman is a popular API client with testing, collaboration, and automation features for working with REST APIs.
Prerequisites [#prerequisites]
Before you begin, make sure you have:
* A [Prisma Console account](https://console.prisma.io)
* [Postman installed](https://www.postman.com/downloads/)
1. Create an OAuth2 Application [#1-create-an-oauth2-application]
First, you'll need to register an OAuth2 application in Prisma Console:
1. Navigate to [Prisma Console](https://console.prisma.io) and log in
2. Click the **🧩 Integrations** tab in the left sidebar
3. Under the "Published Applications" section, click **New Application**
4. Fill in your application details:
* **Name**: Postman API Client
* **Description**: Brief description of your application *(Optional)*
* **Redirect URI**: `https://oauth.pstmn.io/v1/callback`
5. Click **Continue**
6. **Important**: Copy your Client ID and Client Secret immediately and store them securely
The redirect URI `https://oauth.pstmn.io/v1/callback` is Postman's default callback URL when using the "Authorize using browser" option.
2. Configure OAuth 2.0 in Postman [#2-configure-oauth-20-in-postman]
Now you'll set up authentication in Postman:
1. Open Postman and create a new HTTP request
2. Set the request method to **POST**
3. Set the URL to `https://api.prisma.io/v1/projects`
4. Navigate to the **Authorization** tab
5. Set **Auth Type** to **OAuth 2.0**
6. Under **Configure New Token**, enter the following values:
| Parameter | Value |
| -------------------- | ------------------------------------ |
| Token Name | Management API Token |
| Grant Type | Authorization Code |
| Callback URL | `https://oauth.pstmn.io/v1/callback` |
| Authorize in Browser | `true` *(checked)* |
| Auth URL | `https://auth.prisma.io/authorize` |
| Access Token URL | `https://auth.prisma.io/token` |
| Client ID | `your-client-id` |
| Client Secret | `your-client-secret` |
| Scope | `workspace:admin` |
7. Click **Get New Access Token**
8. A browser window will open and have you complete the authorization flow
9. Return to Postman and click **Use Token** to attach it to your request
10. Verify that your new token appears under **Current Token** at the top of the Authorization tab
3. Make your first request [#3-make-your-first-request]
With authentication configured, you can now create a project:
1. In the request body, select **raw** and **JSON** format
2. Add the following JSON payload:
```json
{
"name": "My Postman Database",
"region": "us-east-1"
}
```
3. Click **Send**
You should receive a successful response confirming your project creation.
Insomnia [#insomnia]
Insomnia is an open-source API client with a clean interface for testing and debugging HTTP requests.
Prerequisites [#prerequisites-1]
Before you begin, make sure you have:
* A [Prisma Console account](https://console.prisma.io)
* [Insomnia installed](https://insomnia.rest/download/)
1. Create an OAuth2 Application [#1-create-an-oauth2-application-1]
First, you'll need to register an OAuth2 application in Prisma Console:
1. Navigate to [Prisma Console](https://console.prisma.io) and log in
2. Click the **🧩 Integrations** tab in the left sidebar
3. Under the "Published Applications" section, click **New Application**
4. Fill in your application details:
* **Name**: Insomnia API Client
* **Description**: Brief description of your application *(Optional)*
* **Redirect URI**: `https://app.insomnia.rest/oauth/redirect`
5. Click **Continue**
6. **Important**: Copy your Client ID and Client Secret immediately and store them securely
Insomnia uses `https://app.insomnia.rest/oauth/redirect` as the default OAuth callback URL for local authentication flows.
2. Configure OAuth 2.0 in Insomnia [#2-configure-oauth-20-in-insomnia]
Now you'll set up authentication in Insomnia:
1. Open Insomnia and create a new HTTP request
2. Set the request method to **POST**
3. Set the URL to `https://api.prisma.io/v1/projects`
4. Navigate to the **Auth** tab
5. Set the authentication type to **OAuth 2.0**
6. Under **Configuration**, enter the following values:
| Parameter | Value |
| -------------------------------- | ------------------------------------------ |
| Grant Type | Authorization Code |
| Authorization URL | `https://auth.prisma.io/authorize` |
| Access Token URL | `https://auth.prisma.io/token` |
| Client ID | `your-client-id` |
| Client Secret | `your-client-secret` |
| Redirect URL | `https://app.insomnia.rest/oauth/redirect` |
| Scope *(Under Advanced Options)* | `workspace:admin` |
7. Click **Fetch Tokens**
8. A browser window will open and have you complete the authorization flow
9. Return to Insomnia and verify that the access token has been retrieved
10. The token will be automatically attached to your requests
3. Make your first request [#3-make-your-first-request-1]
With authentication configured, you can now create a project:
1. Navigate to the **Body** tab and select **JSON** format
2. Add the following JSON payload:
```json
{
"name": "My Insomnia Database",
"region": "us-east-1"
}
```
3. Click **Send**
You should receive a successful response confirming your project creation.
Yaak [#yaak]
Yaak is a lightweight, open-source, and offline API client that works with Git.
Prerequisites [#prerequisites-2]
Before you begin, make sure you have:
* A [Prisma Console account](https://console.prisma.io)
* [Yaak installed](https://yaak.app)
1. Create an OAuth2 Application [#1-create-an-oauth2-application-2]
First, you'll need to register an OAuth2 application in Prisma Console:
1. Navigate to [Prisma Console](https://console.prisma.io) and log in
2. Click the **🧩 Integrations** tab in the left sidebar
3. Under the "Published Applications" section, click **New Application**
4. Fill in your application details:
* **Name**: Yaak API Client
* **Description**: Brief description of your application *(Optional)*
* **Redirect URI**: `https://devnull.yaak.app/callback`
5. Click **Continue**
6. **Important**: Copy your Client ID and Client Secret immediately and store them securely
The redirect URI can be any valid URL. Yaak intercepts the OAuth callback regardless of the redirect URI, as long as it matches what's registered with the provider.
2. Configure OAuth 2.0 in Yaak [#2-configure-oauth-20-in-yaak]
Now you'll set up authentication in Yaak:
1. Open Yaak and create a new HTTP request
2. Set the request method to **POST**
3. Set the URL to `https://api.prisma.io/v1/projects`
4. Navigate to the **Auth** tab
5. Set the authentication type to **OAuth 2.0**
6. Enter the following values:
| Parameter | Value |
| ----------------- | ----------------------------------- |
| Grant Type | Authorization Code |
| Authorization URL | `https://auth.prisma.io/authorize` |
| Token URL | `https://auth.prisma.io/token` |
| Client ID | `your-client-id` |
| Client Secret | `your-client-secret` |
| Redirect URL | `https://devnull.yaak.app/callback` |
| Scope | `workspace:admin` |
7. Click **Get Token**
8. A browser window will open and have you complete the authorization flow
9. Return to Yaak and verify that the access token has been retrieved
10. The token will be automatically attached to your requests
3. Make your first request [#3-make-your-first-request-2]
With authentication configured, you can now create a project:
1. Navigate to the **Body** tab and select **JSON** format
2. Add the following JSON payload:
```json
{
"name": "My Yaak Database",
"region": "us-east-1"
}
```
3. Click **Send**
You should receive a successful response confirming your project creation.
# Authentication (/docs/management-api/authentication)
The Management API supports two authentication methods:
* **Service Tokens** - Simple bearer tokens for server-to-server integrations
* **OAuth 2.0** - For user-facing applications requiring user consent
Service tokens [#service-tokens]
Service tokens are the simplest way to authenticate. They're ideal for scripts, CI/CD pipelines, and backend services.
Creating a Service token [#creating-a-service-token]
1. Navigate to [Prisma Console](https://console.prisma.io) and log in
2. Select your workspace
3. Go to **Settings → Service Tokens**
4. Click **New Service Token**
5. Copy the generated token immediately and store it securely
Using a Service token [#using-a-service-token]
Include the token in the `Authorization` header:
```bash
curl -X GET "https://api.prisma.io/v1/workspaces" \
-H "Authorization: Bearer your-service-token"
```
Or with the SDK:
```typescript
import { createManagementApiClient } from "@prisma/management-api-sdk";
const client = createManagementApiClient({
token: "your-service-token",
});
```
Service tokens never expire
Service tokens do not have an expiration date. While this provides convenience for long-running integrations, it also means these tokens require careful security management.
OAuth 2.0 [#oauth-20]
OAuth 2.0 is required for applications that act on behalf of users. The API uses OAuth 2.0 with PKCE for secure authentication.
PKCE Support [#pkce-support]
The OAuth implementation supports Proof Key for Code Exchange (PKCE) using the S256 code challenge method:
* **Public clients** (no client secret): PKCE is **mandatory**
* **Confidential clients** (with client secret): PKCE is **optional**, but if you start the flow with PKCE, it must be completed with PKCE
This provides enhanced security, especially for mobile and single-page applications that cannot securely store client secrets.
Creating an OAuth Application [#creating-an-oauth-application]
1. Navigate to [Prisma Console](https://console.prisma.io) and log in
2. Click the **Integrations** tab in the left sidebar
3. Under "Published Applications", click **New Application**
4. Fill in your application details:
* **Name**: Your application name
* **Description**: Brief description *(optional)*
* **Redirect URI**: Your callback URL (e.g., `https://your-app.com/auth/callback`)
5. Click **Continue**
6. Copy your **Client ID** and **Client Secret** immediately
Development redirect URIs
For local development, the following redirect URIs are accepted with any port via wildcard matching:
* `localhost` (e.g., `http://localhost:3000/callback`)
* `127.0.0.1` (e.g., `http://127.0.0.1:3000/callback`)
* `[::1]` - IPv6 loopback (e.g., `http://[::1]:3000/callback`)
OAuth Endpoints [#oauth-endpoints]
| Endpoint | URL |
| ------------- | --------------------------------------------------------------- |
| Authorization | `https://auth.prisma.io/authorize` |
| Token | `https://auth.prisma.io/token` |
| Discovery | `https://auth.prisma.io/.well-known/oauth-authorization-server` |
The discovery endpoint provides OAuth server metadata that can be used for automatic client configuration. Many OAuth libraries support automatic discovery using this endpoint.
Available Scopes [#available-scopes]
| Scope | Description |
| ----------------- | ---------------------------------------------- |
| `workspace:admin` | Full access to workspace resources |
| `offline_access` | Enables refresh tokens for long-lived sessions |
Token Lifetimes [#token-lifetimes]
| Token Type | Expiration |
| -------------- | ---------- |
| Access tokens | 1 hour |
| Refresh tokens | 90 days |
OAuth Authorization Flow [#oauth-authorization-flow]
1. Redirect users to authorize [#1-redirect-users-to-authorize]
Redirect users to the authorization endpoint with the following query parameters:
| Parameter | Description |
| --------------- | ------------------------------------------------------------------- |
| `client_id` | Your OAuth application's Client ID |
| `redirect_uri` | The callback URL where users will be redirected after authorization |
| `response_type` | Must be `code` for the authorization code flow |
| `scope` | Permissions to request (e.g., `workspace:admin`) |
```
https://auth.prisma.io/authorize?client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&response_type=code&scope=workspace:admin
```
This will redirect the user to the Prisma authorization page where they can grant your application access to their workspace.
2. Receive the authorization code [#2-receive-the-authorization-code]
After authorization, users are redirected to your callback URL with a `code` parameter:
```
https://your-app.com/callback?code=abc123...
```
3. Exchange the code for an access token [#3-exchange-the-code-for-an-access-token]
```bash
curl -X POST https://auth.prisma.io/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "code=$CODE" \
-d "grant_type=authorization_code" \
-d "redirect_uri=$REDIRECT_URI"
```
The response will include an access token that can be used to make authenticated requests to the Management API:
```json
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
```
4. Use the access token [#4-use-the-access-token]
```bash
curl -X GET "https://api.prisma.io/v1/workspaces" \
-H "Authorization: Bearer $ACCESS_TOKEN"
```
Token Refresh [#token-refresh]
If you requested the `offline_access` scope, you'll receive a refresh token. Use it to obtain new access tokens:
```bash
curl -X POST https://auth.prisma.io/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "refresh_token=$REFRESH_TOKEN" \
-d "grant_type=refresh_token"
```
Refresh token rotation
Refresh tokens use single-use rotation with replay attack detection. When you exchange a refresh token for a new access token, you'll receive a new refresh token in the response. The old refresh token is immediately invalidated. If an invalidated refresh token is used again, it indicates a potential security breach, and the system will revoke all tokens associated with that authorization.
Using OAuth with the SDK [#using-oauth-with-the-sdk]
The SDK handles the OAuth flow automatically. See the [SDK documentation](/management-api/sdk#oauth-authentication-flow) for implementation details.
Using API Clients [#using-api-clients]
You can also authenticate using popular API clients like Postman, Insomnia, or Yaak. See the [Using API Clients](/management-api/api-clients) guide for step-by-step instructions.
# Getting Started (/docs/management-api/getting-started)
This guide walks you through setting up a basic TypeScript project that uses the Management API to create a new Prisma Console project with a Prisma Postgres database, and print out all connection details.
You'll authenticate via a service token, set up your environment, and run a script to interact with the API.
Prerequisites [#prerequisites]
* Node.js and `npm` installed
* A [Prisma Data Platform](https://console.prisma.io/) account
1. Create a service token in Prisma Console [#1-create-a-service-token-in-prisma-console]
First, you need to create a service token to be able to access the Management API:
1. Open the [Prisma Console](https://console.prisma.io/)
2. Navigate to the **Settings** page of your workspace and select **Service Tokens**
3. Click **New Service Token**
4. Copy and save the generated service token securely, you'll use it in step 2.2.
2. Set up your project directory [#2-set-up-your-project-directory]
2.1. Create a basic TypeScript project [#21-create-a-basic-typescript-project]
Open your terminal and run the following commands:
```bash
mkdir management-api-demo
cd management-api-demo
```
Next, initialize npm and install dependencies required for using TypeScript:
npm
pnpm
yarn
bun
```bash
npm init -y
npm install tsx typescript @types/node --save-dev
touch index.ts
```
```bash
pnpm init -y
pnpm add tsx typescript @types/node --save-dev
touch index.ts
```
```bash
yarn init -y
yarn add tsx typescript @types/node --dev
touch index.ts
```
```bash
bun init -y
bun add tsx typescript @types/node --dev
touch index.ts
```
You now have an `index.ts` file that you can execute with `npx tsx index.ts`. It's still empty, you'll start writing code in step 3.
2.2. Configure service token environment variable [#22-configure-service-token-environment-variable]
Create your `.env` file:
```bash
touch .env
```
Next, install the [`dotenv`](https://github.com/motdotla/dotenv) library for loading environment variables from the `.env` file:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
Finally, add your service token (from step 1.) to `.env`:
```bash
PRISMA_SERVICE_TOKEN="ey..."
```
2.3. Install the axios library for HTTP request [#23-install-the-axios-library-for-http-request]
You're going to use [`axios`](https://github.com/axios/axios/tree/main) as your HTTP client to interact with the Management API. Install it as follows:
npm
pnpm
yarn
bun
```bash
npm install axios
```
```bash
pnpm add axios
```
```bash
yarn add axios
```
```bash
bun add axios
```
You're all set, let's write some code to create a project and provision a Prisma Postgres database!
3. Programmatically create a new project with a database [#3-programmatically-create-a-new-project-with-a-database]
Paste the following code into `index.ts`:
```ts
import axios from "axios";
import dotenv from "dotenv";
// Load environment variables
dotenv.config();
const API_URL = "https://api.prisma.io/v1";
const SERVICE_TOKEN = process.env.PRISMA_SERVICE_TOKEN;
if (!SERVICE_TOKEN) {
throw new Error("PRISMA_SERVICE_TOKEN is not set in the environment");
}
// Set HTTP headers to be used in this script
const headers = {
Authorization: `Bearer ${SERVICE_TOKEN}`,
"Content-Type": "application/json",
};
async function main() {
// Create a new project in your Prisma Console workspace
const projectName = `demo-project-${Date.now()}`;
const region = "us-east-1";
const createProjectRes = await axios.post(
`${API_URL}/projects`,
{ name: projectName, region },
{ headers },
);
const project = createProjectRes.data;
console.log("Created project: \n", project);
// Log the database details
const apiKeys = project.databases[0].apiKeys || [];
for (const key of apiKeys) {
console.log(`\nDatabase details`);
console.log(`- ID: ${key.id}`);
console.log(`- Created at: ${key.createdAt}`);
console.log(`- API key: ${key.apiKey}`);
console.log(`- Prisma Postgres connection string: ${key.connectionString}`);
if (key.ppgDirectConnection) {
console.log(`- Direct TCP connection: ${key.ppgDirectConnection.host}`);
console.log(` - Host: ${key.ppgDirectConnection.host}`);
console.log(` - Username: ${key.ppgDirectConnection.user}`);
console.log(` - Password: ${key.ppgDirectConnection.pass}`);
}
}
}
main().catch((e) => {
console.error(e.response?.data || e);
process.exit(1);
});
```
You can run your script with the following command:
npm
pnpm
yarn
bun
```bash
npx tsx index.ts
```
```bash
pnpm dlx tsx index.ts
```
```bash
yarn dlx tsx index.ts
```
```bash
bunx --bun tsx index.ts
```
```text no-copy
Created project:
{
createdAt: '2025-07-09T11:52:15.341Z',
id: 'cmcvwftgs00v5zq0vh3kp7pms',
name: 'demo-project-1752061932800',
databases: [
{
createdAt: '2025-07-09T11:52:15.341Z',
id: 'cmcvwftgs00v1zq0v0qrtrg8t',
name: 'demo-project-1752061932800',
connectionString: 'prisma+postgres://accelerate.prisma-data.net/?api_key=',
region: 'us-east-1',
status: 'ready',
apiKeys: [Array],
isDefault: true
}
]
}
Database details
- ID: cmcvwftgs00v2zq0vj3v0104j
- Created at: 2025-07-09T11:52:15.341Z
- API key: ey...
- Prisma Postgres connection string: prisma+postgres://accelerate.prisma-data.net/?api_key=ey...
- Direct TCP connection: db.prisma.io:5432
- Host: db.prisma.io:5432
- Username:
- Password:
```
Your output of the command should look similar to the output above.
Conclusion [#conclusion]
You have now set up a TypeScript project that interacts with the Management API, creates a new project and database, and prints out all connection strings. You can extend this script to manage more resources or automate other tasks using the Management API.
# Management API (/docs/management-api)
Base URL [#base-url]
```
https://api.prisma.io/v1
```
Append an endpoint path to construct the full URL. For example: `https://api.prisma.io/v1/projects/{projectId}`
An interactive [OpenAPI 3.1 specification](https://api.prisma.io/v1/swagger-editor) is available for exploring endpoints and request/response formats.
Getting Started [#getting-started]
* **[Getting Started](/management-api/getting-started)** - Create your first project and database
* **[Authentication](/management-api/authentication)** - OAuth 2.0 and service tokens setup
* **[SDK](/management-api/sdk)** - TypeScript SDK with built-in OAuth and automatic token refresh
* **[Using API Clients](/management-api/api-clients)** - Use with Postman, Insomnia, and Yaak
* **[Partner Integration](/management-api/partner-integration)** - Build integrations that provision and transfer databases
# Partner Integration (/docs/management-api/partner-integration)
This guide walks you through building a partner integration with the Management API to power experiences like the [`npx create-db`](https://create-db.prisma.io/) command.
You'll learn how to provision a Prisma Postgres database on your workspace as a partner, and how to transfer it to another user's workspace so they can "claim" the database. We'll cover how the process is secured using OAuth2, and by the end, you'll understand the full flow and how to integrate it into your own product experience.
This guide references the actual implementation in the `npx create-db` CLI and Cloudflare Workers as real world examples. The repo for the `npx create-db` is [here](https://github.com/prisma/create-db), which can be used as a reference for how to use the Management API in your own projects.
How does this fit into your app?
The two Cloudflare Workers in this guide are just reference examples. You would typically build this logic into your own backend or serverless functions.
Similarly, the `npx create-db` CLI is a simple demo. In your product, you can trigger the same API calls from your own UI or onboarding flows to create a seamless experience for your users.
Core concepts [#core-concepts]
Before diving into implementation, let's clarify the main concepts involved in the Management API integration:
* **Management API**: A set of endpoints that allow you to programmatically provision and manage Prisma Postgres databases.
* **Projects vs Databases**: A project is a container that can hold multiple databases. You can use this to organize databases you create e.g. by user. Projects can then be transferred to users, including all databases they contain.
* **Authentication**: All API requests require authentication. As a partner, you authenticate provisioning calls with a service token for your workspace, and use OAuth 2 to obtain an access token for the user during the claim flow.
* **Tokens**: There are two main types of tokens:
* **Service token**: Issued to your partner integration, scoped to provision and manage databases on your own workspace.
* **OAuth 2 access token**: Obtained via OAuth 2 when a user authenticates with your app; it is scoped to the user's workspace and used to transfer project/database ownership to that workspace.
How to become a partner [#how-to-become-a-partner]
To use the Prisma Postgres Management API, you first need to set up as a partner:
1. **Request access to the Management API**: Contact the Prisma team from the [Prisma Partners page](https://www.prisma.io/partners) to request access to the Management API. You will be guided through the onboarding process.
2. **Obtain OAuth credentials**: You can obtain your OAuth credentials in the [Prisma Console](https://console.prisma.io). See the [next section](#get-oauth-credentials) for details.
For a complete list of available endpoints and details on request/response formats, see the [Prisma Management API documentation](/management-api).
Get OAuth credentials [#get-oauth-credentials]
To obtain a client ID and client secret, you need go through this flow:
1. Open the [Prisma Console](https://console.prisma.io).
2. Click the 🧩 **Integrations** tab in the sidenav.
3. In the **Published Applications** section, click **New Application** button to start the flow for creating a new OAuth app.
4. Enter a **Name**, **Description** and **Callback URL** for your OAuth app.
5. Click **Continue**.
On the next screen, you can access and save the client ID and client secret for your OAuth app.
Provisioning a database as a Partner [#provisioning-a-database-as-a-partner]
To provision a new Prisma Postgres database for your users as a partner, follow these steps:
1. **Gather required information**: Prepare the necessary details for provisioning, such as region, database name, and any other options your application requires. This information may come from user input or be determined by your application logic.
2. **Authenticate your integration**: Use your service token to authenticate API requests from your backend. This token authenticates your app as an approved partner.
3. **Send a database provisioning request**: Make a `POST` request to the Management API endpoint to create a new project with a default database. For example:
```ts
const prismaResponse = await fetch("https://api.prisma.io/v1/projects", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer `,
},
body: JSON.stringify({ region, name }),
});
```
4. **Handle the response**: If successful, the API will return the new project's details, including database connection strings and a `project_id`. Store these securely and display them to your user as needed.
5. **(Optional) Store project metadata**: You may want to associate the `project_id` with your user in your own database for future reference.
Database claim flow [#database-claim-flow]
Once a database is provisioned, you may want to transfer ownership to your user at a later point so they can manage it in their own Prisma workspace and go beyond the free database usage limits. This is done via the claim flow, which consists of three main steps:
Overview: How the claim flow works [#overview-how-the-claim-flow-works]
When a user wants to claim a database, your app will:
1. Trigger the OAuth2 flow, redirecting the user to Prisma Auth. This is necessary, so your app will have the permissions to transfer the database into the user's workspace.
2. The user authenticates and selects a workspace.
3. Your backend receives an authorization code, exchanges it for a user access token, and calls the Management API transfer endpoint with both your integration token and the user's token.
This ensures the transfer is secure and only the intended user can claim the database.
1. Triggering the claim flow [#1-triggering-the-claim-flow]
When your user wants to take ownership of a database you provisioned for them, they need to transfer it to their own Prisma Postgres workspace. This gives them full control over it.
To initiate this process, provide a button or link in your app (e.g., "Claim Database" or "Transfer to My Workspace"). When clicked, your backend should:
* Generate a secure `state` value to track the session and prevent CSRF attacks.
* Construct an OAuth2 authorization URL with your client ID, redirect URI, and required scopes.
* Redirect the user to this URL to begin the authentication flow.
Example:
```ts
const authParams = new URLSearchParams({
client_id: YOUR_CLIENT_ID,
redirect_uri: "https://your-app.com/auth/callback", // Your callback endpoint
response_type: "code",
scope: "workspace:admin", // The scope of the OAuth2 authorization
state: generateState(), // Securely track the session
});
const authUrl = `https://auth.prisma.io/authorize?${authParams.toString()}`;
// Redirect the user to authUrl
```
2. Authenticating the user [#2-authenticating-the-user]
The user will be prompted to log in (if not already authenticated) and select the workspace where they want to claim the database. After successful authentication and workspace selection, Prisma Auth will redirect back to your callback endpoint with a `code` and `state` (and, in some cases, a `project_id`).
3. Finishing the claim flow [#3-finishing-the-claim-flow]
Your backend should now:
1. **Exchange the authorization code for a user access token**:
```ts
const tokenResponse = await fetch("https://auth.prisma.io/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "authorization_code",
code: code, // The code received from the callback
redirect_uri: "https://your-app.com/auth/callback", // Must match the redirect_uri used in step 1
client_id: YOUR_CLIENT_ID,
client_secret: YOUR_CLIENT_SECRET,
}).toString(),
});
const tokenData = await tokenResponse.json();
```
2. **Call the Management API transfer endpoint** to move the project to the selected workspace. You will need the `project_id` and the user's access token:
```ts
const transferResponse = await fetch(`https://api.prisma.io/v1/projects/${project_id}/transfer`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${PRISMA_SERVICE_TOKEN}`,
},
body: JSON.stringify({ recipientAccessToken: tokenData.access_token }),
});
```
If the transfer is successful, the database is now owned by the user's workspace.
Conclusion [#conclusion]
By following this guide, you have learned how to:
* Set up as a Prisma Postgres Partner and obtain the necessary credentials
* Provision a new database for your users using the Management API
* Implement a secure claim flow that allows users to claim ownership of a database in their own workspace using OAuth2
This flow enables you to integrate Prisma Postgres provisioning and transfer seamlessly into your own product, providing a smooth onboarding experience for your users.
For further details, see the [create-db](https://github.com/prisma/create-db) repo for a reference implementation, or consult the [Prisma Management API documentation](/management-api).
# SDK (/docs/management-api/sdk)
Overview [#overview]
The [`@prisma/management-api-sdk`](https://www.npmjs.com/package/@prisma/management-api-sdk) is a TypeScript SDK for the [Prisma Data Platform Management API](/management-api). Use the simple client for direct API access, or the full SDK with built-in OAuth authentication and automatic token refresh.
Based on the [public OpenAPI 3.1 specification](https://api.prisma.io/v1/swagger-editor).
Installation [#installation]
npm
pnpm
yarn
bun
```bash
npm install @prisma/management-api-sdk
```
```bash
pnpm add @prisma/management-api-sdk
```
```bash
yarn add @prisma/management-api-sdk
```
```bash
bun add @prisma/management-api-sdk
```
Basic usage [#basic-usage]
For usage with an existing access or [service token](/management-api/authentication#service-tokens).
Making API calls [#making-api-calls]
The client provides fully typed methods for all API endpoints:
```typescript
import { createManagementApiClient } from "@prisma/management-api-sdk";
const client = createManagementApiClient({
token: "your-access-token",
});
// List workspaces
const { data: workspaces, error } = await client.GET("/v1/workspaces");
// Get a specific project
const { data: project } = await client.GET("/v1/projects/{id}", {
params: { path: { id: "project-id" } },
});
// Create a new project
const { data: newProject } = await client.POST("/v1/workspaces/{workspaceId}/projects", {
params: { path: { workspaceId: "workspace-id" } },
body: { name: "My New Project" },
});
// Create a new database
const { data: newDatabase } = await client.POST("/v1/projects/{projectId}/databases", {
params: { path: { projectId: "project-id" } },
body: {
name: "my-new-db-instance",
region: "us-east-1",
isDefault: true,
},
});
// Delete a database
const { error: deleteError } = await client.DELETE("/v1/databases/{databaseId}", {
params: { path: { databaseId: "database-id" } },
});
```
Customizing the client [#customizing-the-client]
You can override any `ClientOptions` from `openapi-fetch`, including `baseUrl`, `headers`, and other fetch options:
```typescript
import { createManagementApiClient } from "@prisma/management-api-sdk";
// Override baseUrl and add custom headers
const client = createManagementApiClient({
token: "your-access-token",
baseUrl: "https://api.example.com",
headers: {
"X-Custom-Header": "value",
},
});
```
If you provide both `token` and `headers.Authorization`, the `headers.Authorization` takes precedence. The `baseUrl` defaults to `https://api.prisma.io` if not provided.
Advanced usage [#advanced-usage]
For applications that need [OAuth authentication](#oauth-authentication-flow), automatic token refresh, and token storage management, use the full SDK.
OAuth authentication flow [#oauth-authentication-flow]
The SDK uses OAuth 2.0 with PKCE for secure authentication. The flow is stateless - you're responsible for storing the `state` and `verifier` between the login URL generation and callback handling.
1. Create the SDK instance [#1-create-the-sdk-instance]
```typescript
import { createManagementApiSdk, type TokenStorage } from "@prisma/management-api-sdk";
// Implement token storage for your environment
const tokenStorage: TokenStorage = {
async getTokens() {
const stored = localStorage.getItem("prisma-tokens");
return stored ? JSON.parse(stored) : null;
},
async setTokens(tokens) {
localStorage.setItem("prisma-tokens", JSON.stringify(tokens));
},
async clearTokens() {
localStorage.removeItem("prisma-tokens");
},
};
// Create the SDK instance
const api = createManagementApiSdk({
clientId: "your-oauth-client-id",
redirectUri: "https://your-app.com/auth/callback",
tokenStorage,
});
```
2. Initiate login [#2-initiate-login]
Generate the OAuth login URL. The returned `state` and `verifier` must be stored (e.g., in a session or cookie) for use when handling the callback:
```typescript
const { url, state, verifier } = await api.getLoginUrl({
scope: "workspace:admin offline_access",
additionalParams: {
utm_source: "my-app",
utm_medium: "login",
},
});
// Store state and verifier for the callback (e.g., in session storage)
sessionStorage.setItem("oauth-state", state);
sessionStorage.setItem("oauth-verifier", verifier);
// Redirect user to the login URL
window.location.href = url;
```
3. Handle the callback [#3-handle-the-callback]
When the user is redirected back to your app, retrieve the stored `state` and `verifier` and pass them to `handleCallback`. On success, tokens are automatically stored via your `tokenStorage` implementation:
```typescript
// In your callback route handler
const callbackUrl = window.location.href;
// Retrieve the stored values
const expectedState = sessionStorage.getItem("oauth-state");
const verifier = sessionStorage.getItem("oauth-verifier");
// Clean up stored values
sessionStorage.removeItem("oauth-state");
sessionStorage.removeItem("oauth-verifier");
try {
await api.handleCallback({
callbackUrl,
verifier,
expectedState,
});
// Tokens are now stored in tokenStorage and the client is ready to use
console.log("Login successful!");
} catch (error) {
if (error instanceof AuthError) {
console.error("Authentication failed:", error.message);
}
}
```
4. Make API calls [#4-make-api-calls]
The client automatically includes authentication headers and refreshes tokens when they expire. Use `api.client` with the same methods shown in [Basic usage](#making-api-calls).
5. Logout [#5-logout]
```typescript
await api.logout(); // Clears stored tokens
```
Token storage interface [#token-storage-interface]
Implement this interface to handle token persistence in your environment:
```typescript
interface TokenStorage {
/** Provide the stored tokens to the SDK */
getTokens(): Promise;
/** Store new or updated tokens when the SDK has successfully authenticated or refreshed tokens */
setTokens(tokens: Tokens): Promise;
/** Clear the tokens when the user logs out or the refresh token is invalid */
clearTokens(): Promise;
}
type Tokens = {
/** The workspace ID that these tokens are valid for (extracted from the access token) */
workspaceId: string;
/** The access token for API requests */
accessToken: string;
/** The refresh token for obtaining new access tokens (only present if scope includes 'offline_access') */
refreshToken?: string;
};
```
Example: VS Code Extension [#example-vs-code-extension]
```typescript
const tokenStorage: TokenStorage = {
async getTokens() {
const workspaceId = await context.secrets.get("workspaceId");
const accessToken = await context.secrets.get("accessToken");
const refreshToken = await context.secrets.get("refreshToken");
if (!workspaceId || !accessToken) return null;
return { workspaceId, accessToken, refreshToken: refreshToken || undefined };
},
async setTokens(tokens) {
await context.secrets.store("workspaceId", tokens.workspaceId);
await context.secrets.store("accessToken", tokens.accessToken);
if (tokens.refreshToken) {
await context.secrets.store("refreshToken", tokens.refreshToken);
}
},
async clearTokens() {
await context.secrets.delete("workspaceId");
await context.secrets.delete("accessToken");
await context.secrets.delete("refreshToken");
},
};
```
Example: Node.js CLI [#example-nodejs-cli]
```typescript
import { readFile, writeFile, unlink } from "node:fs/promises";
import { homedir } from "node:os";
import { join } from "node:path";
const tokenPath = join(homedir(), ".prisma", "credentials.json");
const tokenStorage: TokenStorage = {
async getTokens() {
try {
const data = await readFile(tokenPath, "utf-8");
return JSON.parse(data);
} catch {
return null;
}
},
async setTokens(tokens) {
await writeFile(tokenPath, JSON.stringify(tokens, null, 2));
},
async clearTokens() {
await unlink(tokenPath).catch(() => {});
},
};
```
For other environments:
* **VS Code extensions** - Use `context.secrets` for secure storage
* **Stateless web servers** - Store PKCE state/verifier in encrypted cookies or a database
Automatic token refresh [#automatic-token-refresh]
The SDK automatically handles token refresh when a refresh token is available (requires `offline_access` scope):
* When a request returns 401, the SDK refreshes the access token using the refresh token
* Concurrent requests during refresh are queued and resolved once refresh completes
* If refresh fails due to an invalid refresh token, tokens are cleared and `AuthError` is thrown with `refreshTokenInvalid: true`
* If no refresh token is available, an `AuthError` is thrown with the message "No refresh token available. Please log in again."
API reference [#api-reference]
createManagementApiClient(options) [#createmanagementapiclientoptions]
Creates a raw API client without authentication handling. Useful if you want to manage authentication yourself or use a service token.
**Parameters:**
* `options.token?: string` - Access token (automatically converted to `Authorization: Bearer ${token}` header)
* `options.baseUrl?: string` - Base URL for API requests (defaults to `https://api.prisma.io`)
* `options.headers?: Record` - Additional headers
* Other `ClientOptions` from `openapi-fetch` are also supported
**Returns:** A typed API client for making requests.
createManagementApiSdk(config) [#createmanagementapisdkconfig]
Creates a Management API SDK instance with OAuth authentication and automatic token refresh.
**Parameters:**
```typescript
type ManagementApiClientConfig = {
// Required
clientId: string; // OAuth client ID
redirectUri: string; // OAuth redirect URI
tokenStorage: TokenStorage;
// Optional (with defaults)
apiBaseUrl?: string; // Default: 'https://api.prisma.io'
authBaseUrl?: string; // Default: 'https://auth.prisma.io'
};
```
**Returns:** An object with:
* `client` - The typed API client for making requests
* `getLoginUrl(options)` - Generate OAuth login URL with specified scope
* `handleCallback(options)` - Handle OAuth callback and store tokens via `tokenStorage`
* `logout()` - Clear stored tokens
Error handling [#error-handling]
The SDK exports two error classes:
AuthError [#autherror]
Thrown for authentication-related errors:
* OAuth callback errors (includes `error_description` when available)
* Invalid or missing tokens
* Token refresh failures
```typescript
import { AuthError } from "@prisma/management-api-sdk";
try {
await api.handleCallback({ callbackUrl, verifier, expectedState });
} catch (error) {
if (error instanceof AuthError) {
if (error.refreshTokenInvalid) {
// Token is invalid/expired, user needs to log in again
const { url } = await api.getLoginUrl({ scope: "workspace:admin offline_access" });
// redirect to url...
} else {
// Other auth errors (e.g., "access_denied: User cancelled")
console.error("Auth error:", error.message);
}
}
}
```
FetchError [#fetcherror]
Thrown for network-related errors. Includes the original error as `cause` for debugging:
```typescript
import { FetchError } from "@prisma/management-api-sdk";
try {
const { data } = await client.GET("/v1/workspaces");
} catch (error) {
if (error instanceof FetchError) {
console.error("Network error:", error.message);
console.error("Cause:", error.cause); // Original error for debugging
}
}
```
TypeScript types [#typescript-types]
The SDK exports all API types generated from the OpenAPI spec:
```typescript
import type { paths, components } from "@prisma/management-api-sdk";
// Access response types
type Workspace = components["schemas"]["Workspace"];
type Project = components["schemas"]["Project"];
```
# Prisma ORM (/docs/orm)
Prisma ORM is [open-source](https://github.com/prisma/prisma) and consists of:
* [**Prisma Client**](/orm/prisma-client/setup-and-configuration/introduction): Auto-generated, type-safe **ORM interface**
* [**Prisma Migrate**](/orm/prisma-migrate): Database migration system
* [**Prisma Studio**](https://www.prisma.io/studio): GUI to view and edit your data
Prisma Client works with any Node.js or TypeScript backend, whether you're deploying to traditional servers, serverless functions, or microservices.
Why Prisma ORM [#why-prisma-orm]
Traditional database tools force a tradeoff between **productivity** and **control**. Raw SQL gives full control but is error-prone and lacks type safety. Traditional ORMs improve productivity but abstract too much, leading to the [object-relational impedance mismatch](https://en.wikipedia.org/wiki/Object-relational_impedance_mismatch) and performance pitfalls like the n+1 problem.
Prisma takes a different approach:
* **Type-safe queries** validated at compile time with full autocompletion
* **Thinking in objects** without the complexity of mapping relational data
* **Plain JavaScript objects** returned from queries, not complex model instances
* **Single source of truth** in the Prisma schema for database and application models
* **Healthy constraints** that prevent common pitfalls and anti-patterns
When to use Prisma [#when-to-use-prisma]
**Prisma is a good fit if you:**
* Build server-side applications (REST, GraphQL, gRPC, serverless)
* Value type safety and developer experience
* Work in a team and want a clear, declarative schema
* Need migrations, querying, and data modeling in one toolkit
**Consider alternatives if you:**
* Need full control over every SQL query (use raw SQL drivers)
* Want a no-code backend (use a BaaS like Supabase or Firebase)
* Need an auto-generated CRUD GraphQL API (use Hasura or PostGraphile)
How it works [#how-it-works]
1. Define your schema [#1-define-your-schema]
The [Prisma schema](/orm/prisma-schema/overview) defines your data models and database connection:
```prisma
datasource db {
provider = "postgresql"
}
generator client {
provider = "prisma-client"
output = "./generated"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
```
2. Configure your connection [#2-configure-your-connection]
Create a `prisma.config.ts` file in your project root:
```ts title="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"),
},
});
```
3. Run migrations [#3-run-migrations]
Use [Prisma Migrate](/orm/prisma-migrate) to create and apply migrations:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev
```
```bash
pnpm dlx prisma migrate dev
```
```bash
yarn dlx prisma migrate dev
```
```bash
bunx --bun prisma migrate dev
```
Or [introspect](/orm/prisma-schema/introspection) an existing database:
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
4. Query with Prisma Client [#4-query-with-prisma-client]
Generate and use the type-safe client:
npm
pnpm
yarn
bun
```bash
npm install @prisma/client
npx prisma generate
```
```bash
pnpm add @prisma/client
pnpm dlx prisma generate
```
```bash
yarn add @prisma/client
yarn dlx prisma generate
```
```bash
bun add @prisma/client
bun x prisma generate
```
```ts
import { PrismaClient } from "./generated/client";
const prisma = new PrismaClient();
// Find all users with their posts
const users = await prisma.user.findMany({
include: { posts: true },
});
// Create a user with a post
const user = await prisma.user.create({
data: {
email: "alice@prisma.io",
posts: {
create: { title: "Hello World" },
},
},
});
```
Next steps [#next-steps]
* [**Prisma schema**](/orm/prisma-schema/overview) - Learn the schema language
* [**Prisma Client**](/orm/prisma-client/setup-and-configuration/introduction) - Explore the query API
# Error reference (/docs/postgres/error-reference)
When working with Prisma Postgres, you may encounter errors often highlighted by specific error codes during development and operations.
It is important to understand the meaning of these errors, why they occur, and how to resolve them in order to ensure the smooth operation of your applications. This guide aims to provide insights and steps to troubleshoot specific error codes encountered with Prisma Postgres.
P6009 (ResponseSizeLimitExceeded) [#p6009-responsesizelimitexceeded]
This error is triggered when the response size from a database query exceeds the configured query response size limit. We've implemented this restriction to safeguard your application performance, as retrieving data over `5MB` can significantly slow down your application due to multiple network layers.
Typically, transmitting more than `5MB` of data is common when conducting ETL (Extract, Transform, Load) operations. However, for other scenarios such as transactional queries, real-time data fetching for user interfaces, bulk data updates, or aggregating large datasets for analytics outside of ETL contexts, it should generally be avoided. These use cases, while essential, can often be optimized to work within the configured query response size limit, ensuring smoother performance and a better user experience.
Possible causes for P6009 [#possible-causes-for-p6009]
Transmitting images/files in response [#transmitting-imagesfiles-in-response]
This error may arise if images or files stored within your table are being fetched, resulting in a large response size. Storing assets directly in the database is generally discouraged because it significantly impacts database performance and scalability. In addition to performance, it makes database backups slow and significantly increases the cost of storing routine backups.
**Suggested solution:** Configure the query response size limit to be larger. If the limit is still exceeded, consider storing the image or file in a BLOB store like [Cloudflare R2](https://developers.cloudflare.com/r2/), [AWS S3](https://aws.amazon.com/pm/serv-s3/), or [Cloudinary](https://cloudinary.com/). These services allow you to store assets optimally and return a URL for access. Instead of storing the asset directly in the database, store the URL, which will substantially reduce the response size.
Over-fetching of data [#over-fetching-of-data]
In certain cases, a large number of records or fields are unintentionally fetched, which results in exceeding the configured query response size limit. This could happen when [the `where` clause](/orm/reference/prisma-client-reference#where) in the query is incorrect or entirely missing.
**Suggested solution:** Configure the query response size limit to be larger. If the limit is still exceeded, double-check that the `where` clause is filtering data as expected. To prevent fetching too many records, consider using [pagination](/v6/orm/prisma-client/queries/pagination). Additionally, use the [`select`](/orm/reference/prisma-client-reference#select) clause to return only the necessary fields, reducing the response size.
Fetching a large volume of data [#fetching-a-large-volume-of-data]
In many data processing workflows, especially those involving ETL (Extract-Transform-Load) processes or scheduled CRON jobs, there's a need to extract large amounts of data from data sources (like databases, APIs, or file systems) for analysis, reporting, or further processing. If you are running an ETL/CRON workload that fetches a huge chunk of data for analytical processing then you might run into this limit.
**Suggested solution:** Configure the query response size limit to be larger. If the limit is exceeded, consider splitting your query into batches. This approach ensures that each batch fetches only a portion of the data, preventing you from exceeding the size limit for a single operation.
P6004 (QueryTimeout) [#p6004-querytimeout]
This error occurs when a database query fails to return a response within the configured query timeout limit. The query timeout limit includes the duration of waiting for a connection from the pool, network latency to the database, and the execution time of the query itself. We enforce this limit to prevent unintentional long-running queries that can overload system resources.
The time for Prisma Postgres's cross-region networking is excluded from the configured query timeout limit.
Possible causes for P6004 [#possible-causes-for-p6004]
This error could be caused by numerous reasons. Some of the prominent ones are:
High traffic and insufficient connections [#high-traffic-and-insufficient-connections]
If the application is receiving very high traffic and there are not a sufficient number of connections available to the database, then the queries would need to wait for a connection to become available. This situation can lead to queries waiting longer than the configured query timeout limit for a connection, ultimately triggering a timeout error if they do not get serviced within this duration.
**Suggested solution**: Review and possibly increase the `connection_limit` specified in the connection string parameter when setting up Accelerate in a platform environment. This limit should align with your database's maximum number of connections.
By default, the connection limit is set to 10 unless a different `connection_limit` is specified in your database connection string.
Long-running queries [#long-running-queries]
Queries may be slow to respond, hitting the configured query timeout limit even when connections are available. This could happen if a very large amount of data is being fetched in a single query or if appropriate indexes are missing from the table.
**Suggested solution**: Configure the query timeout limit to be larger. If the limit is exceeded, identify the slow-running queries and fetch only the necessary data. Use the `select` clause to retrieve specific fields and avoid fetching unnecessary data. Additionally, consider adding appropriate indexes to improve query efficiency. You might also isolate long-running queries into separate environments to prevent them from affecting transactional queries.
Database resource contention [#database-resource-contention]
A common yet challenging issue is when other services operating on the same database perform heavy analytics or data processing tasks, significantly consuming database resources. These operations can monopolize database connections and processing power, leading to a scenario where even simple queries cannot be executed in a timely manner. This "busy" or "noisy" database environment can cause queries that are typically fast to run slowly or even timeout, particularly during periods of high activity from other services.
Users often rely on CPU and memory usage metrics to gauge database load, which can be misleading. While these are important indicators, they might not fully represent the database's operational state. Direct metrics like the number of reads, writes, and wait times offer a clearer view of the database's performance and should be monitored closely. A noticeable degradation in these metrics, especially in the absence of changes to the queries or data model, suggests that external pressures are affecting database performance.
**Suggested solution**: If normally quick queries are intermittently slow or timing out without any modifications to them, it's probable that competing queries are exerting pressure on the same database tables. To diagnose this, adopt monitoring tools or leverage your database's inherent capabilities to observe reads, writes, and wait times. Such monitoring will unveil activity patterns or spikes that align with the observed performance dips.
Moreover, it's crucial to periodically scrutinize and refine essential queries and verify that tables are properly indexed. This proactive approach minimizes the vulnerability of these queries to slowdowns caused by competing workloads.
P6008 (ConnectionError|EngineStartError) [#p6008-connectionerrorenginestarterror]
This error indicates that Prisma ORM cannot establish a connection to your Prisma Postgres database, potentially due to several reasons.
Possible causes for P6008 [#possible-causes-for-p6008]
Unreachable Database Host/Port [#unreachable-database-hostport]
If the database's server address (hostname) and port are incorrect or unreachable then you may encounter this error.
**Suggested solution:** Verify the hostname/port of the database connection string that was provided while creating the project. Additionally, attempt to connect to the database using a Database GUI tool (e.g., [Prisma Studio](https://www.prisma.io/studio), [TablePlus](https://tableplus.com/), or [DataGrip](https://www.jetbrains.com/datagrip/)) for further investigation.
Incorrect username/password/database name [#incorrect-usernamepassworddatabase-name]
This error can happen when the wrong credentials are provided, preventing it from establishing a connection to your database.
**Suggested solution:** Verify the correctness of your database's username, password, and name in the connection string provided to Prisma Postgres. Ensure that these credentials match those required by your database. Testing the connection using a direct database GUI tool can also help in confirming if the provided credentials are correct.
P5011 (TooManyRequests) [#p5011-toomanyrequests]
This error occurs when Prisma Postgres detects a high volume of requests that surpasses allowable thresholds. It acts as a protective measure to safeguard both Prisma Postgres and your underlying database from excessive load.
Possible causes for P5011 [#possible-causes-for-p5011]
Aggressive retry loops [#aggressive-retry-loops]
If your application retries queries immediately or with minimal delay, especially after receiving certain errors, the rapid accumulation of requests can surpass the threshold.
**Suggested solution:**
* Implement an exponential backoff strategy. Rather than retrying immediately or with a fixed delay, gradually increase the delay period after each failed attempt.
Sudden traffic spikes [#sudden-traffic-spikes]
Unpredicted traffic surges (for example, during product launches, flash sales, or viral growth events) can cause the threshold to be met and result into `P5011`.
**Suggested solution:**
* Monitor traffic and resource usage. If you anticipate a surge, please contact [support](/console/more/support) for capacity planning and potential configuration adjustments.
Prolonged or planned high workloads [#prolonged-or-planned-high-workloads]
Certain processes, such as bulk data imports, ETL operations, or extended CRON jobs, can generate continuous high query volume over time.
**Suggested solution:**
* Use batching or chunking techniques to break large operations into smaller parts.
* Establish throttling or scheduling to distribute the load more evenly.
# Prisma Postgres FAQ (/docs/postgres/faq)
Common questions about how Prisma Postgres works, how queries are billed, and how it integrates with the Prisma ORM.
General [#general]
Can I use Prisma Postgres without Prisma ORM? [#can-i-use-prisma-postgres-without-prisma-orm]
Yes, you can use Prisma Postgres with any database library or tool via a [direct connection](/postgres/database/connection-pooling).
You can find examples of using Prisma Postgres with various ORMs below:
* [Prisma ORM](https://github.com/prisma/prisma-examples/tree/latest/databases/prisma-postgres)
* [Drizzle](https://github.com/prisma/prisma-examples/tree/latest/databases/drizzle-prisma-postgres)
* [Kysely](https://github.com/prisma/prisma-examples/tree/latest/databases/kysely-prisma-postgres)
* [TypeORM](https://github.com/prisma/prisma-examples/tree/latest/databases/typeorm-prisma-postgres)
How do I switch from GitHub login to email and password login? [#how-do-i-switch-from-github-login-to-email-and-password-login]
If you previously signed up using GitHub and want to switch to email and password login, follow these steps:
1. Verify Your GitHub Email Address
* Check the primary email address associated with your GitHub account (e.g., from your GitHub profile or notification settings).
2. Create a New Email/Password Account
* Go to the email/password sign-up page.
* Use the *same email address* linked to your GitHub account to create the new account.
* Our system will automatically connect your new email/password account to your existing data.
3. Test Your Login
* Log out and try logging in with your email and the password you just created.
If you encounter any issues, please contact our support team for help linking your accounts.
VS Code does not recognize the $extends method [#vs-code-does-not-recognize-the-extends-method]
If you add the Prisma Client extension for Accelerate to an existing project that is currently open in VS Code, the editor might not immediately recognize the `$extends` method.
This might be an issue with the TypeScript server not yet recognizing the regenerated Prisma Client. To resolve this, you need to restart TypeScript.
1. In VS Code, open the Command Palette. You can do so when you press F1 or select **View** > **Command Palette**.
2. Enter `typescript` and select and run the **TypeScript: Restart TS server** command.
VS Code should now recognize the `$extends` method.
What regions is Prisma Postgres available in? [#what-regions-is-prisma-postgres-available-in]
Prisma Postgres is currently available in the following regions:
| Region Code | Location |
| ---------------- | -------------- |
| `us-west-1` | San Francisco |
| `us-east-1` | North Virginia |
| `eu-west-3` | Paris |
| `eu-central-1` | Frankfurt |
| `ap-northeast-1` | Tokyo |
| `ap-southeast-1` | Singapore |
We're continuously working to expand regional support. If you'd like to request a specific region, reach out to us via [Discord](https://pris.ly/discord).
Pricing [#pricing]
Prisma Postgres bills based on *operations* and *storage* consumed. Visit the [pricing page](https://www.prisma.io/pricing) for details and our [blog post explaining operations-based billing](https://www.prisma.io/blog/operations-based-billing) for a detailed explanation on what an operation is and how this pricing model works.
What is an operation? [#what-is-an-operation]
An operation is counted each time you interact with your database. Read, write, simple or complex. It all simply counts as one.
An operation can be:
* a Prisma ORM query (when using Prisma ORM)
* a SQL query (when using a [direct connection](/postgres/database/connecting-to-your-database))
Does query execution time affect pricing in Prisma Postgres? [#does-query-execution-time-affect-pricing-in-prisma-postgres]
No, cost for Prisma Postgres is based solely on the *number of operations*, not the amount of compute required to execute them.
Whether a query takes 10ms or 10sec to execute, its pricing impact remains the same.
How does pricing differ between using Prisma ORM and direct TCP connections? [#how-does-pricing-differ-between-using-prisma-orm-and-direct-tcp-connections]
The fundamental principle of operations-based pricing remains the same for Prisma ORM and [direct connections](/postgres/database/connecting-to-your-database). However, depending on whether you use Prisma ORM or direct SQL to interact with your database, an operation is something different:
* when using Prisma ORM: a query sent with Prisma Client (e.g. `prisma.user.findMany()`)
* when using another tool: a SQL query sent via the direct connection (e.g. `SELECT * from "User"`)
Note that a single Prisma ORM query may translate into multiple SQL queries which may make using Prisma ORM more economical than direct SQL.
Do read and write queries cost the same? [#do-read-and-write-queries-cost-the-same]
Yes, read and write queries are counted equally as *operations* and are billed the same way.
Does a SELECT 1 query count as a billable operation? [#does-a-select-1-query-count-as-a-billable-operation]
Yes, a query like `SELECT 1` counts as an operation and will be billed accordingly (even if no actual data is accessed in the query).
How can I estimate the number of operations in Prisma ORM? [#how-can-i-estimate-the-number-of-operations-in-prisma-orm]
You can estimate your operation usage in Prisma ORM by integrating an application performance monitoring tool like Prometheus.
What strategies can I use to optimize cost per operation? [#what-strategies-can-i-use-to-optimize-cost-per-operation]
Prisma Postgres bills by operation. The more you can perform using a single operation, the lower your bill. Some tips to reduce the number of operations:
* [**Batch your writes**](/orm/prisma-client/queries/transactions#bulk-operations) with `createMany`, `updateMany`, or `deleteMany` instead of looping over single-row calls.
```ts
// One operation, three users
await prisma.user.createMany({
data: [{ name: "Alice" }, { name: "Bob" }, { name: "Carol" }],
});
```
* **Use nested-relation helpers** such as [`connectOrCreate`](/orm/reference/prisma-client-reference#connectorcreate) or [`set`](/orm/reference/prisma-client-reference#set) to create or link related records in a single operation.
```ts
// Post and (if needed) its author, all in one request
await prisma.post.create({
data: {
title: "Hello World",
author: {
connectOrCreate: {
where: { email: "alice@example.com" },
create: { name: "Alice", email: "alice@example.com" },
},
},
},
});
```
* **Prefer regular (array) [transactions](/orm/prisma-client/queries/transactions#transaction-api) over [interactive transactions](/orm/prisma-client/queries/transactions#interactive-transactions)** when the individual queries don't depend on each other.
```ts
// Interactive transaction: counted as 2 operations
await prisma.$transaction(async (tx) => {
await tx.user.create({ data: { name: "Alice" } });
await tx.post.create({ data: { title: "Hello", authorId: 1 } });
});
// Array transaction: counted as 1 operation
await prisma.$transaction([
prisma.user.create({ data: { name: "Alice" } }),
prisma.post.create({ data: { title: "Hello", authorId: 1 } }),
]);
```
If a later query needs the result of an earlier one (for example, you need the user ID you just created), stick with an interactive transaction for correctness. Otherwise, batching and array transactions let you collapse multiple queries into a single billed operation, keeping both your operation count, and your cost down.
Is there a sample workload to estimate my expected charges? [#is-there-a-sample-workload-to-estimate-my-expected-charges]
We will demonstrate three example workloads and estimate bills for small, medium, and large workloads. Each combine a realistic number of monthly active users (MAUs), a typical level of daily activity per user, and a rounded storage footprint.
We will use the following equations to estimate the monthly bill:
```
total_ops = MAUs x actions_per_user_per_day x 30
billable_ops = total_ops - included_ops_for_plan
ops_cost = (billable_ops ÷ 1_000_000) x plan_rate
billable_storage_GB = storage_used_GB - free_storage_for_plan
storage_cost = billable_storage_GB x storage_rate_for_plan
total_monthly_cost = ops_cost + storage_cost + base_plan_fee
```
You can use your own MAU count, activity level, and storage used to project costs on any plan using the equations above.
We will associate each workload with a paid plan and its corresponding pricing details, for example, the **Starter plan** for the small workload, the **Pro plan** for the medium workload, and the **Business plan** for the large workload. Then we will apply the equations to the example workloads to generate a rough estimate of a monthly bill. For example:
Pricing details
Here are the details for each pricing plan:
* **Starter plan** - $8 per million operations
* Base plan fee - $10 per month
* Included operations - 1,000,000
* Storage - 10 GB free then $2 per additional GB
* **Pro plan** - $2 per million operations
* Base plan fee - $49.00 per month
* Included operations - 10,000,000
* Storage - 50 GB free then $1.5 per additional GB
* **Business plan** - $1 per million operations
* Base plan fee - $129.00 per month
* Included operations - 50,000,000
* Storage - 100 GB free then $1 per additional GB
We also have a Free plan, but we are leaving it out in the following calculations because it's intended for evaluation only and is not meant for production workloads. You can also learn more about the pricing details for each plan on the [pricing page](https://www.prisma.io/pricing?utm_source=docs).
**Example of a small workload on the Starter plan**:
A hobby or early-stage side-project with \~`500` MAUs. Each user performs \~`10` actions per day, and the entire database uses \~`0.5` GB of storage. Based on the assumptions, you would calculate the monthly bill using the following equations:
* `total_ops` = `500` x `10` x `30` = `150000`
* `billable_ops` = `0` (150,000 operations is below the 1 million free operations)
* `ops_cost` = $`0`
* `storage_cost` = $`0` (0.5 GB is below the 10 GB storage already included)
* `base_plan_fee` = $`10`
`total_monthly_cost` = $`10.00` per month
**Example of a medium workload on the Pro plan**:
A growing SaaS product serving \~`5000` MAUs. Power users average \~`40` actions per day, and the app stores \~`6` GB of data. Based on the assumptions, you would calculate the monthly bill using the following equations:
* `total_ops` = `5000` x `40` x `30` = `6000000`
* `billable_ops` = `0` (6 million operations is below the 10 million free operations)
* `ops_cost` = $`0`
* `storage_cost` = $`0` (6 GB is below the 50 GB storage already included)
* `base_plan_fee` = $`49.00`
`total_monthly_cost` = $`49.00` per month
**Example of a large workload on the Business plan**:
A production-grade, consumer-facing application handling \~`50000` MAUs. Heavy usage with \~`60` actions per user per day drives significant traffic, and the dataset reaches \~`40` GB. Based on the assumptions, you would calculate the monthly bill using the following equations:
* `total_ops` = `50000` x `60` x `30` = `90000000`
* `billable_ops` = `90000000` - `50000000` = `40000000`
* `ops_cost` = (`40000000` ÷ `1000000`) = `40.00` x $`1` = $`40.00`
* `storage_cost` = $`0.00` (40 GB is below the 100 GB storage already included)
* `base_plan_fee` = $`129.00`
`total_monthly_cost` = $`40.00` + $`129.00` = $`169.00` per month
Are cached operations billed the same? [#are-cached-operations-billed-the-same]
Every request, whether it hits the database or is served from cache, counts as an operation. Prisma Postgres use a flat per-operation price and never charge for egress traffic, so a cached response doesn't incur any extra or reduced fee. This unified rate keeps the billing model predictable and avoids per-request complexity.
How do I upgrade my plan if I am using Prisma Postgres via Vercel? [#how-do-i-upgrade-my-plan-if-i-am-using-prisma-postgres-via-vercel]
To upgrade your plan via Vercel, follow these steps:
* Open your [Vercel](https://vercel.com/) Dashboard.
* Go to the **Integrations** tab in your Vercel Team.
* Click **Manage** on the Prisma Integration.
* Navigate to the **Settings** tab.
* Under Current Installation Plan Level, click **Change Plan**.
* Select the plan you want to upgrade to.
Caching [#caching]
Prisma Postgres includes built-in connection pooling and global caching. These features improve performance by optimizing how your queries are routed and cached.
How does Prisma Postgres's cache layer know what region to fetch the cache from? [#how-does-prisma-postgress-cache-layer-know-what-region-to-fetch-the-cache-from]
Under the hood, Prisma Postgres's cache layer uses Cloudflare, which uses [Anycast](https://www.cloudflare.com/learning/cdn/glossary/anycast-network/) for network addressing and routing. An incoming request will be routed to the nearest data center or "node" in their network that has the capacity to process the request efficiently. To learn more about how this works, we recommend looking into [Anycast](https://www.cloudflare.com/learning/cdn/glossary/anycast-network/).
How can I invalidate a cache for Prisma Postgres? [#how-can-i-invalidate-a-cache-for-prisma-postgres]
You can invalidate the cache on-demand via the [`$accelerate.invalidate` API](/accelerate/reference/api-reference#accelerateinvalidate) if you're on a [paid plan](https://www.prisma.io/pricing#accelerate), or you can invalidate your entire cache, on a project level, a maximum of five times a day. This limit is set based on [your plan](https://www.prisma.io/pricing). You can manage this via the Accelerate configuration page.
How is Prisma Postgres's caching layer different from other caching tools, such as Redis? [#how-is-prisma-postgress-caching-layer-different-from-other-caching-tools-such-as-redis]
The caching layer of Prisma Postgres:
* Is a *specialized* cache that allows you to optimize data access in code at the query level with a cache strategy. On the other hand, tools such as Redis and Memcached are *general-purpose* caches designed to be adaptable and flexible.
* Is a managed service that reduces the time, risk, and engineering effort of building and maintaining a cache service.
* Is globally distributed, by default, reducing the latency of your queries. Other cache tools would require additional configuration to make them available globally.
When should I not use Prisma Postgres's caching features? [#when-should-i-not-use-prisma-postgress-caching-features]
The caching layer of Prisma Postgres is a global data cache and connection pool that allows you to optimize data access in code at the query level. While caching with Prisma Postgres can greatly boost the performance of your app, it may not always the best choice for your use case.
This global cache feature may not be a good fit for your app if:
* Your app is exclusively used within a specific region and both your application server and database are situated in that same region on the same network. For example, database queries will likely be much faster if your application server and database are in the same region and network. However, If your application server is in different regions or networks from your database, the cache nodes will speed up your queries because the data will be cached in the closest data center to your application.
* Your application data *always* needs to be up-to-date on retrieval, making it difficult to establish a reasonable cache strategy.
What is the maximum allowed value for the ttl parameter when configuring cacheStrategy? [#what-is-the-maximum-allowed-value-for-the-ttl-parameter-when-configuring-cachestrategy]
The [Time-to-live](/accelerate/caching) (`ttl`) parameter can be set for up to a *year*. However, it's important to note that items within the cache may be evicted if they are not frequently accessed.
Based on our experimentation, we’ve seen cache items persist for around 18 hours. While items may remain in the cache for an extended period if they are actively accessed, there is no guarantee.
Even frequently accessed items may occasionally be evicted from the cache. It's unlikely for an item to survive for up to or longer than a month, regardless of its activity level.
Why do I sometimes see unexpected cache behavior? [#why-do-i-sometimes-see-unexpected-cache-behavior]
Prisma Postgres's cache layer performs best when it observes a higher load from a project. Many cache operations, such as committing data to cache and refreshing stale data, happen asynchronously. When benchmarking the cache layer, we recommend doing so with loops or a load testing approach. This will mimic higher load scenarios better and reduce outliers from low frequency operations.
Prisma operations are sent to Prisma Postgres over HTTP. As a result, the first request to Prisma Postgres must establish an HTTP handshake and may have additional latency as a result. We're exploring ways to reduce this initial request latency in the future.
What regions are Prisma Postgres's cache nodes available in? [#what-regions-are-prisma-postgress-cache-nodes-available-in]
Prisma Postgres's cache layer runs on Cloudflare's network and cache hits are served from Cloudflare's 300+ locations. You can find the regions where Prisma Postgres's cache nodes are available here: [https://www.cloudflare.com/network/](https://www.cloudflare.com/network/).
How long does it take to invalidate a cache query result? [#how-long-does-it-take-to-invalidate-a-cache-query-result]
As the cache needs to be cleared globally, it is difficult to provide a specific time frame. However, the cached data is eventually consistent and typically propagates to all PoPs within a few seconds. In very rare cases, it may take longer.
Here is a [demo app](https://pris.ly/test-cache-invalidation) to test the time it takes to invalidate a cache query result.
What is the difference between Invalidate and Revalidate? [#what-is-the-difference-between-invalidate-and-revalidate]
**Invalidate**: The cache entry is deleted, and new data will be fetched on the next request, causing a cache miss. This removes stale data but may lead to slower responses until the cache is repopulated.
**Revalidate**: The cache entry is updated proactively, ensuring the next request uses fresh data from the cache. This keeps the cache valid and maintains faster response times by avoiding cache misses.
What is on-demand cache invalidation? [#what-is-on-demand-cache-invalidation]
[On-demand cache invalidation](/accelerate/caching) lets applications instantly update specific cached data when it changes, instead of waiting for regular cache refresh cycles. This keeps information accurate and up-to-date for users.
When should I use the cache invalidate API? [#when-should-i-use-the-cache-invalidate-api]
The [cache invalidate API](/accelerate/caching) is essential when data consistency cannot wait for the cache’s standard expiration or revalidation. Key use cases include:
* **Content updates**: When critical changes occur, such as edits to a published article, product updates, or profile modifications, that need to be visible immediately.
* **Inventory management**: In real-time applications, like inventory or booking systems, where stock levels, availability, or reservation statuses must reflect the latest information.
* **High-priority data**: For time-sensitive data, like breaking news or urgent notifications, where it’s essential for users to see the most current information right away.
Using on-demand cache invalidation in these scenarios helps keep only the necessary data refreshed, preserving system performance while ensuring accurate, up-to-date information for users.
Connection pooling [#connection-pooling]
Can I increase the query duration and response size limits for my Prisma Postgres instance? [#can-i-increase-the-query-duration-and-response-size-limits-for-my-prisma-postgres-instance]
Yes, you can increase your Prisma Postgres limits based on your subscription plan. Here are the configurable limits:
| Limit | Free | Starter | Pro Plan | Business Plan |
| ------------------------------------ | ---------------- | ---------------- | ---------------- | ---------------- |
| **Query timeout** | Up to 10 seconds | Up to 10 seconds | Up to 20 seconds | Up to 60 seconds |
| **Interactive transactions timeout** | Up to 15 seconds | Up to 15 seconds | Up to 30 seconds | Up to 90 seconds |
| **Response size** | Up to 5 MB | Up to 5 MB | Up to 10 MB | Up to 20 MB |
Check the [pricing page](https://www.prisma.io/pricing) for more details on the available plans and their corresponding limits.
While you can increase these limits based on your subscription plan, it's *still* recommended to optimize your database operations. [Learn more in our troubleshooting guide.](/postgres/error-reference)
Query Insights [#query-insights]
[Query Insights](/query-insights) is built into Prisma Postgres and helps you identify slow queries, understand their cost, and decide what to fix.
I only see raw SQL — how do I see my Prisma ORM queries? [#i-only-see-raw-sql--how-do-i-see-my-prisma-orm-queries]
By default, Query Insights shows raw SQL. To also see the Prisma ORM operation that generated each query (model name, action, and query shape), install the `@prisma/sqlcommenter-query-insights` package:
```bash
npm install @prisma/sqlcommenter-query-insights
```
Then pass it to the `comments` option in your `PrismaClient` constructor:
```ts
import { prismaQueryInsights } from "@prisma/sqlcommenter-query-insights";
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient({
adapter: myAdapter,
comments: [prismaQueryInsights()],
});
```
This annotates every query with a SQL comment containing the model, action, and parameterized query shape. Query Insights uses these annotations to map SQL back to the Prisma call that generated it.
Let your AI agent handle setup [#let-your-ai-agent-handle-setup]
Copy this prompt into your AI coding assistant:
```
Install and configure @prisma/sqlcommenter-query-insights in my project so I can
see Prisma ORM queries in Query Insights. Docs: https://www.prisma.io/docs/query-insights
```
Does Query Insights alter my queries or schema? [#does-query-insights-alter-my-queries-or-schema]
No. Query Insights is read-only — it observes query behavior but does not rewrite queries or modify your Prisma schema.
Can I use Query Insights in production? [#can-i-use-query-insights-in-production]
Query Insights is designed primarily for development and debugging. Running it in production is possible but not recommended, as the SQL comment annotations add a small overhead to every query.
# Prisma Postgres (/docs/postgres)
[Prisma Postgres](https://www.prisma.io/postgres?utm_source=docs) is a managed PostgreSQL service built for modern app development.
Use this page to choose a connection path and get started quickly.
Getting started [#getting-started]
Create a database [#create-a-database]
New to Prisma Postgres? Start here.
Create a temporary Prisma Postgres database in one command.
Set up Prisma ORM and connect it to Prisma Postgres.
Get your connection string [#get-your-connection-string]
In [Prisma Console](https://console.prisma.io), open your database and click **Connect to your database** to copy connection URLs.
Choose a connection type [#choose-a-connection-type]
Prisma ORM (recommended default) [#prisma-orm-recommended-default]
Use Prisma ORM for migrations and type-safe queries.
Get started with the recommended Prisma ORM workflow.
Any PostgreSQL client or ORM [#any-postgresql-client-or-orm]
Use Prisma Postgres with `psql`, GUI tools, `node-postgres`, or other ORMs.
Connect Prisma Postgres from Kysely.
Connect Prisma Postgres from Drizzle ORM.
Connect Prisma Postgres from TypeORM.
Choose the right connection string for Prisma ORM, PostgreSQL tools, and serverless runtimes.
Serverless and edge runtimes [#serverless-and-edge-runtimes]
Use the serverless driver for HTTP/WebSocket connectivity in edge or constrained runtimes.
* [Serverless driver (`@prisma/ppg`)](/postgres/database/serverless-driver)
Local development [#local-development]
Run Prisma Postgres locally with `prisma dev`, then switch to cloud when ready.
* [Local development](/postgres/database/local-development)
Optimize and manage [#optimize-and-manage]
* [Connecting to your database](/postgres/database/connecting-to-your-database)
* [Connection pooling](/postgres/database/connection-pooling)
* [Caching](/accelerate/caching)
* [Backups](/postgres/database/backups)
* [PostgreSQL extensions](/postgres/database/postgres-extensions)
* [Troubleshooting](/postgres/troubleshooting)
* [FAQ](/postgres/faq)
Billing and limits [#billing-and-limits]
Prisma Postgres uses usage-based pricing and includes spend controls.
* [Pricing](https://www.prisma.io/pricing)
* [Operations-based billing explained](https://www.prisma.io/blog/operations-based-billing?utm_source=docs)
* [FAQ: estimating costs](/postgres/faq#is-there-a-sample-workload-to-estimate-my-expected-charges)
In Prisma Console, you can track usage, set spend limits, and view billing details.
Technical details [#technical-details]
Prisma Postgres is based on **PostgreSQL v17** and uses a unikernel-based architecture.
Learn more: [Prisma Postgres: Building a modern PostgreSQL service](https://pris.ly/ppg-early-access?utm_source=docs).
Note
Postgres, PostgreSQL, and the Slonik Logo are trademarks or registered trademarks of the PostgreSQL Community Association of Canada and are used with permission.
# create-db (/docs/postgres/npx-create-db)
[`create-db`](https://create-db.prisma.io/) is an open-source CLI tool that provisions temporary [Prisma Postgres](/postgres) databases with a single command.
* **Fast setup:** No sign-up required to create a temporary production-ready Prisma Postgres database.
* **Lifetime:** Each database is available for *24 hours* by default.
* **Keep for free:** You can *claim* a database (via the URL provided in the CLI output) to make it permanent.
Prerequisites [#prerequisites]
To use `npx create-db`, you need:
* **Node.js** version `16` or higher (we recommend the latest LTS version).
* **npm** (comes with Node.js) to run `npx` commands.
**A Prisma Data Platform account is not required** to create a temporary database. However, if you want to keep a database permanently, you can claim it ([details below](#claiming-your-database)).
Option 1: Using the web interface (recommended) [#option-1-using-the-web-interface-recommended]
The [create-db web application](https://create-db.prisma.io) provides a browser-based interface for creating and managing your databases.
Key features: [#key-features]
* No installation required - works directly in your web browser
* Visual interface for database management
* Easy connection string display and copying
* Built-in schema viewer and editor
* Direct integration with Prisma Studio
* Simple database claiming workflow
Getting started: [#getting-started]
1. Visit [create-db.prisma.io](https://create-db.prisma.io) in your web browser
2. Click "Create with the web interface"
3. Modify your schema and interact with the Studio
4. Copy the provided connection strings for your project
5. Claim your database to make it permanent
Option 2: Using the CLI [#option-2-using-the-cli]
You can create a database using one of the following options:
Option 1: Quick start with default settings [#option-1-quick-start-with-default-settings]
Run the following command in your terminal:
npm
pnpm
yarn
bun
```bash
npx create-db@latest
```
```bash
pnpm dlx create-db@latest
```
```bash
yarn dlx create-db@latest
```
```bash
bunx --bun create-db@latest
```
* The `@latest` tag automatically downloads and runs the latest version of the tool, hence, no global installation required.
* After a few seconds, you'll receive **connection strings** for both Prisma ORM projects and standard PostgreSQL.
* The default region is `us-east-1`. You can specify the region where you want to provision the database in using the `--region` flag. See [the section below](#available-cli-options) to view all the CLI options.
Option 2: Choose a region interactively [#option-2-choose-a-region-interactively]
If you want to select a region manually:
npm
pnpm
yarn
bun
```bash
npx create-db@latest --interactive
```
```bash
pnpm dlx create-db@latest --interactive
```
```bash
yarn dlx create-db@latest --interactive
```
```bash
bunx --bun create-db@latest --interactive
```
* This opens a region selection menu (for example, `us-east-1`, `eu-west-3`).
* Alternatively, you can use the shorthand `-i`:
npm
pnpm
yarn
bun
```bash
npx create-db@latest -i
```
```bash
pnpm dlx create-db@latest -i
```
```bash
yarn dlx create-db@latest -i
```
```bash
bunx --bun create-db@latest -i
```
To view all options and regions:
npm
pnpm
yarn
bun
```bash
npx create-db@latest --help
```
```bash
pnpm dlx create-db@latest --help
```
```bash
yarn dlx create-db@latest --help
```
```bash
bunx --bun create-db@latest --help
```
CLI output walkthrough [#cli-output-walkthrough]
Here is an example output:
```
┌ 🚀 Creating a Prisma Postgres database
│
│ Provisioning a temporary database in us-east-1...
│ It will be automatically deleted in 24 hours, but you can claim it.
◇ Database created successfully!
│
● Database Connection
│ Connection String:
│ postgresql://:@db.prisma.io:5432/postgres
│
◆ Claim your database →
│ Keep your database for free:
│ https://create-db.prisma.io?projectID=proj_...
└
```
Once you have the output, take the connection string and add it to your `.env` file as `DATABASE_URL`:
```text
DATABASE_URL="postgresql://:@db.prisma.io:5432/postgres"
```
You can now follow the [Prisma Postgres quickstart guide](/prisma-orm/quickstart/prisma-postgres) to connect your Prisma project to this database.
If you're using other tools or libraries, use the standard PostgreSQL connection string with any PostgreSQL-compatible client, such as `psql`, `pgAdmin`, `node-postgres`, or an ORM of your choice. Detailed instructions are available in [Connecting to your database](/postgres/database/connecting-to-your-database).
Claiming your database [#claiming-your-database]
By default, databases created with `npx create-db` are **temporary** and will be automatically deleted after **24 hours**.
You can prevent this by **claiming the database** using the claim URL shown in the CLI output:
```
◆ Claim your database →
│
│ Want to keep your database? Claim for free:
│
│ https://create-db.prisma.io?projectID=proj_...
│
│ Your database will be deleted on 7/24/2025, 2:25:41 AM if not claimed.
```
To claim your database and make it permanent:
1. Copy the **claim URL** from the CLI output.
2. Open it in your browser and click **Claim database**.
3. Sign in to your [Prisma Data Platform account](https://console.prisma.io/) (or create one if you don’t have it yet).
4. Choose a **Workspace** that has capacity for creating new projects.
5. Click **Authorize Prisma Create DB** to confirm.
6. You’ll be redirected to a success page. Then, click **Go use your database** to view and manage the claimed database in your workspace.
When you claim a database:
* It's moved into your Prisma Data Platform account workspace.
* It's no longer auto-deleted after 24 hours.
* You can continue using it as a permanent database instance.
Available CLI options [#available-cli-options]
Here are the CLI flags for the `npx create-db` command:
| Flag | Shorthand | Description |
| --------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `--region` | `-r` | Specify a region. **Available regions:** `ap-southeast-1`, `ap-northeast-1`, `eu-central-1`, `eu-west-3`, `us-east-1`, `us-west-1` |
| `--interactive` | `-i` | Run in interactive mode (select region from a list). |
| `--json` | `-j` | Output machine-readable JSON and exit. |
| `--help` | `-h` | Show this help message. |
To view all CLI options use the `--help` or `-h` flag:
npm
pnpm
yarn
bun
```bash
npx create-db@latest --help
```
```bash
pnpm dlx create-db@latest --help
```
```bash
yarn dlx create-db@latest --help
```
```bash
bunx --bun create-db@latest --help
```
```
npx create-db@latest [options]
Options:
--region , -r Specify a region
Available regions:
ap-southeast-1, ap-northeast-1,
eu-central-1, eu-west-3,
us-east-1, us-west-1
--interactive, -i Run in interactive mode
--help, -h Show this help message
```
# Troubleshooting (/docs/postgres/troubleshooting)
This guide helps resolve common issues when working with Prisma Postgres.
The --db option is not recognized when running prisma init [#the---db-option-is-not-recognized-when-running-prisma-init]
Problem [#problem]
Running the following command fails because the `--db` option is not recognized:
npm
pnpm
yarn
bun
```bash
npx prisma init --db
```
```bash
pnpm dlx prisma init --db
```
```bash
yarn dlx prisma init --db
```
```bash
bunx --bun prisma init --db
```
Cause [#cause]
This can occur due to npx caching. If you've previously run `npx prisma init`, your machine may be using an outdated cached version that doesn't recognize the `--db` flag because it was only introduced in a later version of Prisma ORM.
Solution [#solution]
Explicitly run the `latest` Prisma CLI version:
npm
pnpm
yarn
bun
```bash
npx prisma@latest init --db
```
```bash
pnpm dlx prisma@latest init --db
```
```bash
yarn dlx prisma@latest init --db
```
```bash
bunx --bun prisma@latest init --db
```
This ensures that you're using the most up-to-date CLI, preventing issues with outdated command syntax.
Workspace plan limit reached when running prisma init --db [#workspace-plan-limit-reached-when-running-prisma-init---db]
Problem [#problem-1]
When running the command:
npm
pnpm
yarn
bun
```bash
npx prisma@latest init --db
```
```bash
pnpm dlx prisma@latest init --db
```
```bash
yarn dlx prisma@latest init --db
```
```bash
bunx --bun prisma@latest init --db
```
You may encounter the following error message in your logs:
```
Workspace plan limit reached for feature "Project".
```
Cause [#cause-1]
Your default [workspace](/console/concepts#workspace) project limit has been reached.
Solution [#solution-1]
To resolve this issue, consider the following options:
* Configure a different Workspace as your default—one that has available capacity for additional projects.
* Delete unused projects or databases from your current default Workspace to free up space.
* Ensure that you are logged into the correct account in the Prisma CLI. For more details on authentication and account management, please refer to the [Prisma CLI documentation](/cli/console).
* [Upgrade to a plan](/postgres#billing-and-limits) that supports more projects in your default Workspace.
Implementing one or more of these solutions should help you overcome the plan limit issue.
# Query Insights (/docs/query-insights)
Query Insights is built into Prisma Postgres and helps you understand which queries are slow, why they are expensive, and what to change next. It does not automatically rewrite your queries or schema.
Query Insights replaces Prisma Optimize and is now included with Prisma Postgres at no extra cost. You can try it today in the [Prisma Console](https://console.prisma.io).
Dashboard [#dashboard]
The main Query Insights view gives you a live summary of query activity for your database.
At the top of the page, you can inspect:
* Average latency over the selected period
* Queries per second
* A time-based chart for each metric
* Hover values for exact timestamps and measurements
* Playback controls for stepping through captured activity
This makes it easier to see whether a problem is steady, bursty, or tied to a short window of activity.
Query list [#query-list]
Below the charts, Query Insights shows a list of grouped queries.
Each row includes:
* Latency
* Executions
* Reads
* Last seen
* The SQL statement shape
You can use the controls above the table to:
* Filter results by table
* Sort the list to surface the most important queries first
* Focus on repeated, high-read, or recently executed statements
This view is the fastest way to identify which query patterns deserve investigation first.
Query detail [#query-detail]
Selecting a query opens a detail view for that statement.
The detail view shows:
* A stat summary describing the query's table, execution count, average latency, and reads per call
* The full SQL statement
* An AI-generated analysis explaining whether the query needs optimization and why
* A copyable prompt you can paste directly into your editor or an AI coding assistant to apply the suggested fix
The AI analysis describes the likely cause of the performance issue, the specific change it recommends, and the expected impact. The copyable prompt includes your actual query along with context, so you can paste it into your editor or a tool like Cursor, Copilot, or Claude and get a concrete code change without switching context.
Treat the AI analysis as a starting point, not a final answer. Review any suggested change before shipping it.
Prisma ORM attribution [#prisma-orm-attribution]
When using Prisma ORM, Query Insights can trace the full chain from your application code to the SQL it generates. This means you can see which `prisma.*` call produced a slow query, even when a single Prisma call expands into multiple SQL statements.
For raw SQL or queries issued outside Prisma ORM, Query Insights still shows full SQL behavior, but ORM-level attribution requires the steps below.
Setup [#setup]
To enable ORM attribution, install the `@prisma/sqlcommenter-query-insights` package:
```bash
npm install @prisma/sqlcommenter-query-insights
```
Then pass it to the `comments` option in your `PrismaClient` constructor:
```ts
import "dotenv/config";
import { PrismaClient } from "../generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
import { prismaQueryInsights } from "@prisma/sqlcommenter-query-insights";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
export const prisma = new PrismaClient({
adapter: adapter,
comments: [prismaQueryInsights()],
})
```
This adds SQL comment annotations to queries so Query Insights can map SQL statements back to the Prisma calls that generated them. It is built on top of the [SQL comments](/orm/prisma-client/observability-and-logging/sql-comments) feature in Prisma Client.
Availability [#availability]
Query Insights is included with Prisma Postgres at no extra cost. You can try it today in the [Prisma Console](https://console.prisma.io).
Typical issues [#typical-issues]
Query Insights is most useful when it connects a database symptom to a concrete code change.
| Issue | What you might see | Typical fix |
| ------------------ | ------------------------------------ | ------------------------------------------- |
| N+1 queries | High query count for one request | Use nested reads, batching, or joins |
| Missing indexes | High reads relative to rows returned | Add the right index for the filter pattern |
| Over-fetching | Wide rows or large payloads | Use `select` to fetch fewer fields |
| Offset pagination | Reads grow on deeper pages | Switch to cursor pagination |
| Large nested reads | High reads and large payloads | Limit fields, limit depth, or split queries |
| Repeated queries | The same statement shape runs often | Cache or reuse results when appropriate |
How to use it [#how-to-use-it]
When an endpoint gets slow, Query Insights gives you a practical workflow:
1. Open Query Insights and scan the latency and queries-per-second charts.
2. Sort or filter the query list to isolate the expensive statement.
3. Open the query detail view.
4. Read the AI analysis and inspect the SQL.
5. Copy the suggested prompt and paste it into your editor.
6. Review the suggested change, then apply it in code or schema.
7. Re-run the workload and compare the same signals again.
In most cases, the next change falls into one of these buckets:
* Change the Prisma query shape
* Add or adjust an index
* Return fewer fields or fewer rows
* Cache repeated work
Example [#example]
A common example is an N+1 pattern:
```ts
const users = await prisma.user.findMany({
select: { id: true, name: true, email: true },
});
for (const user of users) {
await prisma.post.findMany({
where: { authorId: user.id },
select: { id: true, title: true },
});
}
```
Query Insights would typically show:
* One query to load users
* Many repeated queries to load posts
* A high execution count for the same statement shape
* More reads and latency than the route should need
In this case, the likely fix is to load the related posts in one nested read:
```ts
const usersWithPosts = await prisma.user.findMany({
select: {
id: true,
name: true,
email: true,
posts: {
select: {
id: true,
title: true,
},
},
},
});
```
The same pattern applies to other issues. Query Insights helps you identify the expensive query shape, understand why it is expensive, and choose the next change to verify.
Next steps [#next-steps]
* Review [Connection pooling](/postgres/database/connection-pooling) for high-concurrency workloads
* Use [Connecting to your database](/postgres/database/connecting-to-your-database) when choosing connection strings for other tools
* See [Prisma Client query optimization](/orm/prisma-client/queries/advanced/query-optimization-performance) for related Prisma ORM patterns
# Getting Started (/docs/studio/getting-started)
Installation [#installation]
Prisma Studio comes bundled with the Prisma CLI. To get started, make sure you have Node.js installed, then install the Prisma CLI:
npm
pnpm
yarn
bun
```bash
npm install -g prisma
```
```bash
pnpm add -g prisma
```
```bash
yarn global add prisma
```
```bash
bun add --global prisma
```
Launching Studio [#launching-studio]
With a Prisma Project [#with-a-prisma-project]
If you have an existing Prisma project, navigate to your project directory and run:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
This will start the Studio server and open it in your default browser at `http://localhost:5555`.
Without a Prisma Project [#without-a-prisma-project]
You can also use Studio with any database by providing a connection string:
npm
pnpm
yarn
bun
```bash
npx prisma studio --url="postgresql://user:password@localhost:5432/yourdb"
```
```bash
pnpm dlx prisma studio --url="postgresql://user:password@localhost:5432/yourdb"
```
```bash
yarn dlx prisma studio --url="postgresql://user:password@localhost:5432/yourdb"
```
```bash
bunx --bun prisma studio --url="postgresql://user:password@localhost:5432/yourdb"
```
Connecting to Your Database [#connecting-to-your-database]
1. **Using environment variables**:
Create a `.env` file in your project root with your database URL:
```
DATABASE_URL="postgresql://user:password@localhost:5432/yourdb"
```
Then run: `npx prisma studio`
2. **Using command line**:
```bash
npx prisma studio --url="your-database-connection-string"
```
Basic Usage [#basic-usage]
Browsing Data [#browsing-data]
* The left sidebar lists all your database tables
* Click on a table to view its data
* Use the search bar to quickly find tables or columns
Editing Data [#editing-data]
* **Edit cells**: Double-click any cell to edit its value
* **Add records**: Click the "+" button to add a new record
* **Delete records**: Select records using checkboxes and click the trash icon
Filtering and Sorting [#filtering-and-sorting]
* Click the filter icon to add filters
* Click on column headers to sort the table
* Use the search box to filter records by any field
Common Tasks [#common-tasks]
Viewing Table Relationships [#viewing-table-relationships]
* Related tables are shown as expandable rows
* Click the "+" icon to view related records
Exporting Data [#exporting-data]
* Use the export button to download data as CSV or JSON
* Select specific columns to include in the export
Next Steps [#next-steps]
* Learn how to [embed Studio in your application](/studio/integrations/embedding)
* Discover [VS Code integration](/studio/integrations/vscode-integration) features
# Prisma Studio (/docs/studio)
[Prisma Studio](https://www.prisma.io/studio) works with or without Prisma ORM and supports the following workflows:
* Viewing and editing data in a spreadsheet-like interface
* Real-time schema introspection
* Embedding directly into your Next.js applications
* VS Code integration for in-editor database management
Supported databases [#supported-databases]
* PostgreSQL
* MySQL
* SQLite
Quick start [#quick-start]
npm
pnpm
yarn
bun
```bash
# With Prisma project
npx prisma studio
# With direct database connection
npx prisma studio --url="postgresql://user:password@localhost:5432/dbname"
```
```bash
# With Prisma project
pnpm dlx prisma studio
# With direct database connection
pnpm dlx prisma studio --url="postgresql://user:password@localhost:5432/dbname"
```
```bash
# With Prisma project
yarn dlx prisma studio
# With direct database connection
yarn dlx prisma studio --url="postgresql://user:password@localhost:5432/dbname"
```
```bash
# With Prisma project
bun x prisma studio
# With direct database connection
bun x prisma studio --url="postgresql://user:password@localhost:5432/dbname"
```
Getting started [#getting-started]
* [Getting Started](/studio/getting-started) - Learn how to set up and use Prisma Studio to manage your database
* [Embed Studio](/studio/integrations/embedding) - Learn how to embed Prisma Studio in your own applications
* [Studio in VS Code](/studio/integrations/vscode-integration) - Learn how to use Prisma Studio directly in VS Code
# From the CLI (/docs/prisma-postgres/from-the-cli)
This page provides a step-by-step guide for Prisma Postgres after setting it up with `prisma init --db`:
1. Set up a TypeScript app with Prisma ORM
2. Migrate the schema of your database
3. Query your database from TypeScript
Prerequisites [#prerequisites]
This guide assumes you set up [Prisma Postgres](/postgres) instance with `prisma init --db`:
npm
pnpm
yarn
bun
```bash
npx prisma@latest init --db
```
```bash
pnpm dlx prisma@latest init --db
```
```bash
yarn dlx prisma@latest init --db
```
```bash
bunx --bun prisma@latest init --db
```
Once this command has terminated:
* You're logged into Prisma Data Platform.
* A new Prisma Postgres instance was created.
* The `prisma/` folder was created with an empty `schema.prisma` file.
* The `DATABASE_URL` env var was set in a `.env` file.
* The `prisma.config.ts` file was created with the default configuration.
1. Organize your project directory [#1-organize-your-project-directory]
If you ran the `prisma init --db` command inside a folder where you want your project to live, you can skip this step and [proceed to the next section](/prisma-postgres/from-the-cli#2-set-up-your-project).
If you ran the command outside your intended project directory (e.g., in your home folder or another location), you need to move the generated `prisma` folder and the `.env` file into a dedicated project directory.
Create a new folder (e.g. `hello-prisma`) where you want your project to live and move the necessary files into it:
```bash
mkdir hello-prisma
mv .env ./hello-prisma/
mv prisma ./hello-prisma/
```
Navigate into your project folder:
```bash
cd ./hello-prisma
```
Now that your project is in the correct location, continue with the setup.
2. Set up your project [#2-set-up-your-project]
2.1. Set up TypeScript [#21-set-up-typescript]
Initialize a TypeScript project and add the Prisma CLI as a development dependency:
npm
pnpm
yarn
bun
```bash
npm init -y
```
```bash
pnpm init -y
```
```bash
yarn init -y
```
```bash
bun init -y
```
npm
pnpm
yarn
bun
```bash
npm install typescript tsx @types/node @types/pg -D
```
```bash
pnpm add typescript tsx @types/node @types/pg -D
```
```bash
yarn add typescript tsx @types/node @types/pg --dev
```
```bash
bun add typescript tsx @types/node @types/pg --dev
```
This creates a `package.json` file with an initial setup for your TypeScript app.
Next, initialize TypeScript with a `tsconfig.json` file in the project:
npm
pnpm
yarn
bun
```bash
npx tsc --init
```
```bash
pnpm dlx tsc --init
```
```bash
yarn dlx tsc --init
```
```bash
bunx --bun tsc --init
```
2.2. Configure ESM support [#22-configure-esm-support]
Update `tsconfig.json` for ESM compatibility:
```json title="tsconfig.json"
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"target": "ES2023",
"strict": true,
"esModuleInterop": true,
"ignoreDeprecations": "6.0"
}
}
```
Update `package.json` to enable ESM:
```json title="package.json"
{
"type": "module" // [!code ++]
}
```
2.3. Set up Prisma ORM [#23-set-up-prisma-orm]
Install the required dependencies to use Prisma Postgres:
npm
pnpm
yarn
bun
```bash
npm install prisma --save-dev
npm install @prisma/client @prisma/adapter-pg pg dotenv
```
```bash
pnpm add prisma --save-dev
pnpm add @prisma/client @prisma/adapter-pg pg dotenv
```
```bash
yarn add prisma --dev
yarn add @prisma/client @prisma/adapter-pg pg dotenv
```
```bash
bun add prisma --dev
bun add @prisma/client @prisma/adapter-pg pg dotenv
```
Here's what each package does:
* **`prisma`** - The Prisma CLI for running commands like `prisma migrate` and `prisma generate`
* **`@prisma/client`** - The Prisma Client library for querying your database
* **`@prisma/adapter-pg`** - The [`node-postgres` driver adapter](/orm/core-concepts/supported-databases/postgresql#using-driver-adapters) that connects Prisma Client to your database
* **`pg`** - The node-postgres database driver
* **`@types/pg`** - TypeScript type definitions for node-postgres
* **`dotenv`** - Loads environment variables from your `.env` file
2.4. Review the generated prisma.config.ts [#24-review-the-generated-prismaconfigts]
The `prisma init --db` command automatically created a `prisma.config.ts` file that looks like this:
```typescript title="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"),
},
});
```
2.5. Create a script to query the database [#25-create-a-script-to-query-the-database]
Create an `index.ts` file in the root directory, this will be used to query your application with Prisma ORM:
```bash
touch index.ts
```
3. Migrate the database schema [#3-migrate-the-database-schema]
Update your `prisma/schema.prisma` file to include the `User` and `Post` models:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
```
After adding the models, migrate your database using [Prisma Migrate](/orm/prisma-migrate):
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
This command creates the database tables based on your schema.
Now run the following command to generate the Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
4. Send queries with Prisma ORM [#4-send-queries-with-prisma-orm]
4.1. Instantiate Prisma Client [#41-instantiate-prisma-client]
Create a `lib/prisma.ts` file to instantiate Prisma Client with the driver adapter:
```typescript title="lib/prisma.ts"
import "dotenv/config";
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "../generated/prisma/client";
const connectionString = `${process.env.DATABASE_URL}`;
const adapter = new PrismaPg({ connectionString });
const prisma = new PrismaClient({ adapter });
export { prisma };
```
If you need to query your database via HTTP from an edge runtime (Cloudflare Workers, Vercel Edge Functions, etc.), use the [Prisma Postgres serverless driver](/postgres/database/serverless-driver#use-with-prisma-orm).
4.2. Write your first query [#42-write-your-first-query]
Paste the following boilerplate into `index.ts`:
```ts title="index.ts"
import { prisma } from "./lib/prisma";
async function main() {
// ... you will write your Prisma ORM queries here
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
```
This code contains a `main` function that's invoked at the end of the script. It also instantiates `PrismaClient` which you'll use to send queries to your database.
4.3. Create a new User record [#43-create-a-new-user-record]
Let's start with a small query to create a new `User` record in the database and log the resulting object to the console. Add the following code to your `index.ts` file:
```ts title="index.ts"
import { prisma } from "./lib/prisma";
async function main() {
const user = await prisma.user.create({
// [!code ++]
data: {
// [!code ++]
name: "Alice", // [!code ++]
email: "alice@prisma.io", // [!code ++]
}, // [!code ++]
}); // [!code ++]
console.log(user); // [!code ++]
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
```
Next, execute the script with the following command:
npm
pnpm
yarn
bun
```bash
npx tsx index.ts
```
```bash
pnpm dlx tsx index.ts
```
```bash
yarn dlx tsx index.ts
```
```bash
bunx --bun tsx index.ts
```
```text no-copy
{ id: 1, email: 'alice@prisma.io', name: 'Alice' }
```
Great job, you just created your first database record with Prisma Postgres! 🎉
4.4. Retrieve all User records [#44-retrieve-all-user-records]
Prisma ORM offers various queries to read data from your database. In this section, you'll use the `findMany` query that returns *all* the records in the database for a given model.
Delete the previous Prisma ORM query and add the new `findMany` query instead:
```ts title="index.ts"
import { prisma } from "./lib/prisma";
async function main() {
const users = await prisma.user.findMany(); // [!code ++]
console.log(users); // [!code ++]
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
```
Execute the script again:
npm
pnpm
yarn
bun
```bash
npx tsx index.ts
```
```bash
pnpm dlx tsx index.ts
```
```bash
yarn dlx tsx index.ts
```
```bash
bunx --bun tsx index.ts
```
```text no-copy
[{ id: 1, email: 'alice@prisma.io', name: 'Alice' }]
```
Notice how the single `User` object is now enclosed with square brackets in the console. That's because the `findMany` returned an array with a single object inside.
4.5. Explore relation queries [#45-explore-relation-queries]
One of the main features of Prisma ORM is the ease of working with [relations](/orm/prisma-schema/data-model/relations). In this section, you'll learn how to create a `User` and a `Post` record in a nested write query. Afterwards, you'll see how you can retrieve the relation from the database using the `include` option.
First, adjust your script to include the nested query:
```ts title="index.ts"
import { prisma } from "./lib/prisma";
async function main() {
const user = await prisma.user.create({
// [!code ++]
data: {
// [!code ++]
name: "Bob", // [!code ++]
email: "bob@prisma.io", // [!code ++]
posts: {
// [!code ++]
create: [
// [!code ++]
{
// [!code ++]
title: "Hello World", // [!code ++]
published: true, // [!code ++]
}, // [!code ++]
{
// [!code ++]
title: "My second post", // [!code ++]
content: "This is still a draft", // [!code ++]
}, // [!code ++]
], // [!code ++]
}, // [!code ++]
}, // [!code ++]
}); // [!code ++]
console.log(user); // [!code ++]
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
```
Run the query by executing the script again:
npm
pnpm
yarn
bun
```bash
npx tsx index.ts
```
```bash
pnpm dlx tsx index.ts
```
```bash
yarn dlx tsx index.ts
```
```bash
bunx --bun tsx index.ts
```
```text no-copy
{ id: 2, email: 'bob@prisma.io', name: 'Bob' }
```
In order to also retrieve the `Post` records that belong to a `User`, you can use the `include` option via the `posts` relation field:
```ts title="index.ts"
import { prisma } from "./lib/prisma";
async function main() {
const usersWithPosts = await prisma.user.findMany({
// [!code ++]
include: {
// [!code ++]
posts: true, // [!code ++]
}, // [!code ++]
}); // [!code ++]
console.dir(usersWithPosts, { depth: null }); // [!code ++]
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
```
Run the script again to see the results of the nested read query:
npm
pnpm
yarn
bun
```bash
npx tsx index.ts
```
```bash
pnpm dlx tsx index.ts
```
```bash
yarn dlx tsx index.ts
```
```bash
bunx --bun tsx index.ts
```
```text no-copy
[
{ id: 1, email: 'alice@prisma.io', name: 'Alice', posts: [] },
{
id: 2,
email: 'bob@prisma.io',
name: 'Bob',
posts: [
{
id: 1,
title: 'Hello World',
content: null,
published: true,
authorId: 2
},
{
id: 2,
title: 'My second post',
content: 'This is still a draft',
published: false,
authorId: 2
}
]
}
]
```
This time, you're seeing two `User` objects being printed. Both of them have a `posts` field (which is empty for `"Alice"` and populated with two `Post` objects for `"Bob"`) that represents the `Post` records associated with them.
Next steps [#next-steps]
You just got your feet wet with a basic Prisma Postgres setup. Check out the official [Quickstart](/prisma-orm/quickstart/prisma-postgres).
View and edit data in Prisma Studio [#view-and-edit-data-in-prisma-studio]
Prisma ORM comes with a built-in GUI to view and edit the data in your database. You can open it using the following command:
npm
pnpm
yarn
bun
```bash
npx prisma studio --config ./prisma.config.ts
```
```bash
pnpm dlx prisma studio --config ./prisma.config.ts
```
```bash
yarn dlx prisma studio --config ./prisma.config.ts
```
```bash
bunx --bun prisma studio --config ./prisma.config.ts
```
With Prisma Postgres, you can also directly use Prisma Studio inside the [Console](https://console.prisma.io) by selecting the **Studio** tab in your project.
Build a fullstack app with Next.js [#build-a-fullstack-app-with-nextjs]
Learn how to use Prisma Postgres in a fullstack app:
* [Build a fullstack app with Next.js 15](/guides/frameworks/nextjs)
* [Next.js 15 example app](https://github.com/prisma/nextjs-prisma-postgres-demo) (including authentication)
Explore ready-to-run examples [#explore-ready-to-run-examples]
Check out the [`prisma-examples`](https://github.com/prisma/prisma-examples/) repository on GitHub to see how Prisma ORM can be used with your favorite library. The repo contains examples with Express, NestJS, GraphQL as well as fullstack examples with Next.js and Vue.js, and a lot more.
These examples use SQLite by default but you can follow the instructions in the project README to switch to Prisma Postgres in a few simple steps.
# Import from MySQL (/docs/prisma-postgres/import-from-existing-database-mysql)
This guide provides step-by-step instructions for importing data from an existing MySQL database into Prisma Postgres.
You can accomplish this migration in four steps:
1. Create a new Prisma Postgres database.
2. Connect directly to a Prisma Postgres instance using a [direct connection](/postgres/database/connecting-to-your-database).
3. Migrate your MySQL data to Prisma Postgres using [pgloader](https://pgloader.io/).
4. Configure your Prisma project for Prisma Postgres.
Prerequisites [#prerequisites]
* The connection URL to your existing MySQL database.
* A [Prisma Data Platform](https://console.prisma.io) account.
* Node.js 18+ installed.
* [pgloader](https://pgloader.io/) installed.
Make sure your PostgreSQL tools match the Prisma Postgres version
Prisma Postgres runs PostgreSQL 17. Your `pgloader` and any other PostgreSQL tools you use need to be compatible with PostgreSQL 17.
We recommend attempting this migration in a separate git development branch.
1. Create a new Prisma Postgres database [#1-create-a-new-prisma-postgres-database]
Follow these steps to create a new Prisma Postgres database:
1. Log in to [Prisma Data Platform](https://console.prisma.io/) and open the Console.
2. In a [workspace](/console/concepts#workspace) of your choice, click the **New project** button.
3. Type a name for your project in the **Name** field, e.g. **hello-ppg**.
4. In the **Prisma Postgres** section, click the **Get started** button.
5. In the **Region** dropdown, select the region that's closest to your current location, e.g. **US East (N. Virginia)**.
6. Click the **Create project** button.
Once your database is\*\* \*\*provisioned, find your direct Prisma Postgres connection string:
1. Navigate to your active Prisma Postgres instance.
2. Click the **Connection Strings** tab in the project's sidenav.
3. Click the **Create connection string** button.
4. In the popup, provide a **Name** for the connection string and click **Create**.
5. Copy the connection string starting with `postgres://`, this is your direct connection string.
Save the connection string, as you'll need it in step 3.
2. Prepare your direct connection string [#2-prepare-your-direct-connection-string]
In this step, you'll use the [direct connection string](/postgres/database/connecting-to-your-database) you obtained in step 1 to connect to your Prisma Postgres instance.
Your direct connection string should look like this:
```text
postgres://USER:PASSWORD@db.prisma.io:5432/?sslmode=require
```
You'll use this connection string in the next step when configuring pgloader.
3. Migrate your MySQL data to Prisma Postgres using pgloader [#3-migrate-your-mysql-data-to-prisma-postgres-using-pgloader]
Now that you have an active connection to your Prisma Postgres instance, you'll use [pgloader](https://pgloader.io/) to export data from your MySQL database to Prisma Postgres.
Open a separate terminal window and create a `config.load` file:
```bash
touch config.load
```
Open the `config.load` file in your preferred text editor and copy-paste the following configuration:
```text title="config.load"
LOAD DATABASE
FROM mysql://username:password@host:PORT/database_name
INTO postgres://__USER__:__PASSWORD__@db.prisma.io:5432/?sslmode=require
WITH quote identifiers, -- preserve table/column name case by quoting them
include drop,
create tables,
create indexes,
reset sequences
ALTER SCHEMA 'database_name' RENAME TO 'public';
```
Make sure to update the following details in the `config.load` file:
* `FROM` url (MySQL database URL):
* Replace `username`, `password`, `host`, `PORT`, and `database_name` with the actual connection details for your MySQL database.
* Ensure that your connection string includes `useSSL=true` if SSL is required, for example: `mysql://username:password@host:PORT/database_name?useSSL=true`. Note that when using PlanetScale, appending `sslaccept=strict` will not work.
* `INTO` url (Postgres database URL):
* Update this with your direct connection string from above, replacing the `__USER__` and `__PASSWORD__` placeholders.
* Update the `database_name` in `ALTER SCHEMA 'database_name' RENAME TO 'public';` to exactly match the `database_name` in your MySQL connection string.
After saving the configuration file with your updated credentials, in the same terminal window, execute the following command:
```bash
pgloader config.load
```
You should see a log similar to this, which confirms the successful migration of your data:
```bash
LOG report summary reset
table name errors rows bytes total time
------------------------- --------- --------- --------- --------------
fetch meta data 0 9 2.546s
Create Schemas 0 0 0.325s
Create SQL Types 0 0 0.635s
Create tables 0 6 5.695s
Set Table OIDs 0 3 0.328s
------------------------- --------- --------- --------- --------------
public.post 0 8 0.5 kB 4.255s
public."user" 0 4 0.1 kB 2.775s
public._prisma_migrations 0 1 0.2 kB 4.278s
------------------------- --------- --------- --------- --------------
COPY Threads Completion 0 4 5.095s
Index Build Completion 0 5 9.601s
Create Indexes 0 5 4.116s
Reset Sequences 0 2 4.540s
Primary Keys 0 3 2.917s
Create Foreign Keys 0 1 1.121s
Create Triggers 0 0 0.651s
Install Comments 0 0 0.000s
------------------------- --------- --------- --------- --------------
Total import time ✓ 13 0.8 kB 28.042s
```
If you see output like this, it means your data has been successfully exported to your Prisma Postgres instance.
You can also use [Prisma Studio](/guides/postgres/viewing-data#viewing-and-editing-data-in-prisma-studio) to verify whether the migration was successful:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
4. Configure your Prisma project for Prisma Postgres [#4-configure-your-prisma-project-for-prisma-postgres]
After migrating your data, you need to set up your Prisma project to work with Prisma Postgres. The steps differ depending on whether you were already using Prisma ORM.
If you were not previously using Prisma ORM [#if-you-were-not-previously-using-prisma-orm]
Initialize Prisma in your project by running `npx prisma init` in your project directory. This creates a `prisma` folder with a `schema.prisma` file and `.env` file (if not already present).
In the generated `.env` file, update `DATABASE_URL` to match your Prisma Postgres direct connection string that you received in [step 1](/prisma-postgres/import-from-existing-database-mysql#1-create-a-new-prisma-postgres-database):
```text title=".env" no-copy
DATABASE_URL="postgres://USER:PASSWORD@db.prisma.io:5432/?sslmode=require"
```
[Introspect](/orm/prisma-schema/introspection) your newly migrated database by running:
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
This command updates your `schema.prisma` file with models representing your migrated tables, so you can start using [Prisma Client](/orm/prisma-client/setup-and-configuration/introduction) to query your data or [Prisma Migrate](/orm/prisma-migrate/getting-started) to manage future changes.
Congratulations! You've successfully migrated your MySQL database to Prisma Postgres and configured your Prisma project. Your migration tutorial is now complete.
For a comprehensive guide on getting started with Prisma and Prisma Postgres, see [start from scratch with Prisma and Prisma Postgres](/prisma-orm/quickstart/prisma-postgres).
If you were already using Prisma ORM [#if-you-were-already-using-prisma-orm]
In your `schema.prisma` file, change the `provider` in the `datasource` block from `mysql` to `postgresql`:
```prisma title="schema.prisma"
datasource db {
provider = "mysql" // [!code --]
provider = "postgres" // [!code ++]
}
```
In the generated `.env` file, update `DATABASE_URL` to match your Prisma Postgres direct connection string that you received in [step 1](/prisma-postgres/import-from-existing-database-mysql#1-create-a-new-prisma-postgres-database):
```text title=".env" no-copy
DATABASE_URL="postgres://USER:PASSWORD@db.prisma.io:5432/?sslmode=require"
```
Introspect your newly migrated Prisma Postgres database and generate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
This command refreshes your Prisma models based on the new database schema.
If you were using [Prisma Migrate](/orm/prisma-migrate/getting-started) before:
* Delete your existing `migrations` folder in the `prisma` directory.
* [Baseline your database](/orm/prisma-migrate/workflows/baselining#baselining-a-database) to begin creating new migrations.
Congratulations! You've successfully migrated your MySQL database to Prisma Postgres and configured your Prisma project. Your migration tutorial is now complete.
If you encounter any issues during the migration, please don't hesitate to reach out to us on [Discord](https://pris.ly/discord?utm_source=docs\&utm_medium=conclusion) or via [X](https://pris.ly/x?utm_source=docs\&utm_medium=conclusion).
# Import from PostgreSQL (/docs/prisma-postgres/import-from-existing-database-postgresql)
This guide provides step-by-step instructions for importing data from an existing PostgreSQL database into Prisma Postgres.
You can accomplish this migration in three steps:
1. Create a new Prisma Postgres database.
2. Export your existing data via `pg_dump`.
3. Import the previously exported data into Prisma Postgres via `pg_restore`.
In the third step, you will be using a [direct connection](/postgres/database/connecting-to-your-database) to securely connect to your Prisma Postgres database to run `pg_restore`.
Prerequisites [#prerequisites]
* The connection URL to your existing PostgreSQL database
* A [Prisma Data Platform](https://console.prisma.io) account
* Node.js 18+ installed
* PostgreSQL CLI Tools (`pg_dump`, `pg_restore`) for creating and restoring backups
Make sure your PostgreSQL tools match the Prisma Postgres version
Prisma Postgres runs PostgreSQL 17. Your `pg_dump` and `pg_restore` tools need to be version 17 to ensure compatibility. You can check your version by running `pg_dump --version` or `pg_restore --version`.
1. Create a new Prisma Postgres database [#1-create-a-new-prisma-postgres-database]
Follow these steps to create a new Prisma Postgres database:
1. Log in to [Prisma Data Platform](https://console.prisma.io/) and open the Console.
2. In a [workspace](/console/concepts#workspace) of your choice, click the **New project** button.
3. Type a name for your project in the **Name** field, e.g. **hello-ppg**.
4. In the **Prisma Postgres** section, click the **Get started** button.
5. In the **Region** dropdown, select the region that's closest to your current location, e.g. **US East (N. Virginia)**.
6. Click the **Create project** button.
Once your database is provisioned, obtain your direct connection string:
1. Navigate to your active Prisma Postgres instance.
2. Click the **Connection Strings** tab in the project's sidenav.
3. Click the **Create connection string** button.
4. In the popup, provide a **Name** for the connection string and click **Create**.
5. Copy the connection string starting with `postgres://`, this is your direct connection string.
Save the connection string, as you'll need it in step 3.
2. Export data from your existing database [#2-export-data-from-your-existing-database]
In this step, you're going to export the data from your existing database and store it in a `.bak` file on your local machine.
Make sure to have the connection URL for your existing database ready, it should be [structured](/orm/reference/connection-urls) like this:
```text
postgresql://USER:PASSWORD@HOST:PORT/DATABASE
```
Expand below for provider-specific instructions that help you determine the right connection string:
* Make sure to select non-pooled connection string by switching off the **Connection pooling** toggle.
* The `sslmode` has to be set to `require` and appended to your Neon database URL for the command to work.
* The connection URL should look similar to this:
```text
postgresql://USER:PASSWORD@YOUR-NEON-HOST/DATABASE?sslmode=require
```
* Use a database connection URL that uses [Supavisor session mode](https://supabase.com/docs/guides/database/connecting-to-postgres#supavisor-session-mode).
* The connection URL should look similar to this:
```text
postgres://postgres.apbkobhfnmcqqzqeeqss:[YOUR-PASSWORD]@aws-0-ca-central-1.pooler.supabase.com:5432/postgres
```
Next, run the following command to export the data of your PostgreSQL database (replace the `__DATABASE_URL__` placeholder with your actual database connection URL):
```bash
pg_dump \
-Fc \
-v \
-d __DATABASE_URL__ \
-n public \
-f db_dump.bak
```
Here's a quick overview of the CLI options that were used for this command:
* `-Fc`: Uses the custom format for backups, recommended for `pg_restore`
* `-v`: Runs `pg_dump` in verbose mode
* `-d`: Specifies the database connection string
* `-n`: Specifies the target PostgreSQL schema
* `-f`: Specifies the output name for the backup file
Running this command will create a backup file named `db_dump.bak` which you will use to restore the data into your Prisma Postgres database in the next step.
3. Import data into Prisma Postgres [#3-import-data-into-prisma-postgres]
In this section, you'll use your [direct connection string](/postgres/database/connecting-to-your-database) to connect to your Prisma Postgres instance and import data via `pg_restore`.
Your direct connection string from step 1 should look like this:
```text
postgres://USER:PASSWORD@db.prisma.io:5432/?sslmode=require
```
Use the backup file from **Step 2** to restore data into your Prisma Postgres database with `pg_restore` by running this command (replace `__USER__`, `__PASSWORD__` with the values from your direct connection string):
```bash
pg_restore \
-h db.prisma.io \
-p 5432 \
-U __USER__ \
-d postgres \
-v \
./db_dump.bak \
&& echo "-complete-"
```
When prompted, enter the `__PASSWORD__` from your direct connection string.
You can also use the full connection string format:
```bash
pg_restore \
-d "postgres://USER:PASSWORD@db.prisma.io:5432/postgres?sslmode=require" \
-v \
./db_dump.bak \
&& echo "-complete-"
```
Once the command completes execution, you will have successfully imported the data from your existing PostgreSQL database into Prisma Postgres 🎉
To validate that the import worked, you can use [Prisma Studio](/guides/postgres/viewing-data#viewing-and-editing-data-in-prisma-studio). Either open it in the [Platform Console](https://console.prisma.io) by clicking the **Studio** tab in the left-hand sidenav in your project or run this command to launch Prisma Studio locally:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
4. Update your application code to query Prisma Postgres [#4-update-your-application-code-to-query-prisma-postgres]
Scenario A: You are already using Prisma ORM [#scenario-a-you-are-already-using-prisma-orm]
If you're already using Prisma ORM, you need to update your database connection URL to point to your new Prisma Postgres instance.
Update the `DATABASE_URL` in your `.env` file to match your Prisma Postgres direct connection string from step 1:
```text title=".env"
DATABASE_URL="postgres://USER:PASSWORD@db.prisma.io:5432/?sslmode=require"
```
Then, re-generate Prisma Client so that the updated environment variable takes effect:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
Once this is done, you can run your application and it should work as before.
For a complete guide on setting up Prisma ORM with Prisma Postgres from scratch, including driver adapter configuration and best practices, see the [Prisma ORM with Prisma Postgres quickstart](/prisma-orm/quickstart/prisma-postgres).
Scenario B: You are not yet using Prisma ORM [#scenario-b-you-are-not-yet-using-prisma-orm]
If you are not yet using Prisma ORM, you'll need to go through the following steps to use Prisma Postgres from your application:
1. Install the Prisma CLI and other required dependencies in your project
2. Introspect the database to generate a Prisma schema
3. Generate Prisma Client
4. Update the queries in your application to use Prisma ORM
You can find the detailed step-by-step instructions for this process in this guide: [Add Prisma ORM to an existing project](/prisma-orm/add-to-existing-project/prisma-postgres).
# FAQ (/docs/accelerate/more/faq)
When should I enable static IP for Prisma Accelerate? [#when-should-i-enable-static-ip-for-prisma-accelerate]
Enable static IP for Accelerate when your security setup requires IP allowlisting or if you're implementing firewalls that only permit access from trusted IPs, ensuring controlled and secure database connections.
Learn more on [how to enable static IP for Accelerate in the Platform Console](/accelerate/static-ip).
**What is a static IP?**
A static IP address is an IPv4 or an IPv6 address that is fixed. Unlike dynamic IP addresses, which can change unpredictably, traffic from static IP addresses can be easily identified.
> ℹ️ To enable static IP support for Accelerate within your existing or new project environment, your workspace will need to be on our **Pro** or **Business** plans. Take a look at the [pricing page](https://www.prisma.io/pricing#accelerate) for more information.
Why do I sometimes see unexpected cache behavior? [#why-do-i-sometimes-see-unexpected-cache-behavior]
Accelerate's cache performs best when it observes a higher load from a project. Many cache operations, such as committing data to cache and refreshing stale data, happen asynchronously. When benchmarking Accelerate, we recommend doing so with loops or a load testing approach. This will mimic higher load scenarios better and reduce outliers from low frequency operations.
Prisma operations are sent to Accelerate over HTTP. As a result, the first request to Accelerate must establish an HTTP handshake and may have additional latency as a result. We're exploring ways to reduce this initial request latency in the future.
What is the pricing of Accelerate? [#what-is-the-pricing-of-accelerate]
You can find more details on our [Accelerate pricing page](https://www.prisma.io/pricing)
VS Code does not recognize the $extends method [#vs-code-does-not-recognize-the-extends-method]
If you add the Prisma Client extension for Accelerate to an existing project that is currently open in VS Code, the editor might not immediately recognize the `$extends` method.
This might be an issue with the TypeScript server not yet recognizing the regenerated Prisma Client. To resolve this, you need to restart TypeScript.
1. In VS Code, open the Command Palette. You can do so when you press F1 or select **View** > **Command Palette**.
2. Enter `typescript` and select and run the **TypeScript: Restart TS server** command.
VS Code should now recognize the `$extends` method.
What regions are Accelerate's cache nodes available in? [#what-regions-are-accelerates-cache-nodes-available-in]
Accelerate runs on Cloudflare's network and cache hits are served from Cloudflare's 300+ locations. You can find the regions where Accelerate's cache nodes are available here: [https://www.cloudflare.com/network/](https://www.cloudflare.com/network/).
What regions is Accelerate's connection pool available in? [#what-regions-is-accelerates-connection-pool-available-in]
When no cache strategy is specified or in the event of a cache miss, the Prisma Client query is routed through Accelerate's connection pool. Currently, queries can be routed through any chosen region among the 16 available locations.
Currently, the list of available regions are:
* Asia Pacific, Mumbai (`ap-south-1`)
* Asia Pacific, Seoul (`ap-northeast-2`)
* Asia Pacific, Singapore (`ap-southeast-1`)
* Asia Pacific, Sydney (`ap-southeast-2`)
* Asia Pacific, Tokyo (`ap-northeast-1`)
* Canada, Central (`ca-central-1`)
* Europe, Frankfurt (`eu-central-1`)
* Europe, Ireland (`eu-west-1`)
* Europe, London (`eu-west-2`)
* Europe, Paris (`eu-west-3`)
* Europe, Stockholm (`eu-north-1`)
* South America, Sao Paulo (`sa-east-1`)
* US East, N. Virginia (`us-east-1`)
* US East, Ohio (`us-east-2`)
* US West, N. California (`us-west-1`)
* US West, Oregon (`us-west-2`)
You can also view the available regions when you're about to set up Accelerate or by visiting the **Settings** tab for Accelerate under the **Region** section in the Prisma Cloud Platform [dashboard](https://pris.ly/pdp).
How does Accelerate know what region to fetch the cache from? [#how-does-accelerate-know-what-region-to-fetch-the-cache-from]
Under the hood, Accelerate uses Cloudflare, which uses [Anycast](https://www.cloudflare.com/learning/cdn/glossary/anycast-network/) for network addressing and routing. An incoming request will be routed to the nearest data center or "node" in their network that has the capacity to process the request efficiently. To learn more about how this works, we recommend looking into [Anycast](https://www.cloudflare.com/learning/cdn/glossary/anycast-network/).
How can I invalidate a cache on Accelerate? [#how-can-i-invalidate-a-cache-on-accelerate]
You can invalidate the cache on-demand via the [`$accelerate.invalidate` API](/accelerate/reference/api-reference#accelerateinvalidate) if you're on a [paid plan](https://www.prisma.io/pricing#accelerate), or you can invalidate your entire cache, on a project level, a maximum of five times a day. This limit is set based on [your plan](https://www.prisma.io/pricing#accelerate). You can manage this via the Accelerate configuration page.
What is Accelerate's consistency model? [#what-is-accelerates-consistency-model]
Accelerate does not have a consistency model. It is not a distributed system where nodes need to reach a consensus (because data is only stored in the cache node(s) closest to the user). However, the data cached in Accelerate's cache nodes doesn't propagate to other nodes, so Accelerate by design doesn't need a consistency model.
Accelerate implements a [read-through caching strategy](https://www.prisma.io/dataguide/managing-databases/introduction-database-caching#read-through) particularly suitable for read-heavy workloads.
How is Accelerate different from other caching tools, such as Redis? [#how-is-accelerate-different-from-other-caching-tools-such-as-redis]
* Accelerate is a *specialized* cache that allows you to optimize data access in code at the query level with a cache strategy. On the other hand, tools such as Redis and Memcached are *general-purpose* caches designed to be adaptable and flexible.
* Accelerate is a managed service that reduces the time, risk, and engineering effort of building and maintaining a cache service.
* By default, Accelerate is globally distributed, reducing the latency of your queries. Other cache tools would require additional configuration to make them available globally.
When should I not use Accelerate's caching features? [#when-should-i-not-use-accelerates-caching-features]
Accelerate is a global data cache and connection pool that allows you to optimize data access in code at the query level. While caching with Accelerate can greatly boost the performance of your app, it may not always the best choice for your use case.
Accelerate's global cache feature may not be a good fit for your app if:
* Your app is exclusively used within a specific region and both your application server and database are situated in that same region on the same network. For example, database queries will likely be much faster if your application server and database are in the same region and network. However, If your application server is in different regions or networks from your database, Accelerate will speed up your queries because the data will be cached in the closest data center to your application.
* You *only* need a general-purpose cache. Accelerate is a connection pooler and a *specialized cache* that only caches your database query responses in code. A general-purpose cache, such as Redis, would allow you to cache data from multiple sources, such as external APIs, which Accelerate currently doesn't support. If general-purpose caching interests you, please share your feedback with us via our [Discord](https://pris.ly/discord?utm_source=docs\&utm_medium=inline_text).
* Your application data *always* needs to be up-to-date on retrieval, making it difficult to establish a reasonable cache strategy.
Even without using Accelerate's global cache, you can still greatly benefit from Accelerate by using its connection pool, especially in serverless or edge functions, where it is difficult to manage and scale database connections. You can learn more about the serverless challenge [here](/orm/prisma-client/setup-and-configuration/databases-connections#the-serverless-challenge).
Can I use Accelerate with other ORMs/query builders/drivers? [#can-i-use-accelerate-with-other-ormsquery-buildersdrivers]
No. We currently do not have any plans for supporting other ORMs/query builders or drivers. However, if you're interested in support for other libraries, feel free to reach out and let us know in our [Discord](https://pris.ly/discord?utm_source=docs\&utm_medium=inline_text) community in the `#help-and-questions` channel.
What is the maximum allowed value for the ttl parameter when configuring cacheStrategy? [#what-is-the-maximum-allowed-value-for-the-ttl-parameter-when-configuring-cachestrategy]
The [Time-to-live](/accelerate/caching) (`ttl`) parameter can be set for up to a *year*. However, it's important to note that items within the cache may be evicted if they are not frequently accessed.
Based on our experimentation, we’ve seen cache items persist for around 18 hours. While items may remain in the cache for an extended period if they are actively accessed, there is no guarantee.
> **Note**: Even frequently accessed items may occasionally be evicted from the cache. It's unlikely for an item to survive for up to or longer than a month, regardless of its activity level.
Why doesn’t Accelerate fall back to the direct connection string during a service disruption? [#why-doesnt-accelerate-fall-back-to-the-direct-connection-string-during-a-service-disruption]
In the rare event of a service disruption, falling back to a direct connection would bypass the connection pool. This could potentially deplete the database's available connections and cause other issues on the database level.
If there is a service disruption, it's recommended to verify on the [status page](https://pris.ly/data-platform-status). You can reach out to one of Prisma's [support channels](/console/more/support) for assistance.
> **Note:** Additionally, it's worth noting that some edge function runtime environments may not support direct connections with Prisma ORM. For further details, refer to our [Edge functions documentation](/orm/prisma-client/deployment/edge/overview).
Are each of the queries within an interactive transaction counted separately for billing? [#are-each-of-the-queries-within-an-interactive-transaction-counted-separately-for-billing]
Yes, [interactive transactions](/orm/prisma-client/queries/transactions#interactive-transactions) are billed based on the individual operations within the transaction. There is no charge for the start, commit, or rollback of the transaction itself. For example, in the following query, there are two billable queries:
```ts
await prisma.$transaction(async (tx) => {
await tx.user.deleteMany({ where: { name: "John Doe" } });
await tx.user.createMany({ data });
});
```
However, when using the [`$transaction` API for sequential client operations](/orm/prisma-client/queries/transactions#sequential-operations), regardless of the number of queries within the array, it counts as only one billable query. For example:
```ts
await prisma.$transaction([
prisma.user.deleteMany({ where: { name: "John Doe" } }),
prisma.user.createMany({ data }),
]);
```
If you don't need [interactive transactions](/orm/prisma-client/queries/transactions#interactive-transactions), you can save costs and improve performance by using [sequential operations transactions](/orm/prisma-client/queries/transactions#sequential-operations). Sequential operations transactions perform better on Accelerate because they execute in one round-trip to the database, while interactive transactions require separate round-trips for start, commit, and each individual operation on the transaction.
Can I increase my Accelerate query duration and response size limits? [#can-i-increase-my-accelerate-query-duration-and-response-size-limits]
Yes, you can increase your Accelerate limits based on your subscription plan. Here are the configurable limits:
| Limit | Free | Starter | Pro Plan | Business Plan |
| ------------------------------------ | ---------------- | ---------------- | ---------------- | ---------------- |
| **Query timeout** | Up to 10 seconds | Up to 10 seconds | Up to 20 seconds | Up to 60 seconds |
| **Interactive transactions timeout** | Up to 15 seconds | Up to 15 seconds | Up to 30 seconds | Up to 90 seconds |
| **Response size** | Up to 5 MB | Up to 5 MB | Up to 10 MB | Up to 20 MB |
Check the [pricing page](https://www.prisma.io/pricing#accelerate) for more details on the available plans and their corresponding limits.
While you can increase these limits based on your subscription plan, it's *still* recommended to optimize your database operations. [Learn more in our troubleshooting guide.](/postgres/error-reference)
How long does it take to invalidate a cache query result? [#how-long-does-it-take-to-invalidate-a-cache-query-result]
As the cache needs to be cleared globally, it is difficult to provide a specific time frame. However, the cached data is eventually consistent and typically propagates to all PoPs within a few seconds. In very rare cases, it may take longer.
Here is a [demo app](https://pris.ly/test-cache-invalidation) to test the time it takes to invalidate a cache query result.
What is the difference between Invalidate and Revalidate? [#what-is-the-difference-between-invalidate-and-revalidate]
**Invalidate**: The cache entry is deleted, and new data will be fetched on the next request, causing a cache miss. This removes stale data but may lead to slower responses until the cache is repopulated.
**Revalidate**: The cache entry is updated proactively, ensuring the next request uses fresh data from the cache. This keeps the cache valid and maintains faster response times by avoiding cache misses.
What is on-demand cache invalidation? [#what-is-on-demand-cache-invalidation]
[On-demand cache invalidation](/accelerate/caching) lets applications instantly update specific cached data when it changes, instead of waiting for regular cache refresh cycles. This keeps information accurate and up-to-date for users.
When should I use the cache invalidate API? [#when-should-i-use-the-cache-invalidate-api]
The [cache invalidate API](/accelerate/caching) is essential when data consistency cannot wait for the cache’s standard expiration or revalidation. Key use cases include:
* **Content updates**: When critical changes occur, such as edits to a published article, product updates, or profile modifications, that need to be visible immediately.
* **Inventory management**: In real-time applications, like inventory or booking systems, where stock levels, availability, or reservation statuses must reflect the latest information.
* **High-priority data**: For time-sensitive data, like breaking news or urgent notifications, where it’s essential for users to see the most current information right away.
Using on-demand cache invalidation in these scenarios helps keep only the necessary data refreshed, preserving system performance while ensuring accurate, up-to-date information for users.
How does Accelerate count queries for billing? [#how-does-accelerate-count-queries-for-billing]
Accelerate counts queries at the Prisma Client invocation level. A single Prisma query may translate into multiple SQL statements under the hood, but it will only count as one query for billing purposes. This ensures straightforward, predictable billing that reflects the Prisma Client usage rather than the complexity of the underlying SQL operations.
Queries are counted regardless of whether they are served from the cache or the database. Even if a query is retrieved from the cache, it still counts toward your query limit.
How do I switch from GitHub login to email and password login? [#how-do-i-switch-from-github-login-to-email-and-password-login]
If you previously signed up using GitHub and want to switch to email and password login, follow these steps:
1. Verify Your GitHub Email Address [#1-verify-your-github-email-address]
* Check the primary email address associated with your GitHub account (e.g., from your GitHub profile or notification settings).
2. Create a New Email/Password Account [#2-create-a-new-emailpassword-account]
* Go to the email/password sign-up page.
* Use the **same email address** linked to your GitHub account to create the new account.
* Our system will automatically connect your new email/password account to your existing data.
3. Test Your Login [#3-test-your-login]
* Log out and try logging in with your email and the password you just created.
> **Note**: If you encounter any issues, please contact our support team for help linking your accounts.
# Feedback (/docs/accelerate/more/feedback)
You can submit any feedback about Accelerate in our [Discord server](https://pris.ly/discord?utm_source=docs\&utm_medium=intro_text).
# Known limitations (/docs/accelerate/more/known-limitations)
Below are descriptions of known limitations when using Accelerate. If you encounter any additional ones, please share them with us via [Discord](https://pris.ly/discord?utm_source=docs\&utm_medium=intro_text).
Cannot cache raw queries [#cannot-cache-raw-queries]
At the moment, it is not possible to cache the responses of [raw queries](/orm/prisma-client/using-raw-sql/raw-queries).
Not compatible with the fluent API [#not-compatible-with-the-fluent-api]
Client Extensions (which are used in Accelerate) currently do not correctly forward the [fluent API](/orm/prisma-client/queries/relation-queries#fluent-api) types. We hope to get a fix into Client Extensions soon.
Not compatible with extremely heavy or long-running queries [#not-compatible-with-extremely-heavy-or-long-running-queries]
Accelerate is designed to work with high-performance, low-latency queries. It is not intended for use with extremely heavy or long-running queries that may cause performance issues or resource contention. While limits are configurable, we recommend optimizing your queries to ensure they fit within the recommended guidelines.
For queries that cannot be optimized or pared down, we recommend one of two solutions:
1. **Use the read replica extension**: The Prisma ORM [read replica extension](https://www.npmjs.com/package/@prisma/extension-read-replicas) allows you to set up two different connections: a `primary` and a `replica`. You can set up your Accelerate connection as the `primary` and then a direct connection as the `replica`. Any queries that are resource-intensive or long-running can then be routed to the `replica`, while the `primary` (your Accelerate connection) will handle normal queries. **Please note** that this solution requires you to both set up a direct connection and requires the full generated Prisma Client (i.e. without `--no-engine`).
2. **Separate analytics queries**: Our preferred solution is to separate your analytics queries into a separate application. This separate application can then use a direct connection so that it can run heavy queries without impacting the performance or cost of your Accelerate-powered application.
If you have a use case that requires running extremely heavy or long-running queries and Prisma Accelerate, please reach out to us.
Not compatible with direct IPv4 addresses in MongoDB connection strings [#not-compatible-with-direct-ipv4-addresses-in-mongodb-connection-strings]
Accelerate does not support direct IPv4 addresses in MongoDB connection strings. When an IPv4 address is provided, Accelerate converts it to an IPv6 format to route through its NAT gateway. This conversion may cause the connection string to be considered invalid due to the formatting of the port value.
**Workaround**: To resolve this issue, create a DNS record that points to your IPv4 address and use that DNS record in your connection string instead of the direct IP.
Example [#example]
* **IPv4 connection string** (not supported): `mongodb://user:password@192.168.1.100:27017/db_name`
* **DNS record connection string** (supported): `mongodb://user:password@my-database.example.com:27017/db_name`
For additional details on Accelerate’s IPv6-first design, refer to our [blog post](https://www.prisma.io/blog/accelerate-ipv6-first).
# Troubleshooting (/docs/accelerate/more/troubleshoot)
When working with Accelerate, you may encounter errors often highlighted by specific error codes during development and operations. It is important to understand the meaning of these errors, why they occur, and how to resolve them in order to ensure the smooth operation of your applications. This guide aims to provide insights and steps to troubleshoot specific error codes encountered with Accelerate.
P6009 (ResponseSizeLimitExceeded) [#p6009-responsesizelimitexceeded]
This error is triggered when the response size from a database query exceeds the configured query response size limit. We've implemented this restriction to safeguard your application performance, as retrieving data over 5MB can significantly slow down your application due to multiple network layers. Typically, transmitting more than 5MB of data is common when conducting ETL (Extract, Transform, Load) operations. However, for other scenarios such as transactional queries, real-time data fetching for user interfaces, bulk data updates, or aggregating large datasets for analytics outside of ETL contexts, it should generally be avoided. These use cases, while essential, can often be optimized to work within the configured query response size limit, ensuring smoother performance and a better user experience.
Possible causes for P6009 [#possible-causes-for-p6009]
Transmitting images/files in response [#transmitting-imagesfiles-in-response]
This error may arise if images or files stored within your table are being fetched, resulting in a large response size. Storing assets directly in the database is generally discouraged because it significantly impacts database performance and scalability. In addition to performance, it makes database backups slow and significantly increases the cost of storing routine backups.
**Suggested solution:** Configure the query response size limit to be larger. If the limit is still exceeded, consider storing the image or file in a BLOB store like [Cloudflare R2](https://developers.cloudflare.com/r2/), [AWS S3](https://aws.amazon.com/pm/serv-s3/), or [Cloudinary](https://cloudinary.com/). These services allow you to store assets optimally and return a URL for access. Instead of storing the asset directly in the database, store the URL, which will substantially reduce the response size.
Over-fetching of data [#over-fetching-of-data]
In certain cases, a large number of records or fields are unintentionally fetched, which results in exceeding the configured query response size limit. This could happen when the [`where`](/orm/reference/prisma-client-reference#where) clause in the query is incorrect or entirely missing.
**Suggested solution:** Configure the query response size limit to be larger. If the limit is still exceeded, double-check that the `where` clause is filtering data as expected. To prevent fetching too many records, consider using [pagination](/v6/orm/prisma-client/queries/pagination). Additionally, use the [`select`](/orm/reference/prisma-client-reference#select) clause to return only the necessary fields, reducing the response size.
Fetching a large volume of data [#fetching-a-large-volume-of-data]
In many data processing workflows, especially those involving ETL (Extract-Transform-Load) processes or scheduled CRON jobs, there's a need to extract large amounts of data from data sources (like databases, APIs, or file systems) for analysis, reporting, or further processing. If you are running an ETL/CRON workload that fetches a huge chunk of data for analytical processing then you might run into this limit.
**Suggested solution:** Configure the query response size limit to be larger. If the limit is exceeded, consider splitting your query into batches. This approach ensures that each batch fetches only a portion of the data, preventing you from exceeding the size limit for a single operation.
P6004 (QueryTimeout) [#p6004-querytimeout]
This error occurs when a database query fails to return a response within the configured query timeout limit. The query timeout limit includes the duration of waiting for a connection from the pool, network latency to the database, and the execution time of the query itself. We enforce this limit to prevent unintentional long-running queries that can overload system resources.
> The time for Accelerate's cross-region networking is excluded from the configured query timeout limit.
Possible causes for P6004 [#possible-causes-for-p6004]
This error could be caused by numerous reasons. Some of the prominent ones are:
High traffic and insufficient connections [#high-traffic-and-insufficient-connections]
If the application is receiving very high traffic and there are not a sufficient number of connections available to the database, then the queries would need to wait for a connection to become available. This situation can lead to queries waiting longer than the configured query timeout limit for a connection, ultimately triggering a timeout error if they do not get serviced within this duration.
**Suggested solution**: Review and possibly increase the `connection_limit` specified in the connection string parameter when setting up Accelerate in a platform environment. This limit should align with your database's maximum number of connections.
By default, the connection limit is set to 10 unless a different `connection_limit` is specified in your database connection string.
Long-running queries [#long-running-queries]
Queries may be slow to respond, hitting the configured query timeout limit even when connections are available. This could happen if a very large amount of data is being fetched in a single query or if appropriate indexes are missing from the table.
**Suggested solution**: Configure the query timeout limit to be larger. If the limit is exceeded, identify the slow-running queries and fetch only the necessary data. Use the `select` clause to retrieve specific fields and avoid fetching unnecessary data. Additionally, consider adding appropriate indexes to improve query efficiency. You might also isolate long-running queries into separate environments to prevent them from affecting transactional queries.
Database resource contention [#database-resource-contention]
A common yet challenging issue is when other services operating on the same database perform heavy analytics or data processing tasks, significantly consuming database resources. These operations can monopolize database connections and processing power, leading to a scenario where even simple queries cannot be executed in a timely manner. This "busy" or "noisy" database environment can cause queries that are typically fast to run slowly or even timeout, particularly during periods of high activity from other services.
Users often rely on CPU and memory usage metrics to gauge database load, which can be misleading. While these are important indicators, they might not fully represent the database's operational state. Direct metrics like the number of reads, writes, and wait times offer a clearer view of the database's performance and should be monitored closely. A noticeable degradation in these metrics, especially in the absence of changes to the queries or data model, suggests that external pressures are affecting database performance.
**Suggested solution**: If normally quick queries are intermittently slow or timing out without any modifications to them, it's probable that competing queries are exerting pressure on the same database tables. To diagnose this, adopt monitoring tools or leverage your database's inherent capabilities to observe reads, writes, and wait times. Such monitoring will unveil activity patterns or spikes that align with the observed performance dips.
Moreover, it's crucial to periodically scrutinize and refine essential queries and verify that tables are properly indexed. This proactive approach minimizes the vulnerability of these queries to slowdowns caused by competing workloads.
Considerations for P6009 and P6004 errors [#considerations-for-p6009-and-p6004-errors]
For runtimes that support Prisma ORM natively, you could consider creating two `PrismaClient` Instances. One with the Accelerate connection string (prefixed with `prisma://`) and the other one with the direct database connection string (prefixed with `postgres://`, `mysql://` etc). The main idea behind this approach is to bypass Accelerate for certain specific queries.
However, please note that the available connections would be split between both of your `PrismaClient` Instances. It's crucial to understand the implications of managing multiple instances, particularly in regards to direct database connections. Utilizing a `PrismaClient` instance with a direct database connection string means that this connection will interact directly with your database.
This approach requires careful consideration because the direct connections and those managed by Accelerate share the same underlying database connection pool. This can lead to competition for resources, potentially affecting the performance and availability of your database services.
Additionally, direct connections could have a significant impact on your database's performance and availability. Operations that consume a considerable amount of resources could potentially degrade the service for other users or processes that rely on the same database.
If your application's runtime environment supports Prisma ORM natively and you're considering this strategy to circumvent P6009 and P6004 errors, you might create two `PrismaClient` instances:
1. An instance using the Accelerate connection string (prefixed with `prisma://`) for general operations.
2. Another instance with the direct database connection string (e.g., prefixed with `postgres://`, `mysql://`, etc.) for specific operations anticipated to exceed the configured query timeout limit or to result in responses larger than the configured query response size limit.
```ts
export const prisma = new PrismaClient({
datasourceUrl: process.env.DIRECT_DB_CONNECTION,
});
export const prismaAccelerate = new PrismaClient({
datasourceUrl: process.env.ACCELERATE_CONNECTION,
}).$extends(withAccelerate());
```
This setup allows you to strategically direct certain operations through the direct connection, mitigating the risk of encountering the aforementioned errors. However, this decision should be made with a comprehensive understanding of the potential consequences and an assessment of whether your database infrastructure can support this additional load without compromising overall performance and availability.
> Also see [**why doesn’t Accelerate fall back to the direct connection string during a service disruption?**](/accelerate/more/faq#why-doesnt-accelerate-fall-back-to-the-direct-connection-string-during-a-service-disruption)
P6008 (ConnectionError|EngineStartError) [#p6008-connectionerrorenginestarterror]
This error indicates that Prisma Accelerate cannot establish a connection to your database, potentially due to several reasons.
Possible causes for P6008 [#possible-causes-for-p6008]
Database Not Publicly accessible [#database-not-publicly-accessible]
If your database is within a VPC or access is limited to specific IP addresses, you might encounter this error if static IP is not enabled for Accelerate or if the static IPs are not permitted in your database firewall.
**Suggested solution:** [Enable static IP for Accelerate](/accelerate/static-ip) and configure your database firewall to allow access from the provided static IP addresses.
Unreachable Database Host/Port [#unreachable-database-hostport]
If the database’s server address (hostname) and port are incorrect or unreachable then you may encounter this error.
**Suggested solution:** Verify the hostname/port of the database connection string that was provided while creating the Prisma Accelerate project. Additionally, attempt to connect to the database using a Database GUI tool (e.g., [Prisma Studio](https://www.prisma.io/studio), [TablePlus](https://tableplus.com/), or [DataGrip](https://www.jetbrains.com/datagrip/)) for further investigation.
Incorrect username/password/database name [#incorrect-usernamepassworddatabase-name]
This error can happen when the wrong credentials are provided to Prisma Accelerate, preventing it from establishing a connection to your database.
**Suggested solution:** Verify the correctness of your database's username, password, and name in the connection string provided to Prisma Accelerate. Ensure that these credentials match those required by your database. Testing the connection using a direct database GUI tool can also help in confirming if the provided credentials are correct.
Database taking too long to respond [#database-taking-too-long-to-respond]
If the database is taking too long to respond to the connection request, Prisma Accelerate may timeout and throw this error. This could happen if the database is not active or is waking up from sleep mode.
**Suggested solution:** Verify that the database is active and reachable. If the database is in sleep mode, try to wake it up by sending a request to it using a direct database GUI tool or wake it up using the database's management console.
P5011 (TooManyRequests) [#p5011-toomanyrequests]
This error occurs when Prisma Accelerate detects a high volume of requests that surpasses allowable thresholds. It acts as a protective measure to safeguard both Prisma Accelerate and your underlying database from excessive load.
Possible causes for P5011 [#possible-causes-for-p5011]
Aggressive retry loops [#aggressive-retry-loops]
If your application retries queries immediately or with minimal delay, especially after receiving certain errors, the rapid accumulation of requests can surpass the threshold.
**Suggested solution:**
* Implement an exponential backoff strategy. Rather than retrying immediately or with a fixed delay, gradually increase the delay period after each failed attempt.
* This allows the system time to recover and reduces the likelihood of overwhelming Prisma Accelerate and your database.
Sudden traffic spikes [#sudden-traffic-spikes]
Unpredicted traffic surges (for example, during product launches, flash sales, or viral growth events) can cause the threshold to be met and result into `P5011`.
**Suggested solution:**
* Consider proactive scaling strategies for both Prisma Accelerate and your database.
* Monitor traffic and resource usage. If you anticipate a surge, please contact [support](/console/more/support) for capacity planning and potential configuration adjustments.
Prolonged or planned high workloads [#prolonged-or-planned-high-workloads]
Certain processes, such as bulk data imports, ETL operations, or extended CRON jobs, can generate continuous high query volume over time.
**Suggested solution:**
* Use batching or chunking techniques to break large operations into smaller parts.
* Establish throttling or scheduling to distribute the load more evenly.
Other errors [#other-errors]
Error with MySQL (Aiven): "We were unable to process your request. Please refresh and try again." [#error-with-mysql-aiven-we-were-unable-to-process-your-request-please-refresh-and-try-again]
Issue [#issue]
When using an Aiven MySQL connection string that includes the `?ssl-mode=REQUIRED` parameter, you may encounter the following error:
```
We were unable to process your request. Please refresh and try again.
```
Cause [#cause]
The `ssl-mode=REQUIRED` parameter is incompatible with Accelerate, which leads to connection issues.
Suggested solution [#suggested-solution]
To resolve this error, remove the `?ssl-mode=REQUIRED` parameter from your MySQL connection string.
Example [#example]
* Original connection string: `mysql://username:password@host:port/database?ssl-mode=REQUIRED`
* Updated connection string: `mysql://username:password@host:port/database`
# API Reference (/docs/accelerate/reference/api-reference)
The Accelerate API reference documentation is based on the following schema:
```prisma
model User {
id Int @id @default(autoincrement())
name String?
email String @unique
}
```
All example are based on the `User` model.
cacheStrategy [#cachestrategy]
With the Accelerate extension for Prisma Client, you can use the `cacheStrategy` parameter for model queries and use the [`ttl`](/accelerate/caching) and [`swr`](/accelerate/caching) parameters to define a cache strategy for Accelerate. The Accelerate extension requires that you install Prisma Client version `4.10.0`.
Options [#options]
The `cacheStrategy` parameter takes an option with the following keys:
| Option | Example | Type | Required | Description |
| ------ | ---------- | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `swr` | `60` | `Int` | No | The stale-while-revalidate time in seconds. |
| `ttl` | `60` | `Int` | No | The time-to-live time in seconds. |
| `tags` | `["user"]` | `String[]` | No | The `tag` serves as a variable to control the invalidation of specific queries within your application. It is an optional array of strings to [invalidate](/accelerate/reference/api-reference#accelerateinvalidate) the cache, with each tag containing only alphanumeric characters and underscores, and a maximum length of 64 characters. |
|
Examples [#examples]
Add a caching strategy to the query, defining a 60-second stale-while-revalidate (SWR) value, a 60-second time-to-live (TTL) value, and a cache tag of `"emails_with_alice"`:
```ts highlight=7:11;normal
await prisma.user.findMany({
where: {
email: {
contains: "alice@prisma.io",
},
},
cacheStrategy: {
// [!code highlight]
swr: 60, // [!code highlight]
ttl: 60, // [!code highlight]
tags: ["emails_with_alice"], // [!code highlight]
}, // [!code highlight]
});
```
Supported Prisma Client operations [#supported-prisma-client-operations]
The following is a list of all read query operations that support `cacheStrategy`:
* [`findUnique()`](/orm/reference/prisma-client-reference#findunique)
* [`findUniqueOrThrow()`](/orm/reference/prisma-client-reference#finduniqueorthrow)
* [`findFirst()`](/orm/reference/prisma-client-reference#findfirst)
* [`findFirstOrThrow()`](/orm/reference/prisma-client-reference#findfirstorthrow)
* [`findMany()`](/orm/reference/prisma-client-reference#findmany)
* [`count()`](/orm/reference/prisma-client-reference#count)
* [`aggregate()`](/orm/reference/prisma-client-reference#aggregate)
* [`groupBy()`](/orm/reference/prisma-client-reference#groupby)
The `cacheStrategy` parameter is not supported on any write operations, such as `create()`.
withAccelerateInfo [#withaccelerateinfo]
Any query that supports the `cacheStrategy` can append `withAccelerateInfo()` to wrap the response data and include additional information about the Accelerate response.
To retrieve the status of the response, use:
```ts
const { data, info } = await prisma.user
.count({
cacheStrategy: { ttl: 60, swr: 600 },
where: { myField: "value" },
})
.withAccelerateInfo();
console.dir(info);
```
Notice the `info` property of the response object. This is where the request information is stored.
Return type [#return-type]
The `info` object is of type `AccelerateInfo` and follows the interface below:
```ts
interface AccelerateInfo {
cacheStatus: "ttl" | "swr" | "miss" | "none";
lastModified: Date;
region: string;
requestId: string;
signature: string;
}
```
| Property | Type | Description |
| -------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cacheStatus` | `"ttl" \| "swr" \| "miss" \| "none" ` | The cache status of the response.
`ttl` indicates a cache hit within the `ttl` duration and no database query was executed
`swr` indicates a cache hit within the `swr` duration and the data is being refreshed by Accelerate in the background
`miss` indicates that both `ttl` and `swr` have expired and the database query was executed by the request
`none` indicates that no cache strategy was specified and the database query was executed by the request
|
| `lastModified` | `Date` | The date the response was last refreshed. |
| `region` | `String` | The data center region that received the request. |
| `requestId` | `String` | Unique identifier of the request. Useful for troubleshooting. |
| `signature` | `String` | The unique signature of the Prisma operation. |
$accelerate.invalidate [#accelerateinvalidate]
You can invalidate the cache using the [`$accelerate.invalidate` API](/accelerate).
To invalidate cached query results on-demand, a paid plan is required. Each plan has specific limits on the number of cache tag-based invalidations allowed per day, though there are no limits on calling the `$accelerate.invalidate` API itself. See our [pricing for more details](https://www.prisma.io/pricing#accelerate).
Example [#example]
To invalidate the query below:
```ts
await prisma.user.findMany({
where: {
email: {
contains: "alice@prisma.io",
},
},
cacheStrategy: {
swr: 60,
ttl: 60,
tags: ["emails_with_alice"], // [!code highlight]
},
});
```
You need to provide the cache tag in the `$accelerate.invalidate` API:
```ts
try {
await prisma.$accelerate.invalidate({
// [!code highlight]
tags: ["emails_with_alice"], // [!code highlight]
}); // [!code highlight]
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
// The .code property can be accessed in a type-safe manner
if (e.code === "P6003") {
console.log("The cache invalidation rate limit has been reached. Please try again later.");
}
}
throw e;
}
```
You can invalidate up to 5 tags per call.
$accelerate.invalidateAll [#accelerateinvalidateall]
You can invalidate the entire cache using the `$accelerate.invalidateAll` API.
Example [#example-1]
To invalidate the query below:
```ts
await prisma.user.findMany({
where: {
email: {
contains: "alice@prisma.io",
},
},
cacheStrategy: {
swr: 60,
ttl: 60,
tags: ["emails_with_alice"], // [!code highlight]
},
});
```
Just call the `$accelerate.invalidateAll` API:
```ts
try {
await prisma.$accelerate.invalidateAll(); // [!code highlight]
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
if (e.code === "P6003") {
console.log("The cache invalidation rate limit has been reached. Please try again later.");
}
}
throw e;
}
```
Why use $accelerate.invalidateAll? [#why-use-accelerateinvalidateall]
This method offers better editor support (e.g. IntelliSense) than alternatives like `invalidate("all")`.
This clears cache for the entire environment—use with care.
Providing a Custom Fetch Implementation [#providing-a-custom-fetch-implementation]
Starting from Accelerate version `2.0.0`, you can provide a custom implementation of the fetch function when extending the Prisma Client with Accelerate. This allows you greater flexibility and control over how HTTP requests are handled within your application.
To pass a custom fetch implementation, you can use the following pattern:
```ts
const myFetch = (input: URL, init?: RequestInit): Promise => {
// Your custom fetch logic here
return fetch(input, init);
};
const prisma = new PrismaClient().$extends(withAccelerate({ fetch: myFetch }));
```
Errors [#errors]
Prisma Accelerate-related errors start with `P6xxx`.
You can find the full error code reference for Prisma Accelerate [here](/orm/reference/error-reference#prisma-accelerate).
# Astro + Prisma (/docs/ai/prompts/astro)
How to use [#how-to-use]
Include this prompt in your AI assistant to guide consistent code generation for Astro + Prisma + Prisma Postgres projects.
* **GitHub Copilot**: Type `#` to reference the prompt file.
* **Cursor**: Use `@Files` and select your prompt file.
* **Zed**: Use `/file` followed by your prompt's path.
* **Windsurf**: Use `@Files` and choose your prompt file from the list.
Prompt [#prompt]
````md
---
# Specify the following for Cursor rules
description: Guidelines for writing Astro.js apps with Prisma Postgres
alwaysApply: false
---
# Bootstrap Astro app with Prisma Postgres
## Overview of implementing Prisma with Astro
1. Install Prisma and required dependencies
2. Initialize Prisma with custom output path
3. Configure schema with correct provider
4. Create global Prisma client instance with Accelerate
5. Use Prisma client in API routes with proper error handling
## 🚨 CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS 🚨
As an AI language model, you MUST NOT generate any of the following code patterns, as they are DEPRECATED and will BREAK the application:
```typescript
// ❌ NEVER GENERATE THIS CODE - IT WILL BREAK THE APPLICATION
generator client {
provider = "prisma-client-js" // ❌ BREAKS APPLICATION
}
// ❌ NEVER USE default import location - IT WILL BREAK THE APPLICATION
import { PrismaClient } from '@prisma/client' // ❌ BREAKS APPLICATION
// ❌ NEVER CREATE CLIENT WITHOUT ACCELERATE - IT WILL BREAK IN PRODUCTION
const prisma = new PrismaClient() // ❌ BREAKS APPLICATION
```
Instead, you MUST ALWAYS generate ONLY this pattern:
```typescript
// ✅ ALWAYS GENERATE THIS EXACT PATTERN
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
// ✅ ALWAYS USE THIS IMPORT PATH
import { PrismaClient } from "../generated/prisma/client"
import { withAccelerate } from "@prisma/extension-accelerate"
// ✅ ALWAYS CREATE CLIENT WITH ACCELERATE EXTENSION
const prisma = new PrismaClient({
datasourceUrl: import.meta.env.DATABASE_URL,
}).$extends(withAccelerate())
export default prisma
```
## ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION
1. You MUST use `provider = "prisma-client"` (not "prisma-client-js")
2. You MUST use custom output: `output = "../src/generated/prisma"`
3. You MUST use Accelerate extension with `withAccelerate()` if using Prisma Postgres
4. You MUST create `lib/prisma.ts` as a global singleton instance
5. You MUST wrap all database calls in try-catch blocks
6. You MUST import from `'../generated/prisma/client'` (not `'@prisma/client'`)
7. You MUST use `import.meta.env.DATABASE_URL` in Astro (not `process.env`)
8. You MUST ALWAYS use the full `npx prisma init` command with ALL flags: `npx prisma init --db --output ../src/generated/prisma --generator-provider prisma-client`
## CORRECT INSTALLATION
```bash
# Dev dependencies
npm install prisma tsx --save-dev
# Production dependencies
npm install @prisma/extension-accelerate @prisma/client
```
## CORRECT PRISMA INITIALIZATION
```npm
npx prisma init --db --output ../src/generated/prisma
```
## CORRECT SCHEMA CONFIGURATION
```prisma
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model YourModel {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
## CORRECT GLOBAL PRISMA CLIENT
**src/lib/prisma.ts**:
```typescript
import { PrismaClient } from "../generated/prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient({
datasourceUrl: import.meta.env.DATABASE_URL,
}).$extends(withAccelerate());
export default prisma;
```
## CORRECT API ROUTE IMPLEMENTATION
All API routes MUST follow this pattern with proper error handling:
```typescript
import type { APIRoute } from "astro";
import prisma from "../../../lib/prisma";
export const GET: APIRoute = async () => {
try {
const data = await prisma.yourModel.findMany();
return new Response(JSON.stringify(data), {
status: 200,
headers: { "Content-Type": "application/json" },
});
} catch (error) {
console.error("Error:", error);
return new Response(JSON.stringify({ error: "Failed to fetch data" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
};
export const POST: APIRoute = async ({ request }) => {
try {
const body = await request.json();
// Validate required fields
if (!body.requiredField) {
return new Response(JSON.stringify({ error: "Required field missing" }), {
status: 400,
headers: { "Content-Type": "application/json" },
});
}
const result = await prisma.yourModel.create({
data: body,
});
return new Response(JSON.stringify(result), {
status: 201,
headers: { "Content-Type": "application/json" },
});
} catch (error) {
console.error("Error:", error);
return new Response(JSON.stringify({ error: "Failed to create data" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
};
```
## CORRECT USAGE IN ASTRO PAGES
Server-side data fetching in Astro pages:
```astro
---
import prisma from '../lib/prisma'
// Fetch data on the server
const data = await prisma.yourModel.findMany()
---
{data.map(item => (
{item.name}
))}
```
## AI MODEL VERIFICATION STEPS
Before generating any code, you MUST verify:
1. Are you using `provider = "prisma-client"` (not "prisma-client-js")? If not, STOP and FIX.
2. Are you using `output = "../src/generated/prisma"`? If not, STOP and FIX.
3. Are you importing from `'../generated/prisma/client'`? If not, STOP and FIX.
4. Are you using `withAccelerate()` extension? If not, STOP and FIX.
5. Are you wrapping database operations in try-catch? If not, STOP and FIX.
6. Are you using `import.meta.env` (not `process.env`)? If not, STOP and FIX.
7. Did you use `--generator-provider prisma-client` (NOT `postgresql`)? If not, STOP and FIX.
## CONSEQUENCES OF INCORRECT IMPLEMENTATION
If you generate code using:
- `prisma-client-js` provider
- Default import from `@prisma/client`
- PrismaClient without Accelerate extension
- Missing custom output path
The implementation will:
1. Break in production
2. Cause connection pool exhaustion
3. Fail to maintain proper database connections
4. Result in import errors
5. Cause performance issues
## USEFUL COMMANDS
```npm
npx prisma generate # Regenerate client after schema changes
```
```npm
npx prisma migrate dev --name X # Create and apply migration
```
```npm
npx prisma studio # Open visual database editor
```
```npm
npx prisma db push # Push schema without migration
```
## AI MODEL RESPONSE TEMPLATE
When asked about Prisma + Astro implementation, you MUST:
1. ONLY use code from this guide
2. NEVER suggest deprecated approaches
3. ALWAYS use the exact patterns shown above
4. VERIFY your response against the patterns shown here
5. ALWAYS include error handling in API routes
6. ALWAYS use the global prisma instance from `lib/prisma.ts`
Remember: There are NO EXCEPTIONS to these rules.
````
Running the application [#running-the-application]
Get your application running locally in three quick steps:
**1. Generate the Prisma Client:**
```bash
npx prisma generate --no-engine
```
**2. View your database in Prisma Studio:**
```bash
npm run db:studio
```
Prisma Studio opens at `localhost:5555` where you can inspect your `User` table and see the test user stored in your database.
**3. Start your Next.js development server:**
```bash
npm run dev
```
Visit `http://localhost:3000` to see your Next.js application live, displaying your first user fetched directly from your Prisma Postgres database!
# Next.js + Prisma (/docs/ai/prompts/nextjs)
Prerequisites [#prerequisites]
Before using this prompt, you need to create a new Next.js project:
```bash
npx create-next-app@latest my-app
cd my-app
```
When prompted, select the following recommended options:
* **TypeScript**: Yes
* **ESLint**: Yes
* **Tailwind CSS**: Yes (optional)
* **`src/` directory**: No
* **App Router**: Yes
* **Turbopack**: Yes (optional)
* **Import alias**: Use default (`@/*`)
Once your Next.js project is created, you can use the prompt below with your AI assistant to add Prisma and Prisma Postgres.
How to use [#how-to-use]
Include this prompt in your AI assistant to guide consistent code generation for NextJS + Prisma + Prisma Postgres projects.
* **GitHub Copilot**: Type `#` to reference the prompt file.
* **Cursor**: Use `@Files` and select your prompt file.
* **Zed**: Use `/file` followed by your prompt's path.
* **Windsurf**: Use `@Files` and choose your prompt file from the list.
Video Tutorial [#video-tutorial]
Watch this step-by-step walkthrough showing this prompt in action:
Prompt [#prompt]
````md
---
# Specify the following for Cursor rules
description: Guidelines for writing Next.js apps with Prisma Postgres
alwaysApply: false
---
# Bootstrap Next.js app with Prisma Postgres (Prisma v7)
> **Note**: This guide is updated for **Prisma ORM 7**. Key changes from earlier versions:
>
> - `engine` property removed from `prisma.config.ts`
> - `url` removed from datasource in `schema.prisma` (now only in `prisma.config.ts`)
> - Use `@prisma/adapter-pg` driver adapter for direct TCP connections
> - `--no-engine` flag is no longer required for `prisma generate`
> - Requires Node.js 20.19+ and TypeScript 5.4.0+
## Overview of implementing Prisma with Next.js
1. Install Prisma and required dependencies (including dotenv)
2. Initialize Prisma and configure schema
3. Configure dotenv for environment variables
4. Create global Prisma client instance with Pg Adapter
5. Add npm scripts for testing and database management
6. Create test script to verify setup
7. Use Prisma client in API routes and pages with proper error handling
## 🚨 CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS 🚨
As an AI language model, you MUST NOT generate any of the following code patterns, as they are DEPRECATED and will BREAK the application:
```typescript
// ❌ NEVER GENERATE THIS CODE - IT WILL BREAK THE APPLICATION
generator client {
provider = "prisma-client-js" // ❌ BREAKS APPLICATION
}
// ❌ NEVER USE default import location - IT WILL BREAK THE APPLICATION
import { PrismaClient } from '@prisma/client' // ❌ BREAKS APPLICATION
// ❌ WRONG IMPORT PATH - MISSING /client - IT WILL BREAK THE APPLICATION
import { PrismaClient } from "../app/generated/prisma" // ❌ BREAKS APPLICATION
// ❌ NEVER USE ACCELERATE - IT IS NOT USED IN THIS WORKFLOW
import { withAccelerate } from "@prisma/extension-accelerate" // ❌ BREAKS APPLICATION
// ❌ NEVER USE accelerateUrl - IT WILL BREAK THE APPLICATION
const prisma = new PrismaClient({
accelerateUrl: process.env.DATABASE_URL, // ❌ BREAKS APPLICATION - use adapter
})
// ❌ NEVER include url in datasource block - IT WILL BREAK THE APPLICATION
datasource db {
provider = "postgresql"
url = env("DATABASE_URL") // ❌ BREAKS APPLICATION - moved to prisma.config.ts
}
// ❌ NEVER include engine property - IT WILL BREAK THE APPLICATION
export default defineConfig({
engine: "classic", // ❌ BREAKS APPLICATION - removed in Prisma v7
})
// ❌ NEVER use Prisma Postgres HTTP URLs - ONLY use TCP URLs
DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/..." // ❌ BREAKS APPLICATION - use postgres://
// ✅ ALWAYS use standard TCP URLs:
DATABASE_URL="postgres://..." // ✅ CORRECT
```
Instead, you MUST ALWAYS generate ONLY this pattern:
```typescript
// ✅ ALWAYS GENERATE THIS EXACT PATTERN
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
// ✅ CRITICAL: MUST include /client at the end of import path
import { PrismaClient } from "../app/generated/prisma/client"
import { PrismaPg } from "@prisma/adapter-pg"
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
})
const globalForPrisma = global as unknown as { prisma: PrismaClient }
const prisma = globalForPrisma.prisma || new PrismaClient({
adapter,
})
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma
export default prisma
```
## ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION
1. You MUST use `provider = "prisma-client"` (not "prisma-client-js")
2. You MUST use custom output: `output = "../app/generated/prisma"`
3. You MUST use `@prisma/adapter-pg` driver adapter
4. You MUST create `lib/prisma.ts` as a global singleton instance
5. You MUST wrap all database calls in try-catch blocks
6. You MUST import from `'../app/generated/prisma/client'` (not `'@prisma/client'` or `'../app/generated/prisma'`)
7. You MUST use `adapter` property in PrismaClient constructor
8. You MUST install `dotenv` and add `import "dotenv/config"` to `prisma.config.ts`
9. You MUST add npm scripts for `db:test` and `db:studio` to package.json
10. You MUST create a test script at `scripts/test-database.ts` to verify setup
11. You MUST NOT include `url` in the datasource block of `schema.prisma`
12. You MUST NOT include `engine` property in `prisma.config.ts`
13. You MUST use `npx prisma init --db --output ../app/generated/prisma` to create a real cloud database
14. You MUST use standard TCP URLs (`postgres://...`) in .env
15. You MUST NOT use `accelerateUrl` or `withAccelerate`
## VERSION REQUIREMENTS
- **Node.js**: 20.19 or higher (Node.js 18 is NOT supported)
- **TypeScript**: 5.4.0 or higher (5.9.x recommended)
- **Prisma**: 7.0.0 or higher
## CORRECT INSTALLATION
```bash
# Dev dependencies
npm install prisma tsx --save-dev
# Production dependencies
npm install @prisma/adapter-pg @prisma/client dotenv
```
## CORRECT PRISMA INITIALIZATION
> **FOR AI ASSISTANTS**: This command is **interactive** and requires user input. You **MUST ask the user to run this command manually** in their own terminal, then **wait for them to confirm completion** before proceeding with the next steps. Do NOT attempt to run this command yourself.
```bash
# Initialize Prisma AND create a real Prisma Postgres cloud database
npx prisma init --db --output ../app/generated/prisma
```
This command:
- Authenticates you with Prisma Console (if needed)
- Prompts for **region** and **project name**
- **Creates a cloud Prisma Postgres database**
- Generates:
- `prisma/schema.prisma` (with correct output path)
- `prisma.config.ts` (with dotenv import)
- **`.env` with a `DATABASE_URL`**
**IMPORTANT**: Ensure the generated `.env` uses a `postgres://` URL scheme. If it generates `prisma+postgres://`, replace it with the standard TCP connection string available in the Prisma Console.
```text
DATABASE_URL="postgres://..."
```
**IMPORTANT**: Do NOT use `npx prisma init` without `--db` as this only creates local files without a database.
## CORRECT PRISMA CONFIG (prisma.config.ts)
When using `npx prisma init --db`, the `prisma.config.ts` is **auto-generated** with the correct configuration:
```typescript
import "dotenv/config"; // ✅ Auto-included by prisma init --db
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
// ✅ NO engine property - removed in Prisma v7
datasource: {
url: env("DATABASE_URL"),
},
});
```
**Note**: If you need to manually create this file, ensure `import "dotenv/config"` is at the top.
## CORRECT SCHEMA CONFIGURATION (prisma/schema.prisma)
Update the generated `prisma/schema.prisma` file:
```prisma
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql"
// ✅ NO url here - now configured in prisma.config.ts
}
// Example User model for testing
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
## CORRECT GLOBAL PRISMA CLIENT
Create `lib/prisma.ts` file:
```typescript
import { PrismaClient } from "../app/generated/prisma/client"; // ✅ CRITICAL: Include /client
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const globalForPrisma = global as unknown as { prisma: PrismaClient };
const prisma =
globalForPrisma.prisma ||
new PrismaClient({
adapter,
});
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
export default prisma;
```
## ADD NPM SCRIPTS TO PACKAGE.JSON
Update your `package.json` to include these scripts:
```json
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint",
"db:test": "tsx scripts/test-database.ts",
"db:studio": "prisma studio"
}
}
```
## CREATE TEST SCRIPT
Create `scripts/test-database.ts` to verify your setup:
```typescript
import "dotenv/config"; // ✅ CRITICAL: Load environment variables
import prisma from "../lib/prisma";
async function testDatabase() {
console.log("🔍 Testing Prisma Postgres connection...\n");
try {
// Test 1: Check connection
console.log("✅ Connected to database!");
// Test 2: Create a test user
console.log("\n📝 Creating a test user...");
const newUser = await prisma.user.create({
data: {
email: "demo@example.com",
name: "Demo User",
},
});
console.log("✅ Created user:", newUser);
// Test 3: Fetch all users
console.log("\n📋 Fetching all users...");
const allUsers = await prisma.user.findMany();
console.log(`✅ Found ${allUsers.length} user(s):`);
allUsers.forEach((user) => {
console.log(` - ${user.name} (${user.email})`);
});
console.log("\n🎉 All tests passed! Your database is working perfectly.\n");
} catch (error) {
console.error("❌ Error:", error);
process.exit(1);
}
}
testDatabase();
```
## CORRECT API ROUTE IMPLEMENTATION (App Router)
Create `app/api/users/route.ts` with GET and POST handlers:
```typescript
import { NextRequest, NextResponse } from "next/server";
import prisma from "../../../lib/prisma";
export async function GET(request: NextRequest) {
try {
const users = await prisma.user.findMany();
return NextResponse.json(users);
} catch (error) {
console.error("Error fetching users:", error);
return NextResponse.json({ error: "Failed to fetch users" }, { status: 500 });
}
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const user = await prisma.user.create({
data: {
email: body.email,
name: body.name,
},
});
return NextResponse.json(user, { status: 201 });
} catch (error) {
console.error("Error creating user:", error);
return NextResponse.json({ error: "Failed to create user" }, { status: 500 });
}
}
```
## CORRECT USAGE IN SERVER COMPONENTS
Update `app/page.tsx` to display users from the database:
```typescript
import prisma from "../lib/prisma";
export default async function Home() {
let users: Array<{
id: number;
email: string;
name: string | null;
createdAt: Date;
updatedAt: Date;
}> = [];
let error = null;
try {
users = await prisma.user.findMany({
orderBy: {
createdAt: "desc",
},
});
} catch (e) {
console.error("Error fetching users:", e);
error =
"Failed to load users. Make sure your DATABASE_URL is configured.";
}
return (
Users from Database
{error ? (
{error}
) : users.length === 0 ? (
No users yet. Create one using the API at /api/users
) : (
{users.map((user) => (
{user.name || "No name"}
{user.email}
))}
)}
);
}
```
## COMPLETE SETUP WORKFLOW
User should follow these steps (AI should provide these instructions):
1. **Install dependencies**:
```npm
npm install prisma tsx --save-dev
```
```npm
npm install @prisma/adapter-pg @prisma/client dotenv
```
2. **Initialize Prisma AND create Prisma Postgres database** (⚠️ USER MUST RUN MANUALLY):
> **AI ASSISTANT**: Ask the user to run this command in their own terminal. This is interactive and requires user input. Wait for the user to confirm completion before continuing.
```npm
npx prisma init --db --output ../app/generated/prisma
```
The user should follow the terminal prompts to:
- Authenticate with Prisma Console (if needed)
- Choose a region (e.g., us-east-1)
- Name your project
Once complete, this creates `prisma/schema.prisma`, `prisma.config.ts`, AND `.env` with the `DATABASE_URL`.
**User should confirm when done** so the AI can proceed with the next steps.
3. **Verify `.env` was created** - Ensure `DATABASE_URL` uses `postgres://`. If it uses `prisma+postgres://`, change it to the TCP connection string.
```text
DATABASE_URL="postgres://..."
```
**Do NOT invent or manually change this URL. Use the one from Prisma Console.**
4. **Update `prisma/schema.prisma`** - Add the User model (generator and datasource are already configured):
```prisma
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
5. **Create `lib/prisma.ts`** with correct import path including `/client` and using `@prisma/adapter-pg`.
6. **Add npm scripts** to `package.json` for `db:test` and `db:studio`
7. **Create `scripts/test-database.ts`** test script
8. **Push schema to database**:
```npm
npx prisma db push
```
9. **Generate Prisma Client**:
```npm
npx prisma generate
```
10. **Test the setup**:
```bash
npm run db:test
```
11. **Start development server**:
```bash
npm run dev
```
## AI MODEL VERIFICATION STEPS
Before generating any code, you MUST verify:
1. Are you using `provider = "prisma-client"` (not "prisma-client-js")? If not, STOP and FIX.
2. Are you using `output = "../app/generated/prisma"`? If not, STOP and FIX.
3. Are you importing from `'../app/generated/prisma/client'` (with `/client`)? If not, STOP and FIX.
4. Did you add `import "dotenv/config"` to `prisma.config.ts`? If not, STOP and FIX.
5. Did you add `import "dotenv/config"` to `scripts/test-database.ts`? If not, STOP and FIX.
6. Are you using `@prisma/adapter-pg`? If not, STOP and FIX.
7. Are you using `adapter` property in PrismaClient constructor? If not, STOP and FIX.
8. Are you wrapping database operations in try-catch? If not, STOP and FIX.
9. Did you create the test script at `scripts/test-database.ts`? If not, STOP and FIX.
10. Did you add `db:test` and `db:studio` scripts to package.json? If not, STOP and FIX.
11. Did you remove `url` from the datasource block in `schema.prisma`? If not, STOP and FIX.
12. Did you remove `engine` property from `prisma.config.ts`? If not, STOP and FIX.
13. Are you using `npx prisma init --db` (not just `npx prisma init`)? If not, STOP and FIX.
14. Is the DATABASE_URL a TCP URL (`postgres://...`)? If it's a `prisma+postgres://` URL, STOP and FIX.
15. Did Prisma generate the `.env` file? If you invented the URL manually, STOP and FIX.
## CONSEQUENCES OF INCORRECT IMPLEMENTATION
If you generate code using:
- `prisma-client-js` provider → **CLIENT GENERATION FAILS**
- Wrong import path (missing `/client`) → **MODULE NOT FOUND ERROR**
- Missing `import "dotenv/config"` in prisma.config.ts → **DATABASE_URL NOT FOUND ERROR**
- Missing `import "dotenv/config"` in test scripts → **ENVIRONMENT VARIABLE ERROR**
- Default import from `@prisma/client` → **IMPORT ERROR**
- Using `accelerateUrl` or `withAccelerate` → **UNNECESSARY ACCELERATE DEPENDENCY / CONFIG ERROR**
- Missing custom output path → **WRONG CLIENT GENERATED**
- Including `url` in datasource block → **DEPRECATED CONFIGURATION ERROR**
- Including `engine` property → **DEPRECATED CONFIGURATION ERROR**
- Using local URL (`postgres://localhost:...`) → **VERSION INCOMPATIBILITY ERRORS WITH Prisma v7**
- Using `npx prisma init` without `--db` → **NO DATABASE CREATED, ONLY LOCAL FILES**
- Manually inventing DATABASE_URL → **INVALID CONNECTION STRING ERRORS**
The implementation will:
1. Break immediately with module errors
2. Fail to read environment variables
3. Cause connection pool exhaustion in production
4. Result in import errors that prevent compilation
5. Cause performance issues and connection failures
6. Fail with "HTTP connection string is not supported" errors when using local URLs
## USEFUL COMMANDS
```bash
# After changing schema
npx prisma generate # Regenerate client (--no-engine flag no longer needed)
# Push schema to database (no migrations)
npx prisma db push
# Test database connection
npm run db:test
# Open visual database editor
npm run db:studio
# Create and apply migrations (for production)
npx prisma migrate dev --name your_migration_name
```
## TESTING WORKFLOW
After setup, test with these steps:
1. **Test database connection**:
```bash
npm run db:test
```
Should create a demo user and display it.
2. **Open Prisma Studio**:
```bash
npm run db:studio
```
Visual interface at `localhost:5555` to view/edit data.
3. **Test API routes**:
```bash
# Create a user via API
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","name":"Test User"}'
# Get all users
curl http://localhost:3000/api/users
```
4. **View in browser**:
Open `localhost:3000` to see users displayed on the homepage.
## AI MODEL RESPONSE TEMPLATE
When asked about Prisma + Next.js implementation, you MUST:
1. ONLY use code patterns from this guide
2. NEVER suggest deprecated approaches
3. ALWAYS use the exact patterns shown above
4. ALWAYS include `/client` in import paths
5. ALWAYS add `import "dotenv/config"` to prisma.config.ts
6. ALWAYS add `import "dotenv/config"` to test scripts
7. ALWAYS create the test script at `scripts/test-database.ts`
8. ALWAYS add npm scripts for `db:test` and `db:studio`
9. ALWAYS include error handling in API routes and server components
10. ALWAYS use the global prisma instance from `lib/prisma.ts`
11. ALWAYS use `@prisma/adapter-pg` and `adapter` property
12. NEVER include `url` in the datasource block of schema.prisma
13. NEVER include `engine` property in prisma.config.ts
14. ALWAYS ask the user to run `npx prisma init --db --output ../app/generated/prisma` **manually in their own terminal** (this command is interactive and requires user input for region and project name)
15. ALWAYS wait for user confirmation after they run the interactive `prisma init --db` command before proceeding
16. NEVER attempt to run interactive commands yourself - ask the user to do it
17. NEVER use `prisma+postgres://` URLs - ONLY `postgres://` TCP URLs
18. NEVER manually invent or fabricate DATABASE_URL values
19. ALWAYS let Prisma generate the `.env` file with the real DATABASE_URL (and ensure it's correct type)
20. VERIFY your response against ALL the patterns shown here before responding
Remember: There are NO EXCEPTIONS to these rules. Every requirement is MANDATORY for the setup to work.
````
# Nuxt + Prisma (/docs/ai/prompts/nuxt)
Prerequisites [#prerequisites]
Before using this prompt, you need to create a new Nuxt project:
```bash
npx nuxi@latest init hello-prisma
cd hello-prisma
```
Once your Nuxt project is created, you can use the prompt below with your AI assistant to add Prisma and Prisma Postgres.
How to use [#how-to-use]
Include this prompt in your AI assistant to guide consistent code generation for Nuxt + Prisma + Prisma Postgres projects.
* **GitHub Copilot**: Type `#` to reference the prompt file.
* **Cursor**: Use `@Files` and select your prompt file.
* **Zed**: Use `/file` followed by your prompt's path.
* **Windsurf**: Use `@Files` and choose your prompt file from the list.
Prompt [#prompt]
````md
---
# Specify the following for Cursor rules
description: Guidelines for writing Nuxt apps with Prisma Postgres
alwaysApply: false
---
# Bootstrap Nuxt app with Prisma Postgres (Prisma v7)
**Purpose:** Set up Prisma ORM with Prisma Postgres in a Nuxt project using the correct Prisma v7 patterns.
---
## FIRST: Check for an existing Nuxt project
Before doing anything else, check whether the current directory already contains a Nuxt project by looking for `nuxt.config.ts`.
- **If `nuxt.config.ts` exists** → A project is already set up. Skip to "Overview" below.
- **If the directory does NOT contain `nuxt.config.ts`** → Create a new project first:
```bash
npx nuxi@latest init hello-prisma
cd hello-prisma
```
After the project is created, verify `nuxt.config.ts` exists before continuing.
---
> **Note**: This guide is updated for **Prisma ORM 7**. Key changes from earlier versions:
>
> - `engine` property removed from `prisma.config.ts`
> - `url` removed from datasource in `schema.prisma` (now only in `prisma.config.ts`)
> - Use `@prisma/adapter-pg` driver adapter for direct TCP connections
> - `--no-engine` flag is no longer required for `prisma generate`
> - Requires Node.js 20.19+ and TypeScript 5.4.0+
## Overview of implementing Prisma with Nuxt
1. Ensure a Nuxt project exists (see above)
2. Install Prisma and required dependencies (including dotenv and pg)
3. Initialize Prisma and configure schema
4. Configure dotenv for environment variables
5. Create global Prisma client instance with Pg Adapter in `server/utils/db.ts`
6. Create Nuxt API routes using `defineEventHandler`
7. Create a Vue page to display data
8. Add npm scripts for testing and database management
9. Create test script to verify setup
## 🚨 CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS 🚨
As an AI language model, you MUST NOT generate any of the following code patterns, as they are DEPRECATED and will BREAK the application:
```typescript
// ❌ NEVER GENERATE THIS CODE - IT WILL BREAK THE APPLICATION
generator client {
provider = "prisma-client-js" // ❌ BREAKS APPLICATION
}
// ❌ NEVER USE default import location - IT WILL BREAK THE APPLICATION
import { PrismaClient } from '@prisma/client' // ❌ BREAKS APPLICATION
// ❌ WRONG IMPORT PATH - MISSING /client - IT WILL BREAK THE APPLICATION
import { PrismaClient } from "../../prisma/generated" // ❌ BREAKS APPLICATION
// ❌ NEVER USE ACCELERATE - IT IS NOT USED IN THIS WORKFLOW
import { withAccelerate } from "@prisma/extension-accelerate" // ❌ BREAKS APPLICATION
// ❌ NEVER USE accelerateUrl - IT WILL BREAK THE APPLICATION
const prisma = new PrismaClient({
accelerateUrl: process.env.DATABASE_URL, // ❌ BREAKS APPLICATION - use adapter
})
// ❌ NEVER include url in datasource block - IT WILL BREAK THE APPLICATION
datasource db {
provider = "postgresql"
url = env("DATABASE_URL") // ❌ BREAKS APPLICATION - moved to prisma.config.ts
}
// ❌ NEVER include engine property - IT WILL BREAK THE APPLICATION
export default defineConfig({
engine: "classic", // ❌ BREAKS APPLICATION - removed in Prisma v7
})
// ❌ NEVER use Prisma Postgres HTTP URLs - ONLY use TCP URLs
DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/..." // ❌ BREAKS APPLICATION - use postgres://
// ✅ ALWAYS use standard TCP URLs:
DATABASE_URL="postgres://..." // ✅ CORRECT
// ❌ NEVER create PrismaClient without adapter - IT WILL BREAK THE APPLICATION
const prisma = new PrismaClient() // ❌ BREAKS APPLICATION
```
Instead, you MUST ALWAYS generate ONLY this pattern:
```typescript
// ✅ ALWAYS GENERATE THIS EXACT PATTERN
generator client {
provider = "prisma-client"
output = "./generated"
}
// ✅ CRITICAL: MUST include /client at the end of import path
import { PrismaClient } from "../../prisma/generated/client"
import { PrismaPg } from "@prisma/adapter-pg"
const pool = new PrismaPg({ connectionString: process.env.DATABASE_URL! })
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient | undefined }
const prisma = globalForPrisma.prisma ?? new PrismaClient({ adapter: pool })
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma
export { prisma }
```
## ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION
1. You MUST use `provider = "prisma-client"` (not "prisma-client-js")
2. You MUST use custom output: `output = "./generated"` (relative to prisma directory)
3. You MUST use `@prisma/adapter-pg` driver adapter with `PrismaPg`
4. You MUST create `server/utils/db.ts` as a global singleton instance (Nuxt auto-imports from `server/utils/`)
5. You MUST wrap all database calls in try-catch blocks
6. You MUST import from `'../../prisma/generated/client'` (not `'@prisma/client'` or `'../../prisma/generated'`)
7. You MUST use `adapter` property in PrismaClient constructor
8. You MUST install `dotenv` and add `import "dotenv/config"` to `prisma.config.ts`
9. You MUST add npm scripts for `db:test` and `db:studio` to package.json
10. You MUST create a test script at `scripts/test-database.ts` to verify setup
11. You MUST NOT include `url` in the datasource block of `schema.prisma`
12. You MUST NOT include `engine` property in `prisma.config.ts`
13. You MUST use `npx prisma init --db --output ./generated` to create a real cloud database
14. You MUST use standard TCP URLs (`postgres://...`) in .env
15. You MUST NOT use `accelerateUrl` or `withAccelerate`
16. You MUST install `pg` and `@types/pg` as dependencies
## VERSION REQUIREMENTS
- **Node.js**: 20.19 or higher (Node.js 18 is NOT supported)
- **TypeScript**: 5.4.0 or higher (5.9.x recommended)
- **Prisma**: 7.0.0 or higher
## CORRECT INSTALLATION
```bash
# Production dependencies
npm install @prisma/client @prisma/adapter-pg pg dotenv
# Dev dependencies
npm install -D prisma @types/pg tsx
```
## CORRECT PRISMA INITIALIZATION
> **FOR AI ASSISTANTS**: This command is **interactive** and requires user input. You **MUST ask the user to run this command manually** in their own terminal, then **wait for them to confirm completion** before proceeding with the next steps. Do NOT attempt to run this command yourself.
```bash
# Initialize Prisma AND create a real Prisma Postgres cloud database
npx prisma init --db --output ./generated
```
This command:
- Authenticates you with Prisma Console (if needed)
- Prompts for **region** and **project name**
- **Creates a cloud Prisma Postgres database**
- Generates:
- `prisma/schema.prisma` (with correct output path)
- `prisma.config.ts` (with dotenv import)
- **`.env` with a `DATABASE_URL`**
**IMPORTANT**: Ensure the generated `.env` uses a `postgres://` URL scheme. If it generates `prisma+postgres://`, replace it with the standard TCP connection string available in the Prisma Console.
```text
DATABASE_URL="postgres://..."
```
**IMPORTANT**: Do NOT use `npx prisma init` without `--db` as this only creates local files without a database.
## CORRECT PRISMA CONFIG (prisma.config.ts)
When using `npx prisma init --db`, the `prisma.config.ts` is **auto-generated** with the correct configuration:
```typescript
import "dotenv/config"; // ✅ Auto-included by prisma init --db
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx ./prisma/seed.ts",
},
// ✅ NO engine property - removed in Prisma v7
datasource: {
url: env("DATABASE_URL"),
},
});
```
**Note**: If you need to manually create this file, ensure `import "dotenv/config"` is at the top.
## CORRECT SCHEMA CONFIGURATION (prisma/schema.prisma)
Update the generated `prisma/schema.prisma` file:
```prisma
generator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "postgresql"
// ✅ NO url here - now configured in prisma.config.ts
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
```
## CORRECT GLOBAL PRISMA CLIENT
Create `server/utils/db.ts` file. Nuxt auto-imports exports from `server/utils/`, making `prisma` available in all server API routes without explicit imports:
```typescript
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "../../prisma/generated/client"; // ✅ CRITICAL: Include /client
const prismaClientSingleton = () => {
const pool = new PrismaPg({ connectionString: process.env.DATABASE_URL! });
return new PrismaClient({ adapter: pool });
};
type PrismaClientSingleton = ReturnType;
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClientSingleton | undefined;
};
export const prisma = globalForPrisma.prisma ?? prismaClientSingleton();
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
```
## ADD NPM SCRIPTS TO PACKAGE.JSON
Update your `package.json` to include these scripts:
```json
{
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "prisma generate && nuxt prepare",
"db:test": "tsx scripts/test-database.ts",
"db:studio": "prisma studio"
}
}
```
## CREATE TEST SCRIPT
Create `scripts/test-database.ts` to verify your setup:
```typescript
import "dotenv/config"; // ✅ CRITICAL: Load environment variables
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "../prisma/generated/client";
const pool = new PrismaPg({ connectionString: process.env.DATABASE_URL! });
const prisma = new PrismaClient({ adapter: pool });
async function testDatabase() {
console.log("🔍 Testing Prisma Postgres connection...\n");
try {
// Test 1: Check connection
console.log("✅ Connected to database!");
// Test 2: Create a test user
console.log("\n📝 Creating a test user...");
const newUser = await prisma.user.create({
data: {
email: "demo@example.com",
name: "Demo User",
},
});
console.log("✅ Created user:", newUser);
// Test 3: Fetch all users
console.log("\n📋 Fetching all users...");
const allUsers = await prisma.user.findMany();
console.log(`✅ Found ${allUsers.length} user(s):`);
allUsers.forEach((user) => {
console.log(` - ${user.name} (${user.email})`);
});
console.log("\n🎉 All tests passed! Your database is working perfectly.\n");
} catch (error) {
console.error("❌ Error:", error);
process.exit(1);
}
}
testDatabase();
```
## CORRECT API ROUTE IMPLEMENTATION
Nuxt uses file-based API routing in `server/api/`. The `prisma` instance is auto-imported from `server/utils/db.ts`.
Create `server/api/users.get.ts` to fetch users:
```typescript
export default defineEventHandler(async () => {
try {
const users = await prisma.user.findMany({
include: { posts: true },
});
return users;
} catch (error) {
console.error("Error fetching users:", error);
throw createError({
statusCode: 500,
statusMessage: "Failed to fetch users",
});
}
});
```
Create `server/api/users.post.ts` to create a user:
```typescript
export default defineEventHandler(async (event) => {
try {
const body = await readBody<{ name: string; email: string }>(event);
if (!body.email) {
throw createError({
statusCode: 400,
statusMessage: "Email is required",
});
}
const user = await prisma.user.create({
data: {
name: body.name,
email: body.email,
},
});
return user;
} catch (error) {
console.error("Error creating user:", error);
throw createError({
statusCode: 500,
statusMessage: "Failed to create user",
});
}
});
```
## CORRECT USAGE IN VUE PAGES
Update `app.vue` to display users from the database:
```html
Users
{{ user.name }} ({{ user.email }})
No users yet.
```
## COMPLETE SETUP WORKFLOW
User should follow these steps (AI should provide these instructions):
1. **Ensure a Nuxt project exists** — check for `nuxt.config.ts`. If missing, create one:
```bash
npx nuxi@latest init hello-prisma
cd hello-prisma
```
2. **Install dependencies**:
```bash
npm install @prisma/client @prisma/adapter-pg pg dotenv
```
```bash
npm install -D prisma @types/pg tsx
```
3. **Initialize Prisma AND create Prisma Postgres database** (⚠️ USER MUST RUN MANUALLY):
> **AI ASSISTANT**: Ask the user to run this command in their own terminal. This is interactive and requires user input. Wait for the user to confirm completion before continuing.
```bash
npx prisma init --db --output ./generated
```
The user should follow the terminal prompts to:
- Authenticate with Prisma Console (if needed)
- Choose a region (e.g., us-east-1)
- Name your project
Once complete, this creates `prisma/schema.prisma`, `prisma.config.ts`, AND `.env` with the `DATABASE_URL`.
**User should confirm when done** so the AI can proceed with the next steps.
4. **Verify `.env` was created** — Ensure `DATABASE_URL` uses `postgres://`. If it uses `prisma+postgres://`, change it to the TCP connection string.
```text
DATABASE_URL="postgres://..."
```
**Do NOT invent or manually change this URL. Use the one from Prisma Console.**
5. **Update `prisma/schema.prisma`** — Add the User and Post models (generator and datasource are already configured):
```prisma
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
```
6. **Create `server/utils/db.ts`** with correct import path including `/client` and using `@prisma/adapter-pg`.
7. **Add npm scripts** to `package.json` for `db:test`, `db:studio`, and `postinstall`
8. **Create `scripts/test-database.ts`** test script
9. **Create API routes** — `server/api/users.get.ts` and `server/api/users.post.ts`
10. **Update `app.vue`** to display users
11. **Push schema to database**:
```bash
npx prisma db push
```
12. **Generate Prisma Client**:
```bash
npx prisma generate
```
13. **Test the setup**:
```bash
npm run db:test
```
14. **Start development server**:
```bash
npm run dev
```
## AI MODEL VERIFICATION STEPS
Before generating any code, you MUST verify:
1. Does the current directory contain `nuxt.config.ts`? If not, create the project first.
2. Are you using `provider = "prisma-client"` (not "prisma-client-js")? If not, STOP and FIX.
3. Are you using `output = "./generated"`? If not, STOP and FIX.
4. Are you importing from `'../../prisma/generated/client'` (with `/client`)? If not, STOP and FIX.
5. Did you add `import "dotenv/config"` to `prisma.config.ts`? If not, STOP and FIX.
6. Did you add `import "dotenv/config"` to `scripts/test-database.ts`? If not, STOP and FIX.
7. Are you using `@prisma/adapter-pg` with `PrismaPg`? If not, STOP and FIX.
8. Are you using `adapter` property in PrismaClient constructor? If not, STOP and FIX.
9. Are you wrapping database operations in try-catch? If not, STOP and FIX.
10. Did you create the Prisma client in `server/utils/db.ts` (not `lib/prisma.ts`)? If not, STOP and FIX.
11. Did you create the test script at `scripts/test-database.ts`? If not, STOP and FIX.
12. Did you add `db:test` and `db:studio` scripts to package.json? If not, STOP and FIX.
13. Did you remove `url` from the datasource block in `schema.prisma`? If not, STOP and FIX.
14. Did you remove `engine` property from `prisma.config.ts`? If not, STOP and FIX.
15. Are you using `npx prisma init --db` (not just `npx prisma init`)? If not, STOP and FIX.
16. Is the DATABASE_URL a TCP URL (`postgres://...`)? If it's a `prisma+postgres://` URL, STOP and FIX.
17. Did Prisma generate the `.env` file? If you invented the URL manually, STOP and FIX.
18. Are you using Nuxt auto-imports (`defineEventHandler`, `readBody`, `createError`, `prisma`)? If not, STOP and FIX.
## CONSEQUENCES OF INCORRECT IMPLEMENTATION
If you generate code using:
- `prisma-client-js` provider → **CLIENT GENERATION FAILS**
- Wrong import path (missing `/client`) → **MODULE NOT FOUND ERROR**
- Missing `import "dotenv/config"` in prisma.config.ts → **DATABASE_URL NOT FOUND ERROR**
- Missing `import "dotenv/config"` in test scripts → **ENVIRONMENT VARIABLE ERROR**
- Default import from `@prisma/client` → **IMPORT ERROR**
- Using `accelerateUrl` or `withAccelerate` → **UNNECESSARY ACCELERATE DEPENDENCY / CONFIG ERROR**
- Missing custom output path → **WRONG CLIENT GENERATED**
- Including `url` in datasource block → **DEPRECATED CONFIGURATION ERROR**
- Including `engine` property → **DEPRECATED CONFIGURATION ERROR**
- Using local URL (`postgres://localhost:...`) → **VERSION INCOMPATIBILITY ERRORS WITH Prisma v7**
- Using `npx prisma init` without `--db` → **NO DATABASE CREATED, ONLY LOCAL FILES**
- Manually inventing DATABASE_URL → **INVALID CONNECTION STRING ERRORS**
- Creating client in `lib/prisma.ts` instead of `server/utils/db.ts` → **NOT AUTO-IMPORTED IN NUXT SERVER ROUTES**
- Missing `pg` dependency → **ADAPTER INITIALIZATION FAILURE**
The implementation will:
1. Break immediately with module errors
2. Fail to read environment variables
3. Cause connection pool exhaustion in production
4. Result in import errors that prevent compilation
5. Cause performance issues and connection failures
6. Fail with "HTTP connection string is not supported" errors when using local URLs
## USEFUL COMMANDS
```bash
# After changing schema
npx prisma generate # Regenerate client (--no-engine flag no longer needed)
# Push schema to database (no migrations)
npx prisma db push
# Test database connection
npm run db:test
# Open visual database editor
npm run db:studio
# Create and apply migrations (for production)
npx prisma migrate dev --name your_migration_name
```
## TESTING WORKFLOW
After setup, test with these steps:
1. **Test database connection**:
```bash
npm run db:test
```
Should create a demo user and display it.
2. **Open Prisma Studio**:
```bash
npm run db:studio
```
Visual interface at `localhost:5555` to view/edit data.
3. **Test API routes**:
```bash
# Create a user via API
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","name":"Test User"}'
# Get all users
curl http://localhost:3000/api/users
```
4. **View in browser**:
Open `localhost:3000` to see users displayed on the homepage.
## AI MODEL RESPONSE TEMPLATE
When asked about Prisma + Nuxt implementation, you MUST:
1. ONLY use code patterns from this guide
2. NEVER suggest deprecated approaches
3. ALWAYS use the exact patterns shown above
4. ALWAYS include `/client` in import paths
5. ALWAYS add `import "dotenv/config"` to prisma.config.ts
6. ALWAYS add `import "dotenv/config"` to test scripts
7. ALWAYS create the Prisma client in `server/utils/db.ts` (Nuxt auto-imports)
8. ALWAYS create the test script at `scripts/test-database.ts`
9. ALWAYS add npm scripts for `db:test` and `db:studio`
10. ALWAYS include error handling in API routes using `createError`
11. ALWAYS use the auto-imported `prisma` instance in server routes
12. ALWAYS use `@prisma/adapter-pg` with `PrismaPg` and `adapter` property
13. NEVER include `url` in the datasource block of schema.prisma
14. NEVER include `engine` property in prisma.config.ts
15. ALWAYS ask the user to run `npx prisma init --db --output ./generated` **manually in their own terminal** (this command is interactive and requires user input for region and project name)
16. ALWAYS wait for user confirmation after they run the interactive `prisma init --db` command before proceeding
17. NEVER attempt to run interactive commands yourself - ask the user to do it
18. NEVER use `prisma+postgres://` URLs - ONLY `postgres://` TCP URLs
19. NEVER manually invent or fabricate DATABASE_URL values
20. ALWAYS let Prisma generate the `.env` file with the real DATABASE_URL (and ensure it's correct type)
21. VERIFY your response against ALL the patterns shown here before responding
Remember: There are NO EXCEPTIONS to these rules. Every requirement is MANDATORY for the setup to work.
````
# Migrate to Prisma v7 (/docs/ai/prompts/prisma-7)
How to use [#how-to-use]
Include this prompt in your AI assistant to guide in upgrading to Prisma ORM 7.0.
* **GitHub Copilot**: Type `#` to reference the prompt file.
* **Cursor**: Use `@Files` and select your prompt file.
* **Zed**: Use `/file` followed by your prompt's path.
* **Windsurf**: Use `@Files` and choose your prompt file from the list.
Video Tutorial [#video-tutorial]
Watch this video showing this prompt in action:
Prompt [#prompt]
````md
---
# Specify the following for Cursor rules
description: Guidelines for migrating an app to Prisma ORM v7
alwaysApply: false
---
# Prisma v6 → v7 Migration Assistant
**Role:** You are a precise, changeset-oriented code migration assistant. Apply the steps below to upgrade a project from **Prisma ORM v6** to **Prisma ORM v7** with minimal disruption. Work in small, re-viewable steps and explain each change briefly. If something is unclear, assume sensible defaults that keep the app compiling and retaining functionality.
## Ground Rules
- Never introduce Prisma Accelerate or HTTP/WebSocket drivers on your own.
- Do **not** remove Prisma Accelerate automatically.
- **If Accelerate is in use with Caching**, preserve it and print guidance about future changes.
- **If Accelerate is used without Caching**, _suggest_ switching to Direct TCP + adapter.
- Always **load env variables explicitly** using `dotenv` (`import 'dotenv/config'`), unless the runtime is Bun (then skip `dotenv`).
- Keep TypeScript **ESM** compatible, and avoid CommonJS requires.
- Favor additive, reversible edits; do not remove user logic.
- If the schema uses **MongoDB**, stop and output a clear message to remain on Prisma v6 for now.
---
## 0) Detect Context & Plan
1. Identify:
- Package manager and scripts.
- Database: Postgres, SQLite, MySQL, SQL Server (MongoDB = halt).
- Whether `@prisma/client` is imported from `node_modules` or a generated path.
- Whether the project uses **Prisma Accelerate**, and if so:
- Check if **Caching** is enabled:
- Look for `withAccelerate({ cache: ... })`
- Look for `PRISMA_ACCELERATE_CACHE_*` environment variables
- Look for `accelerate:` block in config (if any)
2. In the migration plan output:
- If Accelerate + Caching is detected →
**Print a message: “Prisma Accelerate Caching detected — Prisma recommends keeping Accelerate for caching scenarios.”**
- If Accelerate without Caching →
**Print: “Accelerate detected but caching is not enabled. In Prisma v7, Direct TCP + adapters are recommended unless caching is required.”**
- If no Accelerate → continue normally.
> **Do not modify or remove Accelerate code paths. Only describe recommendations.**
---
## 1) Dependencies
- Upgrade/install:
- Dev: `prisma@latest` (7.0.0), `tsx`, `dotenv` (skip if Bun).
- Runtime: `@prisma/client@latest` (7.0.0).
- **One** database adapter that matches the datasource:
- Postgres: `@prisma/adapter-ppg`
- SQLite: `@prisma/adapter-better-sqlite3`
- MySQL/mariaDB: `@prisma/adapter-mariadb`
- D1: `@prisma/adapter-d1`
- PlanetScale: `@prisma/adapter-planetscale`
- MSSQL: `@prisma/adapter-mssql`
- CockroachDB: `@prisma/adapter-pg`
- Neon: `@prisma/adapter-neon`
- **Do not remove Accelerate packages automatically.**
- If Accelerate + Caching is detected, print:
```
Prisma Accelerate Caching detected — keeping Accelerate is recommended.
```
- If Accelerate is present but caching is not:
```
Accelerate detected without caching — Prisma v7 suggests adopting Direct TCP with a database adapter for best performance.
```
- Eliminate no user code; only output informational guidance.
> Produce installation commands based on the repo’s package manager.
---
## 2) Prisma Schema Changes
- In `schema.prisma`:
- `generator client`:
```diff
- provider = "prisma-client-js"
+ provider = "prisma-client"
output = "./generated"
```
- Remove any `previewFeatures = ["driverAdapters"]` and any `engineType` attributes.
- Update the `datasource db` block:
- **Goal:** keep the existing `provider` value, but **remove any `url = …` entry**.
- Example (for illustration only — do not insert comments into the user's schema):
- Before:
```prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
```
- After:
```prisma
datasource db {
provider = "postgresql"
}
```
- Rules:
- Preserve the existing `provider` value exactly as-is (e.g. `"postgresql"`, `"mysql"`, `"sqlite"`, etc.).
- Remove only the `url = ...` line from the `datasource db` block.
- Preserve any other properties on the datasource (for example: `shadowDatabaseUrl`, `relationMode`, `schemas`, `extensions`, `directUrl`, etc.).
- Do **not** add explanatory comments into the schema; comments in this prompt are hints for you, not code to emit.
- After edits, run `prisma generate`.
---
## 3) Introduce prisma.config.ts Create **prisma.config.ts** at repo root (or prisma.config.mjs), centralizing Prisma CLI config and env management:
```tsx
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx prisma/seed.ts",
},
datasource: {
// Prefer DIRECT TCP via DATABASE_URL
url: env("DATABASE_URL"),
// Optionally support shadow DB if present:
// shadowDatabaseUrl: env('SHADOW_DATABASE_URL'),
},
});
```
- Remove any prisma.seed from package.json (the config above replaces it).
---
## 4) ESM & TS Baseline - Ensure **package.json**:
```json
{
"type": "module",
"scripts": {
"dev": "tsx src/index.ts",
"generate": "prisma generate",
"migrate": "prisma migrate dev",
"build": "tsc -p tsconfig.json"
}
}
```
- Ensure **tsconfig.json** supports ESM:
```json
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"target": "ES2023",
"strict": true,
"esModuleInterop": true
}
}
```
---
## 5) Refactor Client Import & Construction
If Prisma Accelerate is detected:
- If caching is enabled → **preserve the existing Accelerate setup**.
- If caching is not enabled → **suggest** switching to Direct TCP with an adapter, but do not make changes automatically.
Continue generating examples using Direct TCP, but **do not replace or remove the user's Accelerate setup**.
---
## 6) Seeding Script Update - Ensure prisma/seed.ts uses the same **adapter** and **dotenv** import as runtime:
```tsx
import "dotenv/config";
import { PrismaClient } from "../generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL! });
const prisma = new PrismaClient({ adapter });
// seed…
```
- Set seed command via prisma.config.ts (no package.json#prisma.seed).
---
## 7) Middleware → Extensions
- If prisma.$use middleware exists, inform users that the API has been removed
---
## 8) Accelerate Messaging
### 🟩 If Accelerate Caching is detected
```
Prisma Accelerate Caching detected.
Prisma v7 fully supports caching scenarios via Accelerate.
Your existing Accelerate setup will be preserved.
```
### 🟨 If Accelerate is present but caching is NOT detected
```
Prisma Accelerate detected without caching.
Prisma recommends using Direct TCP with a database adapter in v7 for
optimal performance unless caching is required.
Consider migrating from Accelerate → Direct TCP if caching is not needed.
(No code changes were applied automatically.)
```
### 🟦 If Accelerate is not detected at all
```
Direct TCP is the recommended default for Prisma v7.
Your project will be migrated accordingly using the appropriate adapter.
```
---
## 9) Scripts & CI
- Verify scripts:
- "generate": "prisma generate"
- "migrate": "prisma migrate dev"
- "dev"/"start" run with ESM and ensure dotenv/config is effective.
- In CI, ensure Node **≥ 20.19** and TypeScript **≥ 5.4**.
---
## 10) Run & Verify
1. prisma generate → should succeed and emit client to ./generated.
2. prisma migrate dev → runs against DATABASE_URL (direct TCP).
3. tsx prisma/seed.ts → inserts sample record(s) cleanly.
4. App boot: instantiate PrismaClient with adapter; confirm queries work.
5. If **P1017 / connection** errors: - Confirm DATABASE_URL and network reachability. - Confirm import 'dotenv/config' executes early.
6. If **module resolution** errors: - Confirm "type": "module", ESM imports, and re-generate client.
---
## 11) CLI Flag Changes
### `--schema` and `--url` flags removed from `prisma db execute`
The `--schema` and `--url` flags have been removed from `prisma db execute`. Configure your database connection in `prisma.config.ts` instead.
**Before (v6):**
```bash
# Using --schema
prisma db execute --file ./script.sql --schema prisma/schema.prisma
# Using --url
prisma db execute --file ./script.sql --url "$DATABASE_URL"
```
**After (v7):**
```bash
prisma db execute --file ./script.sql
```
The database URL is now read from `prisma.config.ts`.
### `prisma migrate diff` options changed
Several options have been removed and replaced:
| Removed Option | Replacement |
| -------------------------- | ------------------------------- |
| `--from-url` | `--from-config-datasource` |
| `--to-url` | `--to-config-datasource` |
| `--from-schema-datasource` | `--from-config-datasource` |
| `--to-schema-datasource` | `--to-config-datasource` |
| `--shadow-database-url` | Configure in `prisma.config.ts` |
**Before (v6):**
```bash
prisma migrate diff \
--from-url "$DATABASE_URL" \
--to-schema schema.prisma \
--script
```
**After (v7):**
```bash
prisma migrate diff \
--from-config-datasource \
--to-schema schema.prisma \
--script
```
### Migration Action
- Update any scripts or CI pipelines that use `prisma db execute --schema` or `prisma db execute --url`.
- Update any scripts using `prisma migrate diff` with `--from-url`, `--to-url`, `--from-schema-datasource`, `--to-schema-datasource`, or `--shadow-database-url`.
- Configure your database connection in `prisma.config.ts` instead.
---
## Safety Checks & Edge Cases
- **MongoDB provider** detected → stop and recommend staying on Prisma 6 until v7 MongoDB support returns.
- **Multiple entrypoints** (workers, scripts, tests): apply the same client/adapter/dotenv pattern everywhere.
- **Typed SQL** or custom extensions: keep as-is; ensure they compile after client re-generation.
- Preserve existing output path if the project uses custom locations.
---
## 11) Mapped Enum Breaking Change
In Prisma v7, the generated TypeScript enum values now use `@map` values instead of schema names.
### Example
Given this schema:
```prisma
enum SuggestionStatus {
PENDING @map("pending")
ACCEPTED @map("accepted")
REJECTED @map("rejected")
}
```
**v6 generated enum:**
```ts
export const SuggestionStatus = {
PENDING: "PENDING",
ACCEPTED: "ACCEPTED",
REJECTED: "REJECTED",
} as const;
```
**v7 generated enum:**
```ts
export const SuggestionStatus = {
PENDING: "pending",
ACCEPTED: "accepted",
REJECTED: "rejected",
} as const;
```
### Known Bug (as of v7.2.0)
⚠️ **There is a known bug** where using mapped enum values with Prisma Client operations causes runtime errors. The TypeScript types expect mapped values, but the engine expects schema names. Track this at [GitHub #28591](https://github.com/prisma/prisma/issues/28591).
### Temporary Workarounds
1. **Use schema names as string literals** (causes TS error but works at runtime):
```ts
await prisma.suggestion.create({
data: {
status: "PENDING" as any, // Use schema name, not mapped value
},
});
```
2. **Remove `@map` from enum values** temporarily if you don't strictly need different database values:
```prisma
// Before: with @map directives
enum SuggestionStatus {
PENDING @map("pending")
ACCEPTED @map("accepted")
REJECTED @map("rejected")
}
// After: without @map directives
enum SuggestionStatus {
PENDING
ACCEPTED
REJECTED
}
```
With this change, both the schema names and the database values will be `PENDING`, `ACCEPTED`, and `REJECTED`.
### Migration Action
- Inform users about this breaking change if their schema uses `@map` on enum values.
- Warn about the current bug and suggest workarounds until it's fixed.
---
## Deliverables
- A short **CHANGELOG** summary in the PR body:
- Dependency bumps and added adapter
- Schema generator change
- New `prisma.config.ts`
- Runtime refactor to adapter + optional Accelerate messaging
- ESM/TS config updates
- Seed script updates
- No automatic removal of Accelerate
- CLI flag changes (`--schema` and `--url` removal from `db execute`, `migrate diff` option changes)
- Mapped enum breaking change warning (if applicable)
````
# Turborepo + Prisma (/docs/ai/prompts/turborepo)
How to use [#how-to-use]
Include this prompt in your AI assistant to guide consistent code generation for Turborepo + Prisma + Prisma Postgres projects.
* **GitHub Copilot**: Type `#` to reference the prompt file.
* **Cursor**: Use `@Files` and select your prompt file.
* **Zed**: Use `/file` followed by your prompt's path.
* **Windsurf**: Use `@Files` and choose your prompt file from the list.
Prompt [#prompt]
````md
---
# Specify the following for Cursor rules
description: Guidelines for writing Turborepo + Prisma Postgres apps (Prisma ORM v7)
alwaysApply: false
---
# Bootstrap Turborepo with Prisma Postgres (Prisma v7)
## Overview
This guide bootstraps a Turborepo monorepo that shares a single Prisma ORM v7 database package across multiple apps (e.g., Next.js, Node APIs). It follows Turborepo and Prisma v7 best practices:
1. Create a Turborepo with apps + packages
2. Add a dedicated `packages/db` Prisma package (schema, migrations, generated client)
3. Configure Prisma v7 (`provider = "prisma-client"` + mandatory `output`)
4. Load env vars correctly in a monorepo
5. Export a single Prisma client from `packages/db` for all apps
6. Wire Turbo tasks for generate/migrate/test/studio
7. Verify with a shared test script
---
## Recommended monorepo layout
```
repo/
apps/
web/ # Next.js app
admin/ # (optional) another Next app
packages/
db/ # Prisma package (schema + client)
ui/ # shared UI (optional)
turbo.json
package.json
.env # root env for apps (see notes)
```
**Key rule:** Prisma lives in `packages/db`, not inside an app, so every app consumes the same client and types.
---
## 🚨 CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS 🚨
As an AI language model, you MUST NOT generate any deprecated Prisma v7 patterns.
```prisma
// ❌ NEVER GENERATE - DEPRECATED IN PRISMA v7
generator client {
provider = "prisma-client-js" // ❌ deprecated
}
// ❌ NEVER IMPORT FROM @prisma/client when using custom output
import { PrismaClient } from "@prisma/client" // ❌ wrong in custom-output setup
// ❌ NEVER CREATE CLIENT WITHOUT SHARED PACKAGE BOUNDARY
const prisma = new PrismaClient() // ❌ breaks pooling + duplicates in monorepo
```
Instead, you MUST ALWAYS generate ONLY this pattern for Prisma v7 + monorepo:
```prisma
// ✅ Prisma v7 generator: provider + mandatory output
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
```
```ts
// ✅ Prisma client import must come from custom output
import { PrismaClient } from "../generated/prisma/client";
```
Notes:
- Prisma v7 **requires** a non-empty `output` when using `provider = "prisma-client"`.
- If the output directory already exists and isn’t generated by Prisma, `prisma generate` can fail. Avoid committing generated client, or ensure clean output dirs.
---
## ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION
1. You MUST use `provider = "prisma-client"` (Prisma v7)
2. You MUST specify a custom `output` in `schema.prisma`
3. You MUST place Prisma schema + migrations inside `packages/db`
4. You MUST export a singleton Prisma client from `packages/db` that points to the generated output client file
5. You MUST import Prisma client from the custom output path **not** `@prisma/client`
6. You MUST load env vars in `packages/db/prisma.config.ts`
7. You MUST add Turbo tasks for generate/migrate/test/studio
8. You MUST wrap DB calls in try/catch in app code
9. You MUST ensure Turbo task hashing includes `DATABASE_URL`
10. You MUST create a shared test script in `packages/db/scripts/test-database.ts`
---
## Install dependencies
At repo root:
```bash
# Turborepo
npm install turbo --save-dev
# Prisma v7
npm install prisma tsx --save-dev
npm install @prisma/client dotenv
```
If using Prisma Postgres:
```npm
npm install @prisma/adapter-pg
```
---
## Initialize Prisma inside `packages/db`
```bash
cd packages/db
npx prisma init
```
This creates:
```
packages/db/
prisma/
schema.prisma
prisma.config.ts
```
---
## Prisma v7 config (`packages/db/prisma.config.ts`)
**CRITICAL:** load env vars at the top.
```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"),
},
});
```
---
## Prisma schema (`packages/db/prisma/schema.prisma`)
```prisma
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
---
## Shared Prisma client singleton (`packages/db/src/client.ts`)
```ts
import { PrismaClient } from "../generated/prisma/client";
//Prisma Driver Adapter for Postgres
import { PrismaPg } from "@prisma/adapter-pg";
// Create a new Driver Adapter instance for PrismaPostgres
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const globalForPrisma = globalThis as unknown as {
prisma?: PrismaClient;
};
export const prisma = globalForPrisma.prisma ?? new PrismaClient({ adapter });
if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = prisma;
}
export default prisma;
```
---
## Export DB package API (`packages/db/src/index.ts`)
```ts
export { prisma } from "./client";
export * from "../generated/prisma";
```
And in `packages/db/package.json`:
```json
{
"name": "@repo/db",
"private": true,
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
"db:generate": "prisma generate",
"db:push": "prisma db push",
"db:migrate": "prisma migrate dev",
"db:studio": "prisma studio",
"db:test": "tsx scripts/test-database.ts"
}
}
```
---
## Root Turbo pipeline (`turbo.json`)
```json
{
"globalEnv": ["DATABASE_URL"],
"tasks": {
"dev": {
"cache": false,
"persistent": true,
"dependsOn": ["^db:generate"]
},
"build": {
"dependsOn": ["^db:generate"],
"outputs": [".next/**", "dist/**"]
},
"db:generate": {
"cache": false
},
"db:migrate": {
"cache": false
},
"db:studio": {
"cache": false
},
"db:test": {
"cache": false,
"dependsOn": ["db:generate"]
}
}
}
```
---
## Root scripts (`package.json`)
```json
{
"scripts": {
"dev": "turbo dev",
"build": "turbo build",
"lint": "turbo lint",
"db:generate": "turbo run db:generate",
"db:push": "turbo run db:push",
"db:migrate": "turbo run db:migrate",
"db:studio": "turbo run db:studio",
"db:test": "turbo run db:test"
}
}
```
---
## Shared test script (`packages/db/scripts/test-database.ts`)
```ts
import "dotenv/config";
import prisma from "../src/client";
async function testDatabase() {
console.log("🔍 Testing Prisma Postgres connection...\n");
try {
console.log("✅ Connected to database!");
console.log("\n📝 Creating a test user...");
const newUser = await prisma.user.create({
data: {
email: "demo@example.com",
name: "Demo User",
},
});
console.log("✅ Created user:", newUser);
console.log("\n📋 Fetching all users...");
const allUsers = await prisma.user.findMany();
console.log(`✅ Found ${allUsers.length} user(s):`);
allUsers.forEach((user) => {
console.log(` - ${user.name} (${user.email})`);
});
console.log("\n🎉 All tests passed! Your database is working.\n");
} catch (error) {
console.error("❌ Error:", error);
process.exit(1);
} finally {
await prisma.$disconnect();
}
}
testDatabase();
```
---
## Using Prisma in apps (example: `apps/web` Next.js)
In any app, add a dependency on `@repo/db` (workspace):
```json
{
"dependencies": {
"@repo/db": "*"
}
}
```
Then in server-side code:
```ts
import { prisma } from "@repo/db";
import { NextResponse } from "next/server";
export async function GET() {
try {
const users = await prisma.user.findMany();
return NextResponse.json(users);
} catch (e) {
console.error(e);
return NextResponse.json({ error: "Failed to fetch users" }, { status: 500 });
}
}
```
---
## Complete setup workflow
1. **Create Turborepo** (or use existing):
```npm
npx create-turbo@latest
```
2. **Add `packages/db`**, install Prisma v7 deps.
3. **Initialize Prisma in `packages/db`**:
```bash
cd packages/db
npx prisma init
```
4. **Update `prisma.config.ts`** to include `import "dotenv/config"`.
5. **Update schema** with Prisma v7 generator + output.
6. **Create `src/client.ts`** singleton and export via `src/index.ts`.
7. **Wire Turbo tasks** in `turbo.json`.
8. **Add `.env`** at root **and/or** `packages/db/.env`.
9. **Push schema**:
```bash
npm run db:push
```
10. **Test**:
```bash
npm run db:test
```
11. **Start dev**:
```bash
npm run dev
```
---
## AI Model verification checklist
Before generating any code, verify:
1. `provider = "prisma-client"`?
2. `output = "../src/generated/prisma"` present?
3. All Prisma files in `packages/db`?
4. Client imports from `../generated/prisma/client` (or via `@repo/db`)?
5. `import "dotenv/config"` in `packages/db/prisma.config.ts`?
6. Turbo tasks depend on `db:generate`?
7. `DATABASE_URL` listed in `globalEnv`?
8. All DB ops wrapped in try/catch?
9. Test script exists in `packages/db/scripts/test-database.ts`?
No exceptions. If any check fails, STOP and FIX.
---
## AI MODEL RESPONSE TEMPLATE (UPDATED FOR TURBOREPO + PRISMA v7)
When asked about implementing Prisma v7 inside a Turborepo monorepo (with any framework such as Next.js, Node, etc.), you MUST:
1. **Assume Prisma lives in a shared package**
- Always place schema, config, and migrations in `packages/db`.
- Never suggest adding Prisma directly into an app unless the user explicitly says they don’t want a shared package.
2. **Use only Prisma v7 generator patterns**
- The schema MUST include:
```prisma
generator client {
provider = "prisma-client"
output = "./generated/prisma"
}
```
- Never use `prisma-client-js`.
3. **Use correct import paths for custom output**
- Any PrismaClient import MUST come from the generated output:
```ts
import { PrismaClient } from "./generated/prisma/client";
```
- If importing from apps, you MUST import via the package boundary:
```ts
import { prisma } from "@repo/db";
```
- Never import from `@prisma/client` in this setup.
4. **Always include a shared singleton client in `packages/db`**
- Provide a `packages/db/src/client.ts` with global caching for dev hot-reload.
- If Accelerate is requested or implied, use `$extends(withAccelerate())`.
- If Accelerate is not requested, omit it.
5. **Always load environment variables properly**
- `packages/db/prisma.config.ts` MUST start with `import "dotenv/config"`.
- Use `process.env.DATABASE_URL` in runtime code.
- Remind users that `.env` should exist at root and/or `packages/db`.
6. **Always wire Turbo dependencies**
- Turbo tasks `dev` and `build` MUST depend on `^db:generate`.
- `DATABASE_URL` MUST be listed in `globalEnv` to ensure correct task hashing.
7. **Provide correct repo-level scripts**
- Root scripts should proxy to Turbo (`turbo run db:*`).
- The Prisma package `packages/db` should own `db:generate`, `db:migrate`, `db:studio`, and `db:test`.
8. **Include a real verification step**
- Provide (or reference) `packages/db/scripts/test-database.ts`.
- Ensure it imports dotenv and disconnects Prisma on completion.
9. **Use safe runtime patterns**
- All DB calls in apps MUST be wrapped in try/catch.
- In Next.js App Router examples, use server-only imports and return `NextResponse`.
10. **Self-verify before replying**
- Re-check all items in the “AI Model verification checklist.”
- If any item is missing or incorrect, STOP and FIX before responding.
Remember: There are NO exceptions to these rules. Every requirement is mandatory for a correct Turborepo + Prisma v7 setup.
````
Running the application [#running-the-application]
Get your application running locally in three quick steps:
**1. Generate the Prisma Client:**
```bash
npx turbo db:generate
```
**2. View your database in Prisma Studio:**
npm
pnpm
yarn
bun
```bash
npx turbo db:studio
```
```bash
pnpm dlx turbo db:studio
```
```bash
yarn dlx turbo db:studio
```
```bash
bunx --bun turbo db:studio
```
Prisma Studio opens at `localhost:5555` where you can inspect your `User` table and see the test user stored in your database.
# ChatGPT (/docs/ai/tools/chatgpt)
[ChatGPT](https://openai.com/chatgpt) is a large language model-based chatbot developed by OpenAI. You can extend its capabilities by connecting it to external tools, such as the Prisma MCP server, to interact with your Prisma Postgres databases.
This guide explains how to add the remote Prisma MCP server to ChatGPT, allowing you to create and manage your databases using natural language prompts.
ChatGPT MCP integration is experimental
This feature is still in development by OpenAI and might look or work a little differently over time. Some users may not have access to it yet.
If you notice that something has changed or doesn't match this guide, please [open an issue](https://github.com/prisma/web/issues) or submit a pull request to update our docs.
Here is an end to end demo of setting up the remote Prisma MCP server and using it in ChatGPT:
Features of the Prisma MCP server [#features-of-the-prisma-mcp-server]
By connecting the Prisma MCP server to ChatGPT, you can perform a variety of database management tasks directly from the chat interface. Here are some of the key features available:
* **Database management**: Create, list, and delete your Prisma Postgres databases.
* **Connection strings**: Generate, list, and revoke database connection strings.
* **Backup and recovery**: Create and list database backups, and restore a database from a backup.
* **Schema and Data interaction**: Execute SQL queries, introspect your database schema to understand its structure, and apply schema updates.
* **Workspace information**: Fetch details about your Prisma workspace.
Prerequisites [#prerequisites]
To use the Prisma MCP server with ChatGPT, you need access to ChatGPT's Developer Mode. This feature is available on specific ChatGPT plans. For the most up-to-date information on supported plans, please refer to the [official OpenAI documentation](https://platform.openai.com/docs/guides/developer-mode).
Enable Developer mode in ChatGPT [#enable-developer-mode-in-chatgpt]
1. Go to **Settings** in your ChatGPT account.
2. Click **Apps & Connectors**.
3. Scroll down and locate **Advanced settings**, then click it.
4. Toggle the **Developer mode** button on.
5. Click **Back**.
Add the remote Prisma MCP server [#add-the-remote-prisma-mcp-server]
1. Make sure "Developer mode" is enabled.
2. Go to the **Apps & Connectors** section of your **Settings**.
3. On the top right, locate and click **Create**.
4. A "New Connector" popup will open. Fill in the text fields as follows:
* **Icon**: You can download and use the [Prisma favicon](https://www.prisma.io/favicon.ico).
* **Name**: `Prisma MCP server`
* **Description**: `Manage Prisma Postgres databases`
* **MCP Server URL**: `https://mcp.prisma.io/mcp`
* **Authentication**: `OAuth`
5. Check the "I trust this application" box and click **Create**.
You will be redirected to authenticate with your Prisma Data Platform account and choose your desired workspace. After successful authentication, you will be redirected back to ChatGPT.
Using the remote Prisma MCP server [#using-the-remote-prisma-mcp-server]
Once Developer Mode is enabled and the Prisma MCP server is added, you can use it in your chats.
1. In ChatGPT, click the **+** icon to the left of the chat input box.
2. Click **More**.
3. Select the **Prisma MCP server** to add it to your chat as a connector.
Now you can use natural language prompts to manage your database. For example:
```
Create a DB called pet-app for me near Paris
```
# Cursor (/docs/ai/tools/cursor)
[Cursor](https://www.cursor.com/) is an AI-powered code editor designed to boost productivity by automating repetitive coding tasks. When paired with Prisma, a robust and type-safe toolkit for database workflows, it becomes a powerful solution for managing and optimizing database schemas, queries, and data seeding.
This guide provides detailed instructions for effectively using Prisma with Cursor to:
* Define project-specific best practices with `.cursorrules`.
* Using Cursor's context-aware capabilities.
* Generate schemas, queries, and seed data tailored to your database.
While this guide is focused on Cursor, these patterns should work with any AI editor. [Let us know on X](https://pris.ly/x?utm_source=docs\&utm_medium=inline_text) if you'd like us to create guides for your preferred tool!
Prisma MCP server [#prisma-mcp-server]
Prisma provides its own [Model Context Protocol](https://modelcontextprotocol.io/introduction) (MCP) server that lets you manage Prisma Postgres databases, model database schemas and chat through migrations. Learn more about how you can add it to Cursor [here](/ai/tools/mcp-server#cursor). You can also add the Prisma MCP server to Cursor using the [one-click installation](https://docs.cursor.com/context/model-context-protocol#one-click-installation) by clicking on the following link:
This will prompt you to open the Cursor app in your browser. Once opened, you'll be guided to install the Prisma MCP server directly into your Cursor configuration.
Defining project-specific rules with .cursorrules [#defining-project-specific-rules-with-cursorrules]
The [`.cursorrules` file](https://docs.cursor.com/context/rules-for-ai#cursorrules) in Cursor allows you to enforce best practices and development standards tailored to your Prisma projects. By defining clear and consistent rules, you can ensure that Cursor generates clean, maintainable, and project-specific code with minimal manual adjustments.
To implement these rules, create a `.cursorrules` file in the root of your project. Below is an example configuration:
Example `.cursorrules` file
```text title=".cursorrules"
You are a senior TypeScript/JavaScript programmer with expertise in Prisma, clean code principles, and modern backend development.
Generate code, corrections, and refactorings that comply with the following guidelines:
TypeScript General Guidelines
Basic Principles
- Use English for all code and documentation.
- Always declare explicit types for variables and functions.
- Avoid using "any".
- Create precise, descriptive types.
- Use JSDoc to document public classes and methods.
- Maintain a single export per file.
- Write self-documenting, intention-revealing code.
Nomenclature
- Use PascalCase for classes and interfaces.
- Use camelCase for variables, functions, methods.
- Use kebab-case for file and directory names.
- Use UPPERCASE for environment variables and constants.
- Start function names with a verb.
- Use verb-based names for boolean variables:
- isLoading, hasError, canDelete
- Use complete words, avoiding unnecessary abbreviations.
- Exceptions: standard abbreviations like API, URL
- Accepted short forms:
- i, j for loop indices
- err for errors
- ctx for contexts
Functions
- Write concise, single-purpose functions.
- Aim for less than 20 lines of code.
- Name functions descriptively with a verb.
- Minimize function complexity:
- Use early returns.
- Extract complex logic to utility functions.
- Leverage functional programming techniques:
- Prefer map, filter, reduce.
- Use arrow functions for simple operations.
- Use named functions for complex logic.
- Use object parameters for multiple arguments.
- Maintain a single level of abstraction.
Data Handling
- Encapsulate data in composite types.
- Prefer immutability.
- Use readonly for unchanging data.
- Use as const for literal values.
- Validate data at the boundaries.
Error Handling
- Use specific, descriptive error types.
- Provide context in error messages.
- Use global error handling where appropriate.
- Log errors with sufficient context.
Prisma-Specific Guidelines
Schema Design
- Use meaningful, domain-driven model names.
- Leverage Prisma schema features:
- Use @id for primary keys.
- Use @unique for natural unique identifiers.
- Utilize @relation for explicit relationship definitions.
- Keep schemas normalized and DRY.
- Use meaningful field names and types.
- Implement soft delete with deletedAt timestamp.
- Use Prisma's native type decorators.
Prisma Client Usage
- Always use type-safe Prisma client operations.
- Prefer transactions for complex, multi-step operations.
- Handle optional relations explicitly.
- Use Prisma's filtering and pagination capabilities.
Database Migrations
- Create migrations for schema changes.
- Use descriptive migration names.
- Review migrations before applying.
- Never modify existing migrations.
- Keep migrations idempotent.
Error Handling with Prisma
- Catch and handle Prisma-specific errors:
- PrismaClientKnownRequestError
- PrismaClientUnknownRequestError
- PrismaClientValidationError
- Provide user-friendly error messages.
- Log detailed error information for debugging.
Testing Prisma Code
- Use in-memory database for unit tests.
- Mock Prisma client for isolated testing.
- Test different scenarios:
- Successful operations
- Error cases
- Edge conditions
- Use factory methods for test data generation.
- Implement integration tests with actual database.
Performance Considerations
- Use select and include judiciously.
- Avoid N+1 query problems.
- Use findMany with take and skip for pagination.
- Leverage Prisma's distinct for unique results.
- Profile and optimize database queries.
Security Best Practices
- Never expose raw Prisma client in APIs.
- Use input validation before database operations.
- Implement row-level security.
- Sanitize and validate all user inputs.
- Use Prisma's built-in protections against SQL injection.
Coding Style
- Keep Prisma-related code in dedicated repositories/modules.
- Separate data access logic from business logic.
- Create repository patterns for complex queries.
- Use dependency injection for Prisma services.
Code Quality
- Follow SOLID principles.
- Prefer composition over inheritance.
- Write clean, readable, and maintainable code.
- Continuously refactor and improve code structure.
Development Workflow
- Use version control (Git).
- Implement comprehensive test coverage.
- Use continuous integration.
- Perform regular code reviews.
- Keep dependencies up to date.
```
This file ensures consistent and maintainable code generation, reducing manual intervention while improving project quality.
Using Cursor's context-aware capabilities [#using-cursors-context-aware-capabilities]
Cursor's [context-aware](https://docs.cursor.com/context/) capabilities let you add specific websites, files, folders or documentation to enhance its understanding of your project. By adding your `schema.prisma` file as context, you enable Cursor to generate more accurate queries, tests, and seed data based on your database schema.
Add Prisma docs llm.txt file as @Docs context [#add-prisma-docs-llmtxt-file-as-docs-context]
To improve Cursor's understanding of Prisma-related suggestions in your project, include the [`/llms.txt`](https://llmstxt.org/) markdown file as context. This file offers a concise overview, useful guidance, and links to detailed Prisma documentation—all optimized for LLM processing. Simply navigate to the [url](https://pris.ly/llms.txt) and add it as a `@Docs` resource in your Cursor configuration.
Adding additional Prisma documentation [#adding-additional-prisma-documentation]
Cursor already includes built-in context from Prisma documentation, so you don't need to add anything to make us of our docs!
To stay updated with the latest changes or incorporate additional context, add these resources as `@Docs` context:
* [Prisma Changelog](https://www.prisma.io/changelog) for updates and new features.
* [Prisma Blog](https://www.prisma.io/blog) for practical guides and best practices.
To learn how to add and manage documentation context, visit the [Cursor documentation](https://docs.cursor.com/context/@-symbols/@-docs#docs).
Using schema as context [#using-schema-as-context]
Add your `schema.prisma` file (or the entire codebase) as context using the [`@Files`](https://docs.cursor.com/context/@-symbols/@-files) syntax before requesting queries, tests, or seed scripts. This allows Cursor to generate precise, schema-driven outputs such as queries, tests, and seed data. For example, in [Cursor Chat](https://docs.cursor.com/chat/overview), you can include your schema by typing `@Files` followed by adding your `schema.prisma` file.
Generating Prisma Schema [#generating-prisma-schema]
Cursor can generate Prisma schemas from high-level descriptions, enabling you to quickly establish a solid foundation for your database schema. By providing a clear and detailed prompt, Cursor creates Prisma schemas tailored to your requirements. Whether you need a general foundational schema or a highly specific one for detailed use cases, Cursor can deliver with precision. Here's an example prompt and its corresponding result:
If you run the prompts below, you may receive a different outputs because LLMs produce non-deterministic responses.
Prompt to generate Prisma schema
Result
```text
"Create a Prisma schema for a SaaS app using PostgreSQL as a provider with `User`, `Organization`, and `Subscription` models, ensuring all models include `createdAt` and `updatedAt` DateTime fields with defaults, a soft-delete `deletedAt` field, and proper relationships between entities."
```
```prisma title="schema.prisma"
generator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "postgresql"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
organization Organization @relation(fields: [organizationId], references: [id])
organizationId Int
role UserRole @default(MEMBER)
}
model Organization {
id Int @id @default(autoincrement())
name String
slug String @unique
subscription Subscription?
users User[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
}
model Subscription {
id Int @id @default(autoincrement())
organization Organization @relation(fields: [organizationId], references: [id])
organizationId Int @unique
plan SubscriptionPlan
status SubscriptionStatus @default(ACTIVE)
startDate DateTime
endDate DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
}
enum UserRole {
ADMIN
MEMBER
}
enum SubscriptionPlan {
FREE
BASIC
PREMIUM
ENTERPRISE
}
enum SubscriptionStatus {
ACTIVE
CANCELED
EXPIRED
PAST_DUE
}
```
Generating Prisma queries [#generating-prisma-queries]
Cursor can help you create queries tailored to your Prisma schema, whether for basic data retrieval or complex, optimized operations. To get the best results, focus on writing clear, specific prompts that define your requirements, such as the fields to include, conditions to apply, and relationships to traverse. This ensures Cursor generates accurate, performant, and type-safe queries. Here's an example prompt and its resulting query:
Prompt to generate a database query
Result
```text
"Generate a query to retrieve all User records associated with an Organization that has an `active` Subscription, while excluding any records where the deletedAt field is set."
```
```typescript
const activeUsers = await prisma.user.findMany({
where: {
deletedAt: null,
organization: {
deletedAt: null,
subscription: {
deletedAt: null,
status: "ACTIVE",
},
},
},
include: {
organization: {
include: {
subscription: true,
},
},
},
orderBy: {
createdAt: "desc",
},
skip: 0,
take: 10,
});
```
Creating seed files with Cursor [#creating-seed-files-with-cursor]
Writing seed scripts can be a tedious process, but Cursor simplifies it by quickly generating structured and organized seed code. By providing clear instructions, you can guide Cursor to create scripts that populate your database with realistic data, including handling relationships and complex structures defined in your schema. Here's an example prompt and its resulting seed script:
Prompt to seed the database
Result
```text
"Generate code to populate the Prisma schema with realistic data for the User, Organization, and Subscription models, ensuring all necessary fields are included."
```
```ts title="seed.ts"
import {
PrismaClient,
UserRole,
SubscriptionPlan,
SubscriptionStatus,
} from "../prisma/generated/client";
const prisma = new PrismaClient();
async function main() {
// Clear existing data
await prisma.user.deleteMany();
await prisma.subscription.deleteMany();
await prisma.organization.deleteMany();
const organizations = [
{
name: "Tech Innovators",
slug: "tech-innovators",
subscription: {
plan: SubscriptionPlan.ENTERPRISE,
status: SubscriptionStatus.ACTIVE,
startDate: new Date("2024-01-01"),
},
users: [
{
name: "Emma Thompson",
email: "emma@techinnovators.com",
role: UserRole.ADMIN,
password: "password123",
},
{
name: "Michael Chen",
email: "michael@techinnovators.com",
role: UserRole.MEMBER,
password: "password123",
},
],
},
{
name: "Digital Solutions",
slug: "digital-solutions",
subscription: {
plan: SubscriptionPlan.PREMIUM,
status: SubscriptionStatus.ACTIVE,
startDate: new Date("2024-01-15"),
},
users: [
{
name: "Sarah Wilson",
email: "sarah@digitalsolutions.com",
role: UserRole.ADMIN,
password: "password123",
},
{
name: "James Miller",
email: "james@digitalsolutions.com",
role: UserRole.MEMBER,
password: "password123",
},
],
},
{
name: "Cloud Systems",
slug: "cloud-systems",
subscription: {
plan: SubscriptionPlan.BASIC,
status: SubscriptionStatus.ACTIVE,
startDate: new Date("2024-02-01"),
},
users: [
{
name: "David Garcia",
email: "david@cloudsystems.com",
role: UserRole.ADMIN,
password: "password123",
},
{
name: "Lisa Wang",
email: "lisa@cloudsystems.com",
role: UserRole.MEMBER,
password: "password123",
},
],
},
{
name: "Data Analytics Co",
slug: "data-analytics",
subscription: {
plan: SubscriptionPlan.PREMIUM,
status: SubscriptionStatus.ACTIVE,
startDate: new Date("2024-01-10"),
},
users: [
{
name: "Alex Johnson",
email: "alex@dataanalytics.com",
role: UserRole.ADMIN,
password: "password123",
},
{
name: "Rachel Kim",
email: "rachel@dataanalytics.com",
role: UserRole.MEMBER,
password: "password123",
},
],
},
{
name: "Smart Solutions",
slug: "smart-solutions",
subscription: {
plan: SubscriptionPlan.FREE,
status: SubscriptionStatus.ACTIVE,
startDate: new Date("2024-02-15"),
},
users: [
{
name: "Daniel Brown",
email: "daniel@smartsolutions.com",
role: UserRole.ADMIN,
password: "password123",
},
{
name: "Maria Rodriguez",
email: "maria@smartsolutions.com",
role: UserRole.MEMBER,
password: "password123",
},
],
},
];
for (const org of organizations) {
const createdOrg = await prisma.organization.create({
data: {
name: org.name,
slug: org.slug,
subscription: {
create: {
plan: org.subscription.plan,
status: org.subscription.status,
startDate: org.subscription.startDate,
},
},
},
});
for (const user of org.users) {
await prisma.user.create({
data: {
name: user.name,
email: user.email,
password: user.password,
role: user.role,
organizationId: createdOrg.id,
},
});
}
}
console.log("Seed data created successfully");
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
Using the Prisma VS Code extension to manage your database [#using-the-prisma-vs-code-extension-to-manage-your-database]
The [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) is a powerful tool for building applications with [Prisma Postgres](/postgres). You can also use it in Cursor by installing the extension. It provides a dedicated UI for managing Prisma Postgres instances, both local and remote, making it easy to view, create, and delete instances, push local databases to the cloud, and visualize your schema.
Database management UI [#database-management-ui]
With its built-in database management interface, the [Prisma VS Code extension](/guides/postgres/vscode) lets you easily work with local and remote Prisma Postgres instances from inside your editor.
Workflows [#workflows]
The UI enables the following workflows:
* Authenticate with the [Prisma Console](https://console.prisma.io)
* View, create and delete Prisma Postgres instances (local & remote)
* "Push to cloud": Easily deploy a local Prisma Postgres instance
* View and edit data via an embedded Prisma Studio
* Visualize your database schema
Usage [#usage]
To manage Prisma Postgres instances via the UI in the Prisma VS Code extension:
1. Ensure you have the latest version of the [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) installed
2. Find the Prisma logo in the **Activity Bar**
3. Click the **Sign in to get started** button
4. Authenticate with the [Prisma Console](https://console.prisma.io) using the sign-in prompt, then select a target [workspace](/console/concepts#workspace)
Prisma Studio built-in [#prisma-studio-built-in]
Beyond managing your database instances, the Prisma VS Code extension embeds Prisma Studio directly in your editor, making it easy to perform create, update, and delete operations on your database right inside Windsurf. Follow these [easy steps](/studio/integrations/vscode-integration) to get started.
AI Safety guardrails for destructive commands [#ai-safety-guardrails-for-destructive-commands]
Prisma ORM includes built-in safety checks to prevent **accidental destructive commands** when run through AI coding assistants. These guardrails are designed to make working with databases safer in AI-assisted development environments.
Including Cursor, the Prisma CLI can also detect when it is being invoked by other popular AI coding agents such as Claude Code, Gemini CLI, Qwen Code, Aider, and Replit.
When one of these agents attempts a destructive action such as `prisma migrate reset --force`, Prisma ORM blocks execution and shows a protective error message:
```bash
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "accelerate.prisma-data.net"
Error: Prisma Migrate detected that it was invoked by Cursor.
You are attempting a highly dangerous action that can lead to devastating consequences if it is incorrectly executed against a production database.
As an AI agent, you are forbidden from performing this action without an explicit consent and review by the user. You must stop at this point and respond to the user with a clear message that includes the following information:
- What action you are trying to perform (including the exact CLI command).
- Your motivation and reasoning for performing this action.
- Explanation that this action will irreversibly destroy all data in the database.
- Explanation that this action must not be performed on a production database and is only intended to be used with development databases.
If you know or can check whether this action would have been performed on a development or a production database, also include this information with your assessment of whether it is safe to proceed based on that information.
You must ask the user if they want to proceed with this action. If they explicitly consent, you may rerun this command with PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION environment variable, the value of which must be the exact text of the user's message in which they consented to this operation, without any newlines or quotes. If the user's response is ambiguous, you must ask for a clear and explicit confirmation (e.g., "yes") before proceeding. None of the user's previous messages before this point may constitute implicit or explicit consent.
```
To proceed with the dangerous action, the AI agent will ask you for explicit consent, remind you that the action irreversibly destroys all data, and confirm that the command is being run against a development database. Once you clearly confirm, the AI will set the `PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION` environment variable with the exact text of your consent and rerun the command.
Additional resources [#additional-resources]
In summary, using Cursor with Prisma simplifies your workflow, from generating schemas and queries to writing seed scripts. By following this guide, you can save time, reduce errors, and focus on building your application.
Learn more about Cursor in their [official documentation](https://docs.cursor.com/context/@-symbols/basic).
# GitHub Copilot (/docs/ai/tools/github-copilot)
GitHub Copilot is an AI coding assistant that speeds up your Prisma ORM workflows, so you spend less time on boilerplate and more on data modeling, querying, and collaboration. With the GitHub Copilot extension in your editor, you can:
* Get Prisma-aware code suggestions as you edit your schema or invoke the client.
* Chat with Copilot about modeling patterns, troubleshoot queries, or explore migration strategies.
* Run common Prisma CLI commands (e.g. `prisma migrate dev`, `prisma db push`) via Copilot's command-palette interface.
* Scaffold Prisma schema models and generate Prisma Client code and run migrations directly from the Copilot chat interface.
GitHub Copilot allows you to query the official docs via the [**Prisma for GitHub Copilot** extension](https://github.com/apps/prisma-for-github-copilot) and also perform automated [actions in VS Code agent mode](/guides/postgres/vscode#agent-mode), such as scaffolding a Prisma schema, running seed scripts, and creating a production-ready Prisma Postgres database.
Query Prisma docs with the Prisma for GitHub Copilot extension [#query-prisma-docs-with-the-prisma-for-github-copilot-extension]
The [Prisma for GitHub Copilot extension](https://github.com/apps/prisma-for-github-copilot) lets you fetch Prisma documentation directly in GitHub Copilot Chat. You can look up schema syntax, client methods, migration commands, and more from your editor.
How to enable the extension [#how-to-enable-the-extension]
1. Install the **Prisma for Copilot** from the GitHub Marketplace.
2. Ensure [GitHub Copilot Chat is installed](https://docs.github.com/en/copilot/using-github-copilot/copilot-chat/asking-github-copilot-questions-in-your-ide) and active in your code editor.
3. Open a file in your workspace and launch Copilot Chat.
4. In chat, prefix your question with the `@prisma-for-copilot` keyword:
```
@prisma-for-copilot How do I define a one-to-many relation?
```
1. Install the [Prisma for GitHub Copilot](https://github.com/apps/prisma-for-github-copilot) extension.
2. Open your IDE.
3. Install the [GitHub Copilot Chat extension](https://docs.github.com/en/copilot/managing-copilot/configure-personal-settings/installing-the-github-copilot-extension-in-your-environment).
4. Open Copilot Chat and switch to [**Ask** mode](https://code.visualstudio.com/docs/copilot/chat/chat-ask-mode).
5. Ask: "`@prisma-for-github-copilot` How do I define a one-to-many relation?" (If the `@prisma-for-github-copilot` namespace doesn't show up after a few seconds, reload the chat.)
6. When prompted, authorize the Prisma app in your browser, then return to the chat.
7. After returning to the chat, resend the question.
8. Copilot returns the answer pulled straight from the Prisma docs.
Use GitHub Copilot's agent features [#use-github-copilots-agent-features]
GitHub Copilot Chat offers an **Agent** mode in VS Code that can run Prisma commands. You can use the agent chat to:
* Run and inspect migrations.
* Generate Prisma Client code.
* Create a new Prisma Postgres database and update your `.env` file.
You can type `Create a database named test-db and add its connection string to the .env file.` in the Copilot chat, and it will automatically create a new database named `test-db` and add the connection string to your `.env` file. To learn more about this, visit our [VS Code agent mode documentation](/guides/postgres/vscode#agent-mode).
Customize GitHub Copilot with copilot-instructions.md [#customize-github-copilot-with-copilot-instructionsmd]
You can tailor Copilot Chat's behavior in your repository by [adding a `.github/copilot-instructions.md` file](https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot). This file injects your guidelines into every Copilot Chat session.
Example
`.github/copilot-instructions.md`
for Prisma
````text
# GitHub Copilot Instructions for Prisma Workspace
## General Guidelines
1. **Language**: English only.
2. **Types**: Declare explicit types; avoid `any`.
3. **Comments**: Use JSDoc for public methods and classes.
4. **Exports**: One export per file.
5. **Naming**:
* **Classes/interfaces** → `PascalCase`
* **Variables/functions** → `camelCase`
* **Files/directories** → `kebab-case`
* **Constants** → `UPPERCASE`
* **Boolean flags** → verb-based (e.g., `isLoading`)
---
## Prisma-Specific Guidelines
### 1. Data Modeling
* **Domain-driven model names**: keep them singular (e.g. `User`, `OrderItem`).
* **Field naming**: use `camelCase` for fields (e.g. `createdAt`, `deletedAt`).
* **IDs & keys**:
```prisma
model Post {
id Int @id @default(autoincrement())
uuid String @unique @default(uuid())
}
/```
* **Composite keys & uniques**:
```prisma
@@id([userId, role])
@@unique([email, tenantId])
/```
* **Enums & constrained values**: leverage `enum` for fixed domains.
* **Soft deletes & audit**:
```prisma
model Base {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
}
/```
### 2. Indexing & Constraints
* **Single-column indexes** for frequent lookups:
```prisma
@@index([email])
/```
* **Compound indexes** for multi-field filters/sorts:
```prisma
@@index([status, createdAt])
/```
* **Full-text search** (Postgres-only):
```prisma
@@index([title, content], type: Brin) // or Gin for JSONB
/```
### 3. Migrations
* **Descriptive names**: `npx prisma migrate dev --name add-order-totals`
* **Idempotent steps**: avoid imperative SQL in migrations.
* **Shadow database**: enable in CI to catch drift.
* **Never edit** migration SQL after it’s applied to any environment.
### 4. Client Instantiation & Connection Management
* **Singleton pattern**
```ts
// prisma.ts
import { PrismaClient } from '../prisma/generated/client';
export const prisma = global.prisma || new PrismaClient();
if (process.env.NODE_ENV !== 'production') global.prisma = prisma;
/```
### 5. Transactions & Batch Operations
* **Multi-step atomicity**:
```ts
const result = await prisma.$transaction([
prisma.user.create({ data: { /*…*/ } }),
prisma.order.create({ data: { /*…*/ } }),
]);
/```
* **Interactive transactions** for long-running flows.
* **Bulk writes**: chunk large inserts/updates to avoid timeouts.
### 6. Precise Queries & Performance
* **Select only needed fields**:
```ts
await prisma.user.findUnique({
where: { id },
select: { id: true, email: true },
});
/```
* **Avoid N+1**: use `include` or batch `findMany` with `where: { id: { in: [...] } }` or use database joins in prisma.
* Use **Cursor-based pagination**
### 7. Raw Queries & Client Extensions
* **Raw SQL** when necessary, safely:
```ts
const users = await prisma.$queryRaw`SELECT * FROM "User" WHERE email = ${email}`;
/```
* **Sanitize inputs** with `Prisma.sql` for complex interpolations.
* **Client extensions**: use preview feature `clientExtensions` to add common helper methods.
### 8. Error Handling
* **Catch specific errors**:
```ts
try {
// …
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
// P2002: Unique constraint
}
}
/```
* **Wrap in service-level errors** to add context before bubbling up.
### 9. Testing
* **In-memory DB** (SQLite) or **Testcontainers** for integration tests.
* **Mock Prisma Client** for pure unit tests via `jest.mock()` or similar.
### 10. Logging, Monitoring & Metrics
* **Enable query logging** in dev:
```ts
new PrismaClient({ log: ['query', 'warn', 'error'] });
/```
* **APM integration** (Datadog, Sentry) – capture latency, errors.
### 11. Security & Best Practices
* **Never expose** raw Prisma client in HTTP controllers—wrap in a service layer.
* **Validate inputs** (e.g. with Zod) before any DB operation.
* **Least privilege** DB users: use separate roles for migrations vs. runtime.
* **Rotate credentials** and load from secure vault (AWS Secrets Manager, etc.).
### 12. Environment & Configuration
* **Centralize `DATABASE_URL`** and connection settings in `.env`.
* **Pin preview features** in `schema.prisma`:
```prisma
generator client {
previewFeatures = ["clientExtensions", "interactiveTransactions"]
}
/```
* **Version pinning**: match CLI and client versions in `package.json`.
````
Place this file at the root of your repository under `.github/`. Copilot Chat automatically applies these rules to every conversation in your project.
# MCP server (/docs/ai/tools/mcp-server)
Overview [#overview]
The [Model-Context-Protocol](https://modelcontextprotocol.io/introduction) (MCP) gives LLMs a way to call APIs and thus access external systems in a well-defined manner.
Prisma provides two MCP servers: a *local* and a *remote* one. See below for specific information on each.
If you're a developer working on a local machine and want your AI agent to help with your database workflows, use the local MCP server.
If you're building an "AI platform" and want to give the ability to manage database to your users, use the remote MCP server.
Remote MCP server [#remote-mcp-server]
You can start the remote MCP server as follows:
npm
pnpm
yarn
bun
```bash
npx -y mcp-remote https://mcp.prisma.io/mcp
```
```bash
pnpm dlx -y mcp-remote https://mcp.prisma.io/mcp
```
```bash
yarn dlx -y mcp-remote https://mcp.prisma.io/mcp
```
```bash
bunx --bun -y mcp-remote https://mcp.prisma.io/mcp
```
Tools [#tools]
[Tools](https://modelcontextprotocol.io/docs/concepts/tools) represent the *capabilities* of an MCP server. Here's the list of tools exposed by the remote MCP server:
* `CreateBackupTool`: Create a new managed Prisma Postgres Backup.
* `CreateConnectionStringTool`: Create a new Connection String for a Prisma Postgres database with the given id.
* `CreateRecoveryTool`: Restore a Prisma Postgres Database to a new database with the given Backup id.
* `DeleteConnectionStringTool`: Delete a Connection String with the given connection string id.
* `DeleteDatabaseTool`: Delete a Prisma Postgres database with the given id.
* `ListBackupsTool`: Fetch a list of available Prisma Postgres Backups for the given database id and environment id.
* `ListConnectionStringsTool`: Fetch a list of available Prisma Postgres Database Connection Strings for the given database id and environment id.
* `ListDatabasesTool`: Fetch a list of available Prisma Postgres Databases for user's workspace.
* `ExecuteSqlQueryTool`: Execute a SQL query on a Prisma Postgres database with the given id.
* `IntrospectSchemaTool`: Introspect the schema of a Prisma Postgres database with the given id.
Once you're connected to the remote MCP server, you can also always prompt your AI agent to "List the Prisma tools" to get a full overview of the latest supported tools.
Usage [#usage]
The remote Prisma MCP server follows the standard JSON-based configuration for MCP servers. Here's what it looks like:
```json
{
"mcpServers": {
"Prisma-Remote": {
"url": "https://mcp.prisma.io/mcp"
}
}
}
```
Sample prompts [#sample-prompts]
* "Show me a list of all the databases in my account."
* "Create a new database in the US region for me."
* "Seed my database with real-looking data but create a backup beforehand."
* "Show me all available backups of my database."
* "Show me all customers and run an analysis over their orders."
Local MCP server [#local-mcp-server]
You can start the local MCP server as follows:
npm
pnpm
yarn
bun
```bash
npx -y prisma mcp
```
```bash
pnpm dlx -y prisma mcp
```
```bash
yarn dlx -y prisma mcp
```
```bash
bunx --bun -y prisma mcp
```
If you're using VS Code, you can use [VS Code agent mode](https://code.visualstudio.com/docs/copilot/chat/chat-agent-mode) to enter prompts such as "create Postgres database" or "apply schema migration" directly in the chat. The VS Code agent handles all underlying Prisma CLI invocations and API calls automatically. See our [VS Code Agent documentation](/guides/postgres/vscode#agent-mode) for more details.
Tools [#tools-1]
[Tools](https://modelcontextprotocol.io/docs/concepts/tools) represent the *capabilities* of an MCP server. Here's the list of tools exposed by the local MCP server:
* `migrate-status`: Checks your migration status via the `prisma migrate status` command.
* `migrate-dev`: Creates and executes a migration via the `prisma migrate dev --name ` command. The LLM will provide the `` option.
* `migrate-reset`: Resets your database via the `prisma migrate reset --force` command.
* `Prisma-Postgres-account-status`: Checks your authentication status with [Prisma Console](https://console.prisma.io) via the `platform auth show --early-access` command.
* `Create-Prisma-Postgres-Database`: Creates a new Prisma Postgres database via the `'init --db --name' '--region' '--non-interactive'` command. The LLM will provide the `` and `` options.
* `Prisma-Login`: Authenticates with [Prisma Console](https://console.prisma.io) via the `platform auth login --early-access` command.
* `Prisma-Studio`: Open Prisma Studio via the `prisma studio` command.
Usage [#usage-1]
The local Prisma MCP server follows the standard JSON-based configuration for MCP servers. Here's what it looks like:
```json
{
"mcpServers": {
"Prisma-Local": {
"command": "npx",
"args": ["-y", "prisma", "mcp"]
}
}
}
```
Sample prompts [#sample-prompts-1]
Here are some sample prompts you can use when the MCP server is running:
* "Log me into the Prisma Console."
* "Create a database in the US region."
* "Create a new `Product` table in my database."
Integrating in AI tools [#integrating-in-ai-tools]
AI tools have different ways of integrating MCP servers. In most cases, there are dedicated configuration files in which you add the JSON configuration from above. The configuration contains a command for starting the server that'll be executed by the respective tool so that the server is available to its LLM.
In this section, we're covering the config formats of the most popular AI tools.
VS Code [#vs-code]
Install the Prisma MCP server in VS Code with a single click using the link below:
VS CODE
INSTALL PRISMA MCP SERVER
This will prompt you to open VS Code. Once opened, you'll be guided to install the Prisma MCP server directly into your VS Code configuration.
If your browser blocks the link, [you can set it up manually](https://code.visualstudio.com/docs/copilot/chat/mcp-servers#_add-an-mcp-server-to-your-workspace) by creating a `.vscode/mcp.json` file in your workspace and adding:
```json title=".vscode/mcp.json"
{
"servers": {
"Prisma-Local": {
"command": "npx",
"args": ["-y", "prisma", "mcp"]
},
"Prisma-Remote": {
"url": "https://mcp.prisma.io/mcp"
}
}
}
```
Explore additional Prisma features and workflows for VS Code in [our docs](/guides/postgres/vscode).
Cursor [#cursor]
To learn more about Cursor's MCP integration, check out the [Cursor MCP docs](https://docs.cursor.com/context/model-context-protocol#configuration-locations).
Add via one-click installation [#add-via-one-click-installation]
You can add the Prisma MCP server to Cursor using the [one-click installation](https://docs.cursor.com/context/model-context-protocol#one-click-installation) by clicking on the following link:
This will prompt you to open the Cursor app in your browser. Once opened, you'll be guided to install the Prisma MCP server directly into your Cursor configuration.
Add via Cursor Settings UI [#add-via-cursor-settings-ui]
When opening the **Cursor Settings**, you can add the Prisma MCP Server as follows:
1. Select **MCP** in the settings sidenav
2. Click **+ Add new global MCP server**
3. Add the `Prisma` snippet to the `mcpServers` JSON object:
```json
{
"mcpServers": {
"Prisma-Local": {
"command": "npx",
"args": ["-y", "prisma", "mcp"]
},
"Prisma-Remote": {
"url": "https://mcp.prisma.io/mcp"
}
}
}
```
Global configuration [#global-configuration]
Adding it via the **Cursor Settings** settings will modify the global `~/.cursor/mcp.json` config file. In this case, the Prisma MCP server will be available in *all* your Cursor projects:
```json title="~/.cursor/mcp.json"
{
"mcpServers": {
"Prisma-Local": {
"command": "npx",
"args": ["-y", "prisma", "mcp"]
},
"Prisma-Remote": {
"url": "https://mcp.prisma.io/mcp"
}
// other MCP servers
}
}
```
Project configuration [#project-configuration]
If you want the Prisma MCP server to be available only in specific Cursor projects, add it to the Cursor config of the respective project inside the `.cursor` directory in the project's root:
```json title=".cursor/mcp.json"
{
"mcpServers": {
"Prisma-Local": {
"command": "npx",
"args": ["-y", "prisma", "mcp"]
},
"Prisma-Remote": {
"url": "https://mcp.prisma.io/mcp"
}
// other MCP servers
}
}
```
Windsurf [#windsurf]
To learn more about Windsurf's MCP integration, check out the [Windsurf MCP docs](https://docs.codeium.com/windsurf/mcp).
Add via Windsurf MCP Plugin Store (Recommended) [#add-via-windsurf-mcp-plugin-store-recommended]
Use the Prisma MCP plugin from the [Windsurf MCP Plugin Store](https://docs.windsurf.com/windsurf/cascade/mcp#adding-a-new-mcp-plugin). Follow [the steps here](/ai/tools/windsurf#add-prisma-mcp-server-via-windsurf-plugins) to add the Prisma MCP plugin in Windsurf. This is the simplest and recommended way to add the Prisma MCP server to Windsurf.
Add via Windsurf Settings UI [#add-via-windsurf-settings-ui]
When opening the **Windsurf Settings** (via **Windsurf - Settings** > **Advanced Settings or Command Palette** > **Open Windsurf Settings Page**), you can add the Prisma MCP Server as follows:
1. Select **Cascade** in the settings sidenav
2. Click **Add Server**
3. Add the `Prisma-Local` and/or `Prisma-Remote` snippets to the `mcpServers` JSON object:
```json
{
"mcpServers": {
"Prisma-Local": {
"command": "npx",
"args": ["-y", "prisma", "mcp"]
},
"Prisma-Remote": {
"url": "https://mcp.prisma.io/mcp"
}
}
}
```
Global configuration [#global-configuration-1]
Adding it via the **Windsurf Settings** will modify the global `~/.codeium/windsurf/mcp_config.json` config file. Alternatively, you can also manually add it to that file:
```json title="~/.codeium/windsurf/mcp_config.json"
{
"mcpServers": {
"Prisma-Local": {
"command": "npx",
"args": ["-y", "prisma", "mcp"]
},
"Prisma-Remote": {
"url": "https://mcp.prisma.io/mcp"
}
// other MCP servers
}
}
```
Warp [#warp]
You can add the Prisma MCP to Warp as a globally available tool. First, [visit your MCP settings](https://docs.warp.dev/knowledge-and-collaboration/mcp#how-to-access-mcp-server-settings) and click **+ Add**. From here, you can configure the Prisma MCP server as JSON. Use the `command` and `args` properties to start the Prisma MCP server as a setup command. You can optionally configure Prisma to activate on startup using the `start_on_launch` flag:
```json
{
"Prisma": {
"command": "npx",
"args": ["-y", "prisma", "mcp"],
"env": {},
"working_directory": null,
"start_on_launch": true
}
}
```
Hit **Save** and ensure the MCP server is running from your MCP settings panel. Then, open a new terminal window and ask Warp to manage your Prisma database. It should reach for the Prisma MCP server automatically.
To learn more about Warp's MCP integration, visit the [Warp MCP docs](https://docs.warp.dev/knowledge-and-collaboration/mcp).
Claude Code [#claude-code]
Claude Code is a terminal-based AI tool where you can add MCP servers using the `claude mcp add` command for the local MCP server:
```bash
claude mcp add prisma-local -- npx -y prisma mcp
```
or for the remote MCP server:
```bash
claude mcp add --transport http prisma-remote https://mcp.prisma.io/mcp
```
Learn more in the [Claude Code MCP docs](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/tutorials#configure-mcp-servers).
Claude Desktop only [#claude-desktop-only]
Follow the instructions in the [Claude Desktop MCP docs](https://modelcontextprotocol.io/quickstart/user#2-add-the-filesystem-mcp-server) to create the required configuration file:
* macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
* Windows: `%APPDATA%\Claude\claude_desktop_config.json`
Then add the JSON snippet to that configuration file:
```json
{
"mcpServers": {
"Prisma-Local": {
"command": "npx",
"args": ["-y", "prisma", "mcp"]
},
"Prisma-Remote": {
"url": "https://mcp.prisma.io/mcp"
}
// other MCP servers
}
}
```
Claude Desktop & Web [#claude-desktop--web]
Alternatively, you can add the *remote* MCP server as an [integration](https://www.anthropic.com/news/integrations):
1. In a new chat, find the **Connect apps** field in the main Claude UI below the input prompt field
2. Click **+ Add integration**
3. Enter the following:
* **Integration name**: `Prisma Postgres`
* **Integration URL**: `https://mcp.prisma.io/mcp`
1. Click **Add**
ChatGPT [#chatgpt]
You can add the remote Prisma MCP server to ChatGPT to manage your Prisma Postgres databases using natural language. Learn more about setting it up in our [ChatGPT integration guide](/ai/tools/chatgpt).
OpenAI Agents SDK [#openai-agents-sdk]
Here's an example for using the Prisma MCP servers in a Python script via the OpenAI Agents SDK:
```python
from openai import AsyncOpenAI
from openai.types.beta import Assistant
from openai.beta import AsyncAssistantExecutor
from openai.experimental.mcp import MCPServerStdio
from openai.types.beta.threads import Message, Thread
from openai.types.beta.tools import ToolCall
import asyncio
async def main():
# Launch both MCP servers concurrently
async with MCPServerStdio(
params={
"command": "npx",
"args": ["-y", "prisma", "mcp"]
}
) as local_server, MCPServerStdio(
params={
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.prisma.io/mcp"]
}
) as remote_server:
# Optional: list tools from both servers
local_tools = await local_server.list_tools()
remote_tools = await remote_server.list_tools()
print("Local server tools:", [tool.name for tool in local_tools])
print("Remote server tools:", [tool.name for tool in remote_tools])
# Set up the assistant with both MCP servers
agent = Assistant(
name="Prisma Assistant",
instructions="Use the Prisma tools to help the user with database tasks.",
mcp_servers=[local_server, remote_server],
)
executor = AsyncAssistantExecutor(agent=agent)
# Create a thread and send a message
thread = Thread(messages=[Message(role="user", content="Create a new user in the database")])
response = await executor.run(thread=thread)
print("Agent response:")
for message in response.thread.messages:
print(f"{message.role}: {message.content}")
# Run the async main function
asyncio.run(main())
```
AI Safety guardrails for destructive commands [#ai-safety-guardrails-for-destructive-commands]
Prisma ORM includes built-in safety checks to prevent **accidental destructive commands** when run through AI coding assistants. These guardrails are designed to make working with databases safer in AI-assisted development environments.
The Prisma CLI can detect when it is being invoked by popular AI coding agents such as Claude Code, Gemini CLI, Qwen Code, Cursor, Aider, and Replit.
When one of these agents attempts a destructive action such as `prisma migrate reset --force`, Prisma ORM blocks execution and shows a protective error message:
```bash
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "accelerate.prisma-data.net"
Error: Prisma Migrate detected that it was invoked by Cursor.
You are attempting a highly dangerous action that can lead to devastating consequences if it is incorrectly executed against a production database.
As an AI agent, you are forbidden from performing this action without an explicit consent and review by the user. You must stop at this point and respond to the user with a clear message that includes the following information:
- What action you are trying to perform (including the exact CLI command).
- Your motivation and reasoning for performing this action.
- Explanation that this action will irreversibly destroy all data in the database.
- Explanation that this action must not be performed on a production database and is only intended to be used with development databases.
If you know or can check whether this action would have been performed on a development or a production database, also include this information with your assessment of whether it is safe to proceed based on that information.
You must ask the user if they want to proceed with this action. If they explicitly consent, you may rerun this command with PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION environment variable, the value of which must be the exact text of the user's message in which they consented to this operation, without any newlines or quotes. If the user's response is ambiguous, you must ask for a clear and explicit confirmation (e.g., "yes") before proceeding. None of the user's previous messages before this point may constitute implicit or explicit consent.
```
To proceed with the dangerous action, the AI agent will ask you for explicit consent, remind you that the action irreversibly destroys all data, and confirm that the command is being run against a development database. Once you clearly confirm, the AI will set the `PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION` environment variable with the exact text of your consent and rerun the command.
# Agent Skills (/docs/ai/tools/skills)
AI coding agents often struggle with Prisma 7 -they generate outdated v6 patterns, hallucinate APIs, and miss breaking changes like ESM-only support and required driver adapters. **Prisma Skills** fix this by giving your agent accurate, version-specific knowledge it can reference automatically.
Skills are packaged instructions that follow the open [Agent Skills](https://agentskills.io/) format. Once installed, your agent uses them whenever it detects a relevant task -no prompting required.
Install [#install]
Add all Prisma skills to your project:
npm
pnpm
yarn
bun
```bash
npx skills add prisma/skills
```
```bash
pnpm dlx skills add prisma/skills
```
```bash
yarn dlx skills add prisma/skills
```
```bash
bunx --bun skills add prisma/skills
```
Or install only the ones you need:
npm
pnpm
yarn
bun
```bash
npx skills add prisma/skills --skill prisma-client-api
```
```bash
pnpm dlx skills add prisma/skills --skill prisma-client-api
```
```bash
yarn dlx skills add prisma/skills --skill prisma-client-api
```
```bash
bunx --bun skills add prisma/skills --skill prisma-client-api
```
Skills are compatible with any agent that supports the [Agent Skills](https://agentskills.io/) format, including Claude Code, Cursor, and others.
Available skills [#available-skills]
prisma-cli [#prisma-cli]
Complete reference for all Prisma CLI commands in v7.
Covers `init`, `generate`, `dev`, `migrate dev`, `migrate deploy`, `db push`, `db pull`, `db seed`, `studio`, and more. Use this when your agent needs to run Prisma commands, set up projects, or manage migrations.
prisma-client-api [#prisma-client-api]
Comprehensive Prisma Client API reference for v7.
Covers CRUD operations (`findMany`, `create`, `update`, `delete`), query options (`select`, `include`, `omit`, `orderBy`), filter operators, transactions (`$transaction`), raw queries (`$queryRaw`, `$executeRaw`), and client methods (`$connect`, `$disconnect`, `$extends`).
prisma-upgrade-v7 [#prisma-upgrade-v7]
Step-by-step migration guide from Prisma v6 to v7.
Covers ESM module configuration, required driver adapters, the new `prisma.config.ts` file, manual environment variable loading, and removed features (middleware, metrics, deprecated CLI flags). Essential for upgrading existing projects.
prisma-database-setup [#prisma-database-setup]
Guides for configuring Prisma with different database providers.
Covers PostgreSQL, Prisma Postgres, MySQL/MariaDB, SQLite, MongoDB, SQL Server, and CockroachDB. Use this when setting up a new project or switching databases.
prisma-postgres [#prisma-postgres]
Prisma Postgres workflows across Console, CLI, Management API, and SDK.
Covers `npx create-db`, Console operations, programmatic provisioning via the Management API, and the `@prisma/management-api-sdk`. Use this when creating or managing Prisma Postgres databases.
Useful commands [#useful-commands]
List available skills before installing:
npm
pnpm
yarn
bun
```bash
npx skills add prisma/skills --list
```
```bash
pnpm dlx skills add prisma/skills --list
```
```bash
yarn dlx skills add prisma/skills --list
```
```bash
bunx --bun skills add prisma/skills --list
```
List skills currently installed in your project:
npm
pnpm
yarn
bun
```bash
npx skills list
```
```bash
pnpm dlx skills list
```
```bash
yarn dlx skills list
```
```bash
bunx --bun skills list
```
Example prompts [#example-prompts]
Once skills are installed, your agent will use them automatically. Try prompts like:
* *"Set up Prisma with PostgreSQL in this project"*
* *"Upgrade this project from Prisma 6 to 7"*
* *"Write a query to find all users with their posts"*
* *"Run migrations for production"*
* *"Create a new Prisma Postgres database"*
Learn more [#learn-more]
* [Prisma Skills on skills.sh](https://skills.sh/prisma/skills) - browse available skills and install instructions
* [GitHub repository](https://github.com/prisma/skills) - source code, contribution guidelines, and skill structure
* [Agent Skills format](https://agentskills.io/) - the open standard behind skills
# Tabnine (/docs/ai/tools/tabnine)
[Tabnine](https://www.tabnine.com/) is a an AI software development platform that comes as an [extension](https://www.tabnine.com/install/) for your IDE (e.g. VS Code, WebStorm, IntelliJ, ...).
Overview [#overview]
It helps developers write code faster by:
* Providing context-aware [code completion](https://docs.tabnine.com/main/getting-started/getting-the-most-from-tabnines-code-completion) suggestions in the editor for small, repetitive coding tasks
* Offering an integrated [chat](https://docs.tabnine.com/main/getting-started/getting-the-most-from-tabnine-chat) for higher-level tasks and detailed instructions
Why use Prisma ORM with Tabnine? [#why-use-prisma-orm-with-tabnine]
AI editors like Tabnine are powerful tools that can drastically improve developer productivity. It works especially well with the following workflows:
* Data modeling and database schema design
* Constructing and optimizing database queries
* Generating CRUD functionality and other boilerplate code
* Generating plain SQL queries that can be used with [TypedSQL](/orm/prisma-client/using-raw-sql/typedsql)
* Generating code for unit and integrations tests
* Guiding through major refactorings
* Generating seeding scripts
Leveraging the Prisma schema [#leveraging-the-prisma-schema]
Because Prisma has its own [schema](/orm/prisma-schema/overview), Tabnine can understand the basic shape of your data and help you write code for the other parts of your stack.
We therefore recommend that you start out by defining your Prisma schema and then use Tabnine to build the application layer around it (including API calls, DTOs, business logic, 3rd party integrations, ...).
Data modeling and database schema design [#data-modeling-and-database-schema-design]
How Tabnine helps [#how-tabnine-helps]
Designing a database schema from scratch involves a lot of boilerplate and can be time-consuming.
Tabnine can accelerate this process by:
* Generating boilerplate for models, indexes, constraints, and relations.
* Keeping the schema consistent by sticking to naming and other conventions.
* Auto-completing model and field definitions based on common database patterns.
* Suggesting relationships and field types based on naming conventions.
Example: Defining a Prisma schema [#example-defining-a-prisma-schema]
Prompt [#prompt]
*Define a Prisma schema for a SaaS application with User, Organization, and Subscription models. Ensure relationships are properly set up.*
Generated code [#generated-code]
```prisma
generator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "postgresql"
}
model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
email String @unique
name String
organization Organization @relation(fields: [organizationId], references: [id])
organizationId Int
}
model Organization {
id Int @id @default(autoincrement())
name String
slug String @unique
subscription Subscription?
users User[]
}
model Subscription {
id Int @id @default(autoincrement())
organization Organization @relation(fields: [organizationId], references: [id])
organizationId Int @unique
plan String
status Status
}
enum Status {
Active
Paused
Expired
}
```
Constructing and optimizing database queries [#constructing-and-optimizing-database-queries]
How Tabnine helps [#how-tabnine-helps-1]
Prisma ORM provides a convenient high-level API for writing database queries intuitively. However, queries involving filters, pagination and advanced patterns can still become complex to construct.
Tabnine can help by:
* Auto-completing Prisma queries based on the schema.
* Suggesting `where` clauses for filters and `skip` / `take` options for pagination logic.
* Helping with efficiency and performance optimizations.
Example: fetching data with relationships [#example-fetching-data-with-relationships]
Prompt [#prompt-1]
*Generate a Prisma query to fetch all active users from an organization with an active subscription. Include data about the users' organizations in the query result.*
Generated code [#generated-code-1]
```ts
const activeUsers = await prisma.user.findMany({
where: {
organization: {
subscription: {
status: "ACTIVE",
},
},
},
include: {
organization: true,
},
});
```
Generating CRUD functionality and other boilerplate code [#generating-crud-functionality-and-other-boilerplate-code]
How Tabnine helps [#how-tabnine-helps-2]
Most applications require basic CRUD operations or other boilerplate code that's usually derived from the structure of the database schema. For example, an API layer may expose a set of HTTP endpoints that allow to create, read, update or delete records of a certain model. Similarly, a frontend will data fetching and state management logic to interact with these API endpoints and update the UI accordingly.
Instead of writing this code manually, Tabnine can speed up this process by:
* Generating Prisma `create`, `read`, `update`, and `delete` operations for the backend and UI components for the frontend.
* Auto-completing function names and argument types.
* Write boilerplate code while following best practices for using DTOs, error handling, consistent API design, ...
Example: Generating CRUD functionality with Next.js [#example-generating-crud-functionality-with-nextjs]
Prompt [#prompt-2]
*Generate CRUD functionality for a Next.js app based on the User model from the schema above.*
Generated code [#generated-code-2]
API endpoints [#api-endpoints]
```ts filename=app/api/users/routes.ts
import { NextResponse } from "next/server";
import prisma from "../../../lib/prisma";
export async function GET() {
const users = await prisma.user.findMany({
include: { organization: true },
});
return NextResponse.json(users);
}
export async function POST(request: Request) {
const body = await request.json();
const user = await prisma.user.create({
data: {
email: body.email,
name: body.name,
organization: {
connect: { id: body.organizationId },
},
},
include: { organization: true },
});
return NextResponse.json(user);
}
export async function PUT(request: Request) {
const body = await request.json();
const user = await prisma.user.update({
where: { id: body.id },
data: {
email: body.email,
name: body.name,
organizationId: body.organizationId,
},
include: { organization: true },
});
return NextResponse.json(user);
}
export async function DELETE(request: Request) {
const { searchParams } = new URL(request.url);
const id = searchParams.get("id");
const user = await prisma.user.delete({
where: { id: Number(id) },
});
return NextResponse.json(user);
}
```
React components [#react-components]
```ts filename=app/components/User.tsx
import React, { useState, useEffect } from 'react';
interface User {
id: number;
email: string;
name: string;
organizationId: number;
}
const User: React.FC = () => {
const [users, setUsers] = useState([]);
const [newUser, setNewUser] = useState({ email: '', name: '', organizationId: 0 });
useEffect(() => {
fetchUsers();
}, []);
const fetchUsers = async () => {
const response = await fetch('/api/users');
const data = await response.json();
setUsers(data);
};
const createUser = async () => {
await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(newUser),
});
fetchUsers();
setNewUser({ email: '', name: '', organizationId: 0 });
};
const deleteUser = async (id: number) => {
await fetch(`/api/users?id=${id}`, { method: 'DELETE' });
fetchUsers();
};
return (
);
};
export default User;
```
Generating plain SQL queries for use with TypedSQL [#generating-plain-sql-queries-for-use-with-typedsql]
How Tabnine helps [#how-tabnine-helps-3]
While Prisma provides a high-level API for querying, sometimes a developer may need to drop down to raw SQL for more low-level control of a query. In these cases, they can use [TypedSQL](/orm/prisma-client/using-raw-sql/typedsql) which provides full type safety for raq SQL queries in Prisma ORM.
One common use case are aggregation queries, such as calculating percentages of different subscription statuses in the schema example above.
Tabnine can assist by:
* Generating SQL queries based on your Prisma schema.
* Structuring complex aggregations without manual trial and error.
* Integrating the queries in your application code.
Example: Calculating the percentages of active, expired, and paused subscriptions [#example-calculating-the-percentages-of-active-expired-and-paused-subscriptions]
Prompt [#prompt-3]
*Generate a SQL query that returns the percentage of subscriptions that are Active, Paused, and Expired.*
Generated SQL query [#generated-sql-query]
```sql title="prisma/sql/subscriptionsReport.sql"
SELECT
status,
COUNT(*) * 100.0 / (SELECT COUNT(*) FROM "Subscription") AS percentage
FROM "Subscription"
GROUP BY status;
```
Application code [#application-code]
```ts
import { PrismaClient } from "../prisma/generated/client";
import { subscriptionsReport } from "../prisma/generated/client/sql";
const prisma = new PrismaClient();
const usersWithPostCounts = await prisma.$queryRawTyped(subscriptionsReport());
console.log(usersWithPostCounts);
```
Generating code for unit and integration tests [#generating-code-for-unit-and-integration-tests]
How Tabnine helps [#how-tabnine-helps-4]
Writing tests ensures that Prisma-based applications function correctly and behave according to requirements and expectations. However, writing tests is a time-consuming activity that often follows predictable and repetitive patterns.
Tabnine can drastically speed up writing tests by:
* Generating test boilerplate for both unit and integration tests.
* Suggesting mocks and fixtures for Prisma database interactions.
* Helping structure test cases to follow best practices.
* Providing integration test scaffolding for testing Prisma with a real or in-memory database.
Example: Writing a unit test for a Prisma service [#example-writing-a-unit-test-for-a-prisma-service]
Prompt [#prompt-4]
*Generate a Jest unit test for a Prisma service function that fetches all active users.*
Generated code [#generated-code-3]
```ts filename=__tests__/userService.test.ts
import { prismaMock } from "../prisma/singleton";
import { getActiveUsers } from "../services/userService";
test("should return only active users", async () => {
prismaMock.user.findMany.mockResolvedValue([
{ id: 1, name: "Alice", email: "alice@example.com" },
{ id: 2, name: "Bob", email: "bob@example.com" },
]);
const users = await getActiveUsers();
expect(users).toHaveLength(2);
expect(users[0].email).toBe("alice@example.com");
});
```
Guiding through major refactorings [#guiding-through-major-refactorings]
How Tabnine helps [#how-tabnine-helps-5]
Thanks to Prisma ORM's type safe queries, refactoring are more safe and predictable than with other ORMs: After making schema changes, the generated Prisma Client code will be updated and the TypeScript compiler will highlight all places that need a change.
However, there may still be more difficult situations during a refactoring, e.g. when business logic or complex queries need to be adjusted.
Tabnine can assist during refactorings by:
* Identifying patterns in your code and suggesting refactorings while maintaining consistency.
* Helping update database queries after schema changes and reducing manual effort.
* Providing function rewrites to simplify and optimize logic.
* Suggesting breaking changes that need to be handled across your codebase.
Example: Refactoring a Prisma query after a schema change [#example-refactoring-a-prisma-query-after-a-schema-change]
Prompt [#prompt-5]
*Refactor this Prisma query to support soft deletion using a `deletedAt` timestamp field in the User model.*
Initial code [#initial-code]
```ts
const users = await prisma.user.findMany();
```
Refactored code [#refactored-code]
```ts
const users = await prisma.user.findMany({
where: { deletedAt: null },
});
```
Generating seeding scripts [#generating-seeding-scripts]
How Tabnine helps [#how-tabnine-helps-6]
Seeding a database with realistic test data can be cumbersome. Realistic seed data is helpful during development because it gives the developer a better impression of the application when it's used in the real-world. Tabnine can help with database seeding by:
* Generating scripts with structured seed data based on the schema and with specific requirements.
* Creating real-looking placeholder data that can be used to test the app.
* Generate specific data to cover edge cases.
Example: Creating a seed script [#example-creating-a-seed-script]
Prompt [#prompt-6]
*Generate a Prisma seed script for populating User, Organization, and Subscription models.*
Generated code [#generated-code-4]
```ts
import { PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient();
async function main() {
await prisma.organization.create({
data: {
name: "Prisma Corp",
slug: "prisma-corp",
subscription: {
create: {
plan: "PRO",
status: "ACTIVE",
},
},
users: {
create: [
{ name: "Alice Doe", email: "alice@prisma.io" },
{ name: "Bob Smith", email: "bob@prisma.io" },
],
},
},
});
console.log("Seed data created successfully");
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
Using the Prisma VS Code extension to manage your database [#using-the-prisma-vs-code-extension-to-manage-your-database]
The [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) is a powerful tool for building applications with [Prisma Postgres](/postgres). If you are using Tabnine in an editor that allows you to install the Prisma VS Code extension and you are using Prisma Postgres, you should use it. The extension provides a dedicated UI for managing Prisma Postgres instances, both local and remote, making it easy to view, create, and delete instances, push local databases to the cloud, and visualize your schema.
Database management UI [#database-management-ui]
With its built-in database management interface, the [Prisma VS Code extension](/guides/postgres/vscode) lets you easily work with local and remote Prisma Postgres instances from inside your editor.
Workflows [#workflows]
The UI enables the following workflows:
* Authenticate with the [Prisma Console](https://console.prisma.io)
* View, create and delete Prisma Postgres instances (local & remote)
* "Push to cloud": Easily deploy a local Prisma Postgres instance
* View and edit data via an embedded Prisma Studio
* Visualize your database schema
Usage [#usage]
To manage Prisma Postgres instances via the UI in the Prisma VS Code extension:
1. Ensure you have the latest version of the [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) installed
2. Find the Prisma logo in the **Activity Bar**
3. Click the **Sign in to get started** button
4. Authenticate with the [Prisma Console](https://console.prisma.io) using the sign-in prompt, then select a target [workspace](/console/concepts#workspace)
Prisma Studio built-in [#prisma-studio-built-in]
Beyond managing your database instances, the Prisma VS Code extension embeds Prisma Studio directly in your editor, making it easy to perform create, update, and delete operations on your database right inside Windsurf. Follow these [easy steps](/studio/integrations/vscode-integration) to get started.
# Windsurf (/docs/ai/tools/windsurf)
[Windsurf Editor](https://windsurf.com/editor/) is an AI-powered code editor designed to boost productivity by automating repetitive coding tasks. When paired with Prisma, a robust and type-safe toolkit for database workflows, it becomes a powerful solution for managing and optimizing database schemas, queries, and data seeding.
This guide provides detailed instructions for effectively using Prisma with Windsurf to:
* Define project-specific best practices with `.windsurfrules`.
* Use Windsurf's context-aware capabilities.
* Generate schemas, queries, and seed data tailored to your database.
While this guide is focused on Windsurf, these patterns should work with any AI editor. [Let us know on X](https://pris.ly/x?utm_source=docs\&utm_medium=inline_text) if you'd like us to create guides for your preferred tool!
Prisma MCP server [#prisma-mcp-server]
Prisma provides its own [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) server that lets you manage Prisma Postgres databases, model database schemas, and even chat through migrations.
Add Prisma MCP server via Windsurf Plugins [#add-prisma-mcp-server-via-windsurf-plugins]
You can add the Prisma MCP server via [Windsurf MCP Plugin Store](https://docs.windsurf.com/windsurf/cascade/mcp#adding-a-new-mcp-plugin).
New MCP plugins can be added from the **Plugin Store**, which you can access by clicking on the **Plugins** icon in the top right menu in the **Cascade** panel, or from the **Windsurf Settings** > **Cascade** > **Plugins** section. Just search for **Prisma** in the **Plugin Store** and install the `Prisma` plugin.
You can also add the Prisma MCP server manually. Learn more about how you can add the MCP server manually to Windsurf [here](/ai/tools/mcp-server#windsurf).
Defining project-specific rules with .windsurfrules [#defining-project-specific-rules-with-windsurfrules]
The [`.windsurfrules` file](https://docs.windsurf.com/windsurf/memories#windsurfrules) in Windsurf allows you to enforce best practices and development standards tailored to your Prisma project. By defining clear and consistent rules, you can ensure that Windsurf generates clean, maintainable, and project-specific code with minimal manual adjustments.
To implement these rules, create a `.windsurfrules` file in the root of your project. Below is an example configuration:
Example
.windsurfrules
file
```text title=".windsurfrules"
You are a senior TypeScript/JavaScript programmer with expertise in Prisma, clean code principles, and modern backend development.
Generate code, corrections, and refactorings that comply with the following guidelines:
TypeScript General Guidelines
Basic Principles
- Use English for all code and documentation.
- Always declare explicit types for variables and functions.
- Avoid using "any".
- Create precise, descriptive types.
- Use JSDoc to document public classes and methods.
- Maintain a single export per file.
- Write self-documenting, intention-revealing code.
Nomenclature
- Use PascalCase for classes and interfaces.
- Use camelCase for variables, functions, methods.
- Use kebab-case for file and directory names.
- Use UPPERCASE for environment variables and constants.
- Start function names with a verb.
- Use verb-based names for boolean variables:
- isLoading, hasError, canDelete
- Use complete words, avoiding unnecessary abbreviations.
- Exceptions: standard abbreviations like API, URL
- Accepted short forms:
- i, j for loop indices
- err for errors
- ctx for contexts
Functions
- Write concise, single-purpose functions.
- Aim for less than 20 lines of code.
- Name functions descriptively with a verb.
- Minimize function complexity:
- Use early returns.
- Extract complex logic to utility functions.
- Leverage functional programming techniques:
- Prefer map, filter, reduce.
- Use arrow functions for simple operations.
- Use named functions for complex logic.
- Use object parameters for multiple arguments.
- Maintain a single level of abstraction.
Data Handling
- Encapsulate data in composite types.
- Prefer immutability.
- Use readonly for unchanging data.
- Use as const for literal values.
- Validate data at the boundaries.
Error Handling
- Use specific, descriptive error types.
- Provide context in error messages.
- Use global error handling where appropriate.
- Log errors with sufficient context.
Prisma-Specific Guidelines
Schema Design
- Use meaningful, domain-driven model names.
- Leverage Prisma schema features:
- Use @id for primary keys.
- Use @unique for natural unique identifiers.
- Utilize @relation for explicit relationship definitions.
- Keep schemas normalized and DRY.
- Use meaningful field names and types.
- Implement soft delete with deletedAt timestamp.
- Use Prisma's native type decorators.
Prisma Client Usage
- Always use type-safe Prisma client operations.
- Prefer transactions for complex, multi-step operations.
- Handle optional relations explicitly.
- Use Prisma's filtering and pagination capabilities.
Database Migrations
- Create migrations for schema changes.
- Use descriptive migration names.
- Review migrations before applying.
- Never modify existing migrations.
- Keep migrations idempotent.
Error Handling with Prisma
- Catch and handle Prisma-specific errors:
- PrismaClientKnownRequestError
- PrismaClientUnknownRequestError
- PrismaClientValidationError
- Provide user-friendly error messages.
- Log detailed error information for debugging.
Testing Prisma Code
- Use in-memory database for unit tests.
- Mock Prisma client for isolated testing.
- Test different scenarios:
- Successful operations
- Error cases
- Edge conditions
- Use factory methods for test data generation.
- Implement integration tests with actual database.
Performance Considerations
- Use select and include judiciously.
- Avoid N+1 query problems.
- Use findMany with take and skip for pagination.
- Leverage Prisma's distinct for unique results.
- Profile and optimize database queries.
Security Best Practices
- Never expose raw Prisma client in APIs.
- Use input validation before database operations.
- Implement row-level security.
- Sanitize and validate all user inputs.
- Use Prisma's built-in protections against SQL injection.
Coding Style
- Keep Prisma-related code in dedicated repositories/modules.
- Separate data access logic from business logic.
- Create repository patterns for complex queries.
- Use dependency injection for Prisma services.
Code Quality
- Follow SOLID principles.
- Prefer composition over inheritance.
- Write clean, readable, and maintainable code.
- Continuously refactor and improve code structure.
Development Workflow
- Use version control (Git).
- Implement comprehensive test coverage.
- Use continuous integration.
- Perform regular code reviews.
- Keep dependencies up to date.
```
This file ensures consistent and maintainable code generation, reducing manual intervention while improving project quality.
Using Windsurf's context-aware capabilities [#using-windsurfs-context-aware-capabilities]
Windsurf's [context-awareness](https://docs.windsurf.com/context-awareness/overview) features let you leverage both your project files and external resources to enhance the AI's understanding of your project. By including your Prisma schema and relevant documentation in the context, you enable Windsurf to generate more accurate queries, tests, and seed data based on your database schema.
Including Additional Prisma Resources [#including-additional-prisma-resources]
Windsurf comes with built-in knowledge of common libraries, but you can further enhance its awareness by explicitly referencing external Prisma resources. This is especially useful for staying up-to-date or providing authoritative context for code generation and best practices.
For example, you might reference:
* [Prisma Changelog](https://www.prisma.io/changelog)
* [Prisma Blog](https://www.prisma.io/blog)
* [Prisma Documentation](/)
Reference the resource in your requests: [#reference-the-resource-in-your-requests]
When asking for code, explanations, or reviews, include the link to the relevant Prisma resource and specify that it should be used as a reference.
```bash
Generate a migration script using best practices from prisma.io/docs.
```
Request persistent awareness: [#request-persistent-awareness]
Ask Windsurf to always consider a specific resource for all Prisma-related work in your project.
```bash
Always use the Prisma Changelog at prisma.io/changelog for Prisma updates in this project.
```
Ask for regular updates: [#ask-for-regular-updates]
If you want Windsurf to check for updates or new features, explicitly request it.
```bash
Before suggesting Prisma code, check the latest changes from prisma.io/changelog.
```
By referencing external resources directly in your requests or project guidelines, you ensure Windsurf leverages the most current and relevant Prisma information.
Using schema as context [#using-schema-as-context]
Out of the box, Windsurf automatically considers the current file, other open files, and indexed portions of your codebase as context. To ensure Cascade fully leverages your Prisma schema, keep your `schema.prisma` file open or pinned in the editor.
Generating Prisma schema [#generating-prisma-schema]
Windsurf can generate Prisma schemas from high-level descriptions, enabling you to quickly establish a solid foundation for your database schema. By providing a clear and detailed prompt, Windsurf creates Prisma schemas tailored to your requirements. Whether you need a general foundational schema or a highly specific one for detailed use cases, Windsurf can deliver with precision. Here's an example prompt and its corresponding result:
LLMs may produce different results each time, even with the same prompt.
Prompt to generate Prisma schema
Result
```text copy
"Create a Prisma schema for a SaaS app using PostgreSQL as a provider with `User`, `Organization`, and `Subscription` models, ensuring all models include `createdAt` and `updatedAt` DateTime fields with defaults, a soft-delete `deletedAt` field, and proper relationships between entities."
```
```prisma title="schema.prisma" showLineNumbers
generator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "postgresql"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
organization Organization @relation(fields: [organizationId], references: [id])
organizationId Int
role UserRole @default(MEMBER)
}
model Organization {
id Int @id @default(autoincrement())
name String
slug String @unique
subscription Subscription?
users User[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
}
model Subscription {
id Int @id @default(autoincrement())
organization Organization @relation(fields: [organizationId], references: [id])
organizationId Int @unique
plan SubscriptionPlan
status SubscriptionStatus @default(ACTIVE)
startDate DateTime
endDate DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
}
enum UserRole {
ADMIN
MEMBER
}
enum SubscriptionPlan {
FREE
BASIC
PREMIUM
ENTERPRISE
}
enum SubscriptionStatus {
ACTIVE
CANCELED
EXPIRED
PAST_DUE
}
```
Generating Prisma queries [#generating-prisma-queries]
Windsurf can help you create queries tailored to your Prisma schema, whether for basic data retrieval or complex, optimized operations. To get the best results, focus on writing clear, specific prompts that define your requirements, such as the fields to include, conditions to apply, and relationships to traverse. This ensures Windsurf generates accurate, performant, and type-safe queries. Here's an example prompt and its resulting query:
Prompt to generate a database query
Result
```text copy
"Generate a query to retrieve all User records associated with an Organization that has an `active` Subscription, while excluding any records where the `deletedAt` field is set."
```
```ts showLineNumbers
const activeUsers = await prisma.user.findMany({
where: {
deletedAt: null,
organization: {
deletedAt: null,
subscription: {
deletedAt: null,
status: "ACTIVE",
},
},
},
include: {
organization: {
include: {
subscription: true,
},
},
},
orderBy: {
createdAt: "desc",
},
skip: 0,
take: 10,
});
```
Creating seed files with Windsurf [#creating-seed-files-with-windsurf]
Writing seed scripts can be a tedious process, but Windsurf simplifies it by quickly generating structured and organized seed code. By providing clear instructions, you can guide Windsurf to create scripts that populate your database with realistic data, including handling relationships and complex structures defined in your schema. Here's an example prompt and its resulting seed script:
Prompt to seed the database
Result
```text copy
"Generate code to populate the Prisma schema with realistic data for the User, Organization, and Subscription models, ensuring all necessary fields are included."
```
```ts title="seed.ts"
import {
PrismaClient,
UserRole,
SubscriptionPlan,
SubscriptionStatus,
} from "../prisma/generated/client";
const prisma = new PrismaClient();
async function main() {
// Clear existing data
await prisma.user.deleteMany();
await prisma.subscription.deleteMany();
await prisma.organization.deleteMany();
const organizations = [
{
name: "Tech Innovators",
slug: "tech-innovators",
subscription: {
plan: SubscriptionPlan.ENTERPRISE,
status: SubscriptionStatus.ACTIVE,
startDate: new Date("2024-01-01"),
},
users: [
{
name: "Emma Thompson",
email: "emma@techinnovators.com",
role: UserRole.ADMIN,
password: "password123",
},
{
name: "Michael Chen",
email: "michael@techinnovators.com",
role: UserRole.MEMBER,
password: "password123",
},
],
},
{
name: "Digital Solutions",
slug: "digital-solutions",
subscription: {
plan: SubscriptionPlan.PREMIUM,
status: SubscriptionStatus.ACTIVE,
startDate: new Date("2024-01-15"),
},
users: [
{
name: "Sarah Wilson",
email: "sarah@digitalsolutions.com",
role: UserRole.ADMIN,
password: "password123",
},
{
name: "James Miller",
email: "james@digitalsolutions.com",
role: UserRole.MEMBER,
password: "password123",
},
],
},
{
name: "Cloud Systems",
slug: "cloud-systems",
subscription: {
plan: SubscriptionPlan.BASIC,
status: SubscriptionStatus.ACTIVE,
startDate: new Date("2024-02-01"),
},
users: [
{
name: "David Garcia",
email: "david@cloudsystems.com",
role: UserRole.ADMIN,
password: "password123",
},
{
name: "Lisa Wang",
email: "lisa@cloudsystems.com",
role: UserRole.MEMBER,
password: "password123",
},
],
},
{
name: "Data Analytics Co",
slug: "data-analytics",
subscription: {
plan: SubscriptionPlan.PREMIUM,
status: SubscriptionStatus.ACTIVE,
startDate: new Date("2024-01-10"),
},
users: [
{
name: "Alex Johnson",
email: "alex@dataanalytics.com",
role: UserRole.ADMIN,
password: "password123",
},
{
name: "Rachel Kim",
email: "rachel@dataanalytics.com",
role: UserRole.MEMBER,
password: "password123",
},
],
},
{
name: "Smart Solutions",
slug: "smart-solutions",
subscription: {
plan: SubscriptionPlan.FREE,
status: SubscriptionStatus.ACTIVE,
startDate: new Date("2024-02-15"),
},
users: [
{
name: "Daniel Brown",
email: "daniel@smartsolutions.com",
role: UserRole.ADMIN,
password: "password123",
},
{
name: "Maria Rodriguez",
email: "maria@smartsolutions.com",
role: UserRole.MEMBER,
password: "password123",
},
],
},
];
for (const org of organizations) {
const createdOrg = await prisma.organization.create({
data: {
name: org.name,
slug: org.slug,
subscription: {
create: {
plan: org.subscription.plan,
status: org.subscription.status,
startDate: org.subscription.startDate,
},
},
},
});
for (const user of org.users) {
await prisma.user.create({
data: {
name: user.name,
email: user.email,
password: user.password,
role: user.role,
organizationId: createdOrg.id,
},
});
}
}
console.log("Seed data created successfully");
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
Using the Prisma VS Code extension to manage your database [#using-the-prisma-vs-code-extension-to-manage-your-database]
The [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) is a powerful tool for building applications with [Prisma Postgres](/postgres). You can also use it in Windsurf by installing the extension. It provides a dedicated UI for managing Prisma Postgres instances, both local and remote, making it easy to view, create, and delete instances, push local databases to the cloud, and visualize your schema.
Database management UI [#database-management-ui]
With its built-in database management interface, [the Prisma VS Code extension](/guides/postgres/vscode) lets you easily work with local and remote Prisma Postgres instances from inside your editor.
Workflows [#workflows]
The UI enables the following workflows:
* Authenticate with the [Prisma Console](https://console.prisma.io)
* View, create and delete Prisma Postgres instances (local & remote)
* "Push to cloud": Easily deploy a local Prisma Postgres instance
* View and edit data via an embedded Prisma Studio
* Visualize your database schema
Usage [#usage]
To manage Prisma Postgres instances via the UI in the Prisma VS Code extension:
1. Ensure you have the latest version of the [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) installed
2. Find the Prisma logo in the **Activity Bar**
3. Click the **Sign in to get started** button
4. Authenticate with the [Prisma Console](https://console.prisma.io) using the sign-in prompt, then select a target [workspace](/console/concepts#workspace)
Prisma Studio built-in [#prisma-studio-built-in]
Beyond managing your database instances, the Prisma VS Code extension embeds Prisma Studio directly in your editor, making it easy to perform create, update, and delete operations on your database right inside Windsurf. Follow these [easy steps](/studio/integrations/vscode-integration) to get started.
Additional resources [#additional-resources]
Using Windsurf with Prisma can speed up development while ensuring clean and maintainable database code. To keep learning:
* [Windsurf Documentation](https://docs.windsurf.com/windsurf/getting-started)
* [Prisma Documentation](/)
# Linktree Clone SaaS (/docs/ai/tutorials/linktree-clone)
Introduction [#introduction]
In this comprehensive vibe coding tutorial, you'll build a complete **Linktree clone SaaS** application from scratch using AI assistance. This guide teaches you how to leverage AI tools to rapidly develop a full-stack application with:
* **[Next.js](https://nextjs.org/)** — React framework for production
* **[Prisma ORM](https://www.prisma.io/orm)** — Type-safe database access
* **[Prisma Postgres](https://www.prisma.io/postgres)** — Serverless PostgreSQL database
* **[Clerk](https://clerk.com/)** — Authentication and user management
By the end of this tutorial, you'll have a working SaaS application where users can sign up, create their profile, and manage their personal link page — all built with AI-assisted development.
What is Vibe Coding?
Vibe coding is a development approach where you collaborate with AI assistants to build applications. You describe what you want to build, and the AI helps generate the code while you guide the direction and make architectural decisions.
Video tutorial [#video-tutorial]
Watch this step-by-step walkthrough of the entire build process:
Prerequisites [#prerequisites]
Before starting this tutorial, make sure you have:
* [Node.js 20+](https://nodejs.org) installed
* A [Clerk account](https://clerk.com) (free tier works)
* An AI coding assistant ([Cursor](https://cursor.com), [Windsurf](https://windsurf.com), [GitHub Copilot](https://github.com/features/copilot), etc.)
* Basic familiarity with React and TypeScript
Recommended AI Models
For best results, we recommend using the latest AI models such as (minimum) Claude Sonnet 4, Gemini 2.5 Pro, or GPT-4o. These models provide better code generation accuracy and understand complex architectural patterns.
1. Set Up Your Project [#1-set-up-your-project]
Let's start by creating a new Next.js application:
npm
pnpm
yarn
bun
```bash
npx create-next-app@latest app-name
```
```bash
pnpm dlx create-next-app@latest app-name
```
```bash
yarn dlx create-next-app@latest app-name
```
```bash
bunx --bun create-next-app@latest app-name
```
Once the setup is complete, you'll need to add **Prisma** and **Prisma Postgres** to your project. We've prepared a detailed prompt that handles the complete setup for you.
👉 **Find the setup prompt here:** [Next.js + Prisma Prompt](/ai/prompts/nextjs)
**How to use it:**
1. Create a new file called `prompt.md` at the root of your project
2. Copy and paste the prompt content into this file
3. Ask your AI assistant to follow the instructions in this file
The AI will set up Prisma ORM, create your database connection, and configure everything automatically.
Quick Check [#quick-check]
Let's verify everything is working correctly:
1. Start your development server:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
2. Open Prisma Studio to view your seed data:
npm
pnpm
yarn
bun
```bash
npm run db:studio
```
```bash
pnpm run db:studio
```
```bash
yarn db:studio
```
```bash
bun run db:studio
```
If both commands run without errors and you can see sample data in Prisma Studio, you're ready to continue!
Good Practice: Commit Early and Often
Throughout this tutorial, we'll commit our changes regularly. This makes it easy to track progress and roll back if something goes wrong.
Start by linking your project to GitHub:
```bash
git init
git add .
git commit -m "Initial setup: Next.js app with Prisma"
```
2. Set Up Authentication with Clerk [#2-set-up-authentication-with-clerk]
Now let's add user authentication using [Clerk](https://clerk.com/), which provides a complete authentication solution out of the box.
**Steps to follow:**
1. Go to [Clerk](https://clerk.com/) and create an account (if you don't have one)
2. Create a new application in your Clerk dashboard
3. Follow Clerk's official quickstart guide to integrate it with your Next.js app:
👉 **Clerk Next.js Quickstart:** [clerk.com/docs/nextjs/getting-started/quickstart](https://clerk.com/docs/nextjs/getting-started/quickstart)
The guide will walk you through installing the SDK, adding environment variables, and wrapping your app with the `ClerkProvider`.
Once complete, commit your changes:
```bash
git add .
git commit -m "Add Clerk authentication setup"
```
3. Update Your Database Schema [#3-update-your-database-schema]
Since we're building a Linktree clone, we need to update the database schema to support our specific data model. This includes:
* A `User` model with a unique `username` (for public profile URLs like `/username`)
* A `Link` model to store each user's links
Replace the contents of your `prisma/schema.prisma` file with the following:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql"
}
// Example User model for testing
model User {
id Int @id @default(autoincrement())
email String @unique
username String @unique // Important for the public profile URL
clerkId String @unique // Links to Clerk Auth
name String?
links Link[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Link {
id Int @id @default(autoincrement())
title String
url String
userId Int
user User @relation(fields: [userId], references: [id])
createdAt DateTime @default(now())
}
```
Since we're changing the schema structure, we need to reset the database. The existing seed data was just for testing purposes, so it's safe to drop and recreate:
npm
pnpm
yarn
bun
```bash
npx prisma db push --force-reset
```
```bash
pnpm dlx prisma db push --force-reset
```
```bash
yarn dlx prisma db push --force-reset
```
```bash
bunx --bun prisma db push --force-reset
```
This command:
* **Drops** the existing database tables
* **Creates** new tables based on your updated schema
Use with Caution
The `--force-reset` flag deletes all existing data. This is fine during prototyping, but never use it on a production database! Once your schema is stable, switch to `prisma migrate dev` for proper migration tracking.
Quick Check [#quick-check-1]
Open Prisma Studio to verify the new schema is applied:
npm
pnpm
yarn
bun
```bash
npm run db:studio
```
```bash
pnpm run db:studio
```
```bash
yarn db:studio
```
```bash
bun run db:studio
```
You should see the updated `User` and `Link` tables (they'll be empty, which is expected).
**Commit your changes:**
```bash
git add .
git commit -m "Update schema for Linktree clone"
```
4. Connect Clerk Users to Your Database [#4-connect-clerk-users-to-your-database]
Here's the challenge: when a user signs in with Clerk, they exist in Clerk's system but **not** in your database. We need to bridge this gap.
Our approach: create a "Claim Username" flow where users pick their unique username (e.g., `yourapp.com/johndoe`) after signing in for the first time.
Use ASK Mode First
When working with AI assistants, we recommend using **ASK mode** by default to review suggested changes before applying them. Only switch to AGENT mode once you're comfortable with the proposed code.
The Prompt [#the-prompt]
Copy and paste the following prompt into your AI assistant:
```markdown
Connect Clerk authentication to your Prisma database with a "Claim Username" flow.
**Goal:**
When a user signs in via Clerk, they don't automatically exist in YOUR database. Create a flow where:
1. Logged out → Show landing page with "Sign In" button
2. Logged in but no DB profile → Show "Claim Username" form
3. Has DB profile → Show dashboard
**User Model (already in schema):**
model User {
id Int @id @default(autoincrement())
email String @unique
username String @unique
clerkId String @unique
name String?
links Link[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
**Files to create/update:**
1. `app/actions.ts` - Server Action with `claimUsername(formData)`
2. `app/page.tsx` - Three-state UI (logged out / claim username / dashboard)
3. `app/api/users/route.ts` - Update POST to accept `clerkId`, `email`, `username`, `name`
**Requirements:**
- Use `'use server'` directive in `app/actions.ts`
- Use `currentUser()` from `@clerk/nextjs/server` to get auth user
- Store `clerkId`, `email`, `username`, and `name` in User model
- Use `redirect("/")` after successful profile creation
- Handle username uniqueness (Prisma will throw if duplicate)
**Pattern:**
1. Server Action receives FormData, validates username (min 3 chars, alphanumeric + underscore)
2. Creates User in Prisma with Clerk's `user.id` as `clerkId`
3. Page.tsx checks: `currentUser()` → then `prisma.user.findUnique({ where: { clerkId } })`
4. Render different UI based on auth state and DB state
**Keep it simple:**
- No middleware file needed
- No webhook sync (user creates profile manually)
- Basic validation (username length >= 3)
- Errors just throw (no fancy error UI for MVP)
```
After the AI generates the code, you may see TypeScript errors. This is because the Prisma Client needs to be regenerated to reflect the schema changes:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
Quick Check [#quick-check-2]
Test the complete flow:
1. Stop your dev server and restart it
2. Open your app in the browser
3. Sign up as a new user through Clerk
4. You should see the "Claim Username" form
5. Enter a username and submit
6. Verify the user appears in Prisma Studio (`npm run db:studio`)
If everything works, commit your changes!
5. Upgrade the UI Design [#5-upgrade-the-ui-design]
Let's give our app a more polished, friendly look inspired by platforms like Buy Me a Coffee.
👉 [Visit Buy Me a Coffee for design inspiration](https://buymeacoffee.com/)
Copy and paste this prompt to your AI assistant:
```markdown
Design a minimal, friendly UI inspired by Buy Me a Coffee.
**Theme:**
- Force light mode only (no dark mode switching)
- Clean white background (#FFFFFF)
- Black text (#000000) for headings
- Gray (#6B7280) for secondary text
- Bright yellow (#FFDD00) for CTA buttons
- Light gray (#F7F7F7) for cards/sections
- Subtle borders (#E5E5E5)
**Typography & Spacing:**
- Large, bold headlines (text-5xl or bigger)
- Generous whitespace and padding
- Rounded corners everywhere (rounded-full for buttons, rounded-xl for cards)
**Buttons:**
- Primary: Yellow background, black text, rounded-full, font-semibold
- Secondary: White background, border, rounded-full
**Overall feel:**
- Friendly, approachable, not corporate
- Minimal — only essential elements
- Mobile-first with good touch targets (py-4, px-8 on buttons)
- One unified canvas — background applies to the entire page (body), with white cards floating on top. No separate section backgrounds.
Use Tailwind CSS. Keep it simple.
```
Quick Check [#quick-check-3]
After the AI applies the changes:
1. Refresh your app and browse through all pages
2. Verify the design has updated but **no functionality has changed**
3. Test the sign-in flow and username claim process
Once verified, commit the changes:
```bash
git add .
git commit -m "Update UI design"
```
6. Build Link Management (Add & Delete) [#6-build-link-management-add--delete]
Now let's add the core functionality: managing links! Users should be able to add new links and delete existing ones from their dashboard.
Copy and paste this prompt:
```markdown
Build a simple dashboard for managing links using Next.js App Router and Server Actions.
**Requirements:**
- Server Component page that fetches user data from database
- "Add Link" form with Title and URL inputs
- List of existing links with Delete button
- Use Server Actions (no API routes) for create/delete operations
- Use `revalidatePath("/")` after mutations to refresh the page
**Pattern:**
1. Create server actions in `actions.ts` with `'use server'` directive
2. Pass actions directly to form `action` prop
3. Keep page.tsx as a Server Component (no 'use client')
4. Use hidden inputs for IDs (e.g., ``)
**Keep it simple:**
- No loading states
- No client components
- No confirmation dialogs
- Just forms + server actions + revalidation
This is the MVP pattern for CRUD with Next.js App Router.
```
Quick Check [#quick-check-4]
Test the link management:
1. Add a new link with a title and URL
2. Verify it appears in your dashboard
3. Delete the link
4. Verify it's removed
Both operations should work instantly without page navigation.
7. Create Public Profile Pages [#7-create-public-profile-pages]
This is the heart of a Linktree clone: public profile pages that anyone can visit at `/username`.
Copy and paste this prompt:
```markdown
Build a public profile page at /[username] using Next.js App Router dynamic routes.
**Requirements:**
- Create `app/[username]/page.tsx` as a Server Component
- Fetch user + links from database by username (from URL params)
- Return 404 if user not found (use `notFound()` from next/navigation)
- Display: avatar (first letter), username, name, and list of links
- Links open in new tab with `target="_blank"`
- Add a small "Create your own" link at the bottom
**Pattern:**
1. Get params: `const { username } = await params`
2. Query database with `findUnique({ where: { username } })`
3. If no user: call `notFound()`
4. Render profile with links as clickable buttons
**Keep it simple:**
- No auth required (it's a public page)
- Pure Server Component (no 'use client')
- Basic styling with hover effects
This is the core "Linktree" feature — anyone can visit /username to see the links.
```
Quick Check [#quick-check-5]
Test your public profile:
1. Navigate to `localhost:3000/your-username` (replace with your actual username)
2. Verify your profile and links display correctly
3. Click a link and confirm it opens in a new tab
8. Add a "Copy Link" Button [#8-add-a-copy-link-button]
Make it easy for users to share their profile URL with a one-click copy button.
Copy and paste this prompt:
```markdown
**Requirements:**
- Create a Client Component (`'use client'`) for the button
- Use `navigator.clipboard.writeText(url)` to copy
- Show "Copied!" feedback for 2 seconds after clicking
- Use `useState` to toggle the button text
**Pattern:**
1. Create `app/components/copy-button.tsx` with 'use client'
2. Accept `url` as a prop
3. On click: copy to clipboard, set `copied` to true
4. Use `setTimeout` to reset after 2 seconds
5. Import and use in your Server Component page
**Keep it simple:**
- One small client component
- No toast libraries
- Just inline text feedback ("Copy link" → "Copied!")
```
Quick Check [#quick-check-6]
1. Find the "Copy link" button on your dashboard
2. Click it and verify it shows "Copied!"
3. Paste somewhere to confirm the URL was copied correctly
9. Create a Custom 404 Page [#9-create-a-custom-404-page]
When someone visits a non-existent username, they should see a friendly error page instead of a generic 404.
Copy and paste this prompt:
```markdown
Create a custom 404 page for Next.js App Router.
**Requirements:**
- Create `app/not-found.tsx` (Server Component)
- Display: 404 heading, friendly message, "Go home" button
- Match your app's design (colors, fonts, spacing)
**Pattern:**
- Next.js automatically uses `not-found.tsx` when `notFound()` is called
- Or when a route doesn't exist
- No configuration needed — just create the file
**Keep it simple:**
- Static page, no data fetching
- One heading, one message, one link
- Same styling as rest of the app
```
Quick Check [#quick-check-7]
Test the 404 page by visiting a random URL like `/this-user-does-not-exist`. You should see your custom 404 page with a link back to the homepage.
10. Add a Custom Background [#10-add-a-custom-background]
Let's make the app more visually distinctive with a custom background pattern.
**First**, either:
* Download a background SVG pattern you like, or
* Create your own using tools like [SVG Backgrounds](https://www.svgbackgrounds.com/) or [Hero Patterns](https://heropatterns.com/)
**Then**, save it as `background.svg` in your `public/` folder.
Copy and paste this prompt:
````markdown
Add a custom SVG background to my app.
**Requirements:**
- The svg file is in the `public/` folder (e.g., `public/background.svg`)
- Apply it as a fixed, full-cover background on the body
**Pattern:**
In `globals.css`, update the body:
```css
body {
background: var(--background) url("/background.svg") center/cover no-repeat fixed;
min-height: 100vh;
}
```
**Key properties:**
- `center/cover` — centers and scales to fill
- `no-repeat` — prevents tiling
- `fixed` — background stays in place when scrolling
Files in `public/` are served at the root URL, so `/background.svg` works.
````
Quick Check [#quick-check-8]
1. Refresh your app
2. Verify the background appears on **all pages** (homepage, dashboard, profile pages, 404)
3. If the background doesn't appear everywhere, ask your AI to fix it
Commit your changes once it's working correctly.
11. Add Glassmorphism Card Containers [#11-add-glassmorphism-card-containers]
Create visual depth by adding semi-transparent card containers that "float" over the background.
Copy and paste this prompt:
````markdown
Add a reusable card container class to create visual separation from the background.
**Requirements:**
- Create a `.card` class in `globals.css`
- Apply glassmorphism: semi-transparent white + blur
- Use on all main content areas (landing, forms, dashboard, profile pages)
**Pattern:**
In `globals.css`, add:
```css
.card {
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
border-radius: 1.5rem;
padding: 2rem;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06);
}
```
**Usage:**
Wrap content sections with `
...
`
For public profile pages (/[username]):
Wrap the entire profile (avatar, name, username, and links list) in a single .card container
This creates a Linktree-style floating card effect
Footer/attribution links stay outside the card
Hero section:
Add a soft radial glow behind the content (large blurred white circle, blur-3xl, 50% opacity)
No visible container edges — just organic, fading brightness
Content floats freely over the glow
**Result:**
- Content "lifts" off the background
- Subtle blur creates depth
- Consistent UI across all pages
````
12. Display Clerk Profile Images [#12-display-clerk-profile-images]
If users sign in with Google or another OAuth provider, Clerk stores their profile photo. Let's display it on public profiles!
Copy and paste this prompt:
````markdown
On the public profile page (`/[username]`), display the user's Clerk profile image (Google photo, etc.) instead of the initial letter avatar.
**Pattern:**
```typescript
// Fetch Clerk user to get profile image
const client = await clerkClient();
const clerkUser = await client.users.getUser(user.clerkId);
```
**Display:**
- Use a plain `` tag (not Next.js Image component)
- If `clerkUser.imageUrl` exists, show the image
- Otherwise fallback to the yellow initial avatar
**Keep it simple:**
- No try/catch — let errors bubble up
- No next.config changes needed
- No database schema changes needed
````
Quick Check [#quick-check-9]
Visit your public profile page and verify your profile image (from Google, GitHub, etc.) is displayed instead of the initial letter avatar.
13. Add Icons with Lucide [#13-add-icons-with-lucide]
Small icons can significantly improve UI clarity. Let's add some using Lucide React.
Copy and paste this prompt:
```markdown
Add Lucide React icons to improve the UI.
First install: npm install lucide-react
Add icons to these elements:
- View button: ExternalLink icon
- Delete button: Trash2 icon (replace text with icon)
- Empty links state: Link icon
Import icons from 'lucide-react' and use with size prop (e.g., size={18}).
Keep buttons minimal — only add icons where they improve clarity.
```
Quick Check [#quick-check-10]
Browse through your app and verify the icons appear on:
* The view/external link buttons
* The delete buttons
* The empty state when no links exist
14. Deploy to Vercel [#14-deploy-to-vercel]
Time to ship! Let's deploy your app to Vercel.
Important Steps
Follow these steps carefully to avoid deployment errors.
Step 1: Configure Prisma for Production [#step-1-configure-prisma-for-production]
Add a `postinstall` script to ensure Prisma Client is generated during deployment.
Add this to your `package.json` scripts section:
```json title="package.json"
{
"scripts": {
"postinstall": "prisma generate"
}
}
```
📖 **Reference:** [Deploy to Vercel - Build Configuration](/orm/prisma-client/deployment/serverless/deploy-to-vercel#build-configuration)
Step 2: Clean Up Development Files [#step-2-clean-up-development-files]
Delete the `scripts/` folder if it exists. This folder was auto-generated during initial setup for seed data, you don't need it in production.
Step 3: Deploy to Vercel [#step-3-deploy-to-vercel]
1. Push your code to GitHub (if you haven't already)
2. Go to [vercel.com](https://vercel.com) and import your repository
3. **Important:** Add all your environment variables in Vercel's dashboard:
* `DATABASE_URL`
* `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY`
* `CLERK_SECRET_KEY`
Step 4: Update the App URL [#step-4-update-the-app-url]
After your first deployment:
1. Copy your production URL from Vercel (e.g., `https://your-app.vercel.app`)
2. Add a new environment variable in Vercel:
```text
NEXT_PUBLIC_APP_URL=https://your-app.vercel.app
```
3. Redeploy to apply the change
Don't Forget This Step
If you skip setting `NEXT_PUBLIC_APP_URL`, features like the "Copy Link" button will copy `localhost` URLs instead of your production URL.
Final Check [#final-check]
Test your deployed app thoroughly:
* [ ] Sign up flow works
* [ ] Username claiming works
* [ ] Adding/deleting links works
* [ ] Public profile pages load correctly
* [ ] Copy link copies the correct production URL
* [ ] 404 page displays for non-existent usernames
**Congratulations! Your Linktree clone is live! 🎉**
Resources [#resources]
* [Prisma Documentation](/orm)
* [Next.js Documentation](https://nextjs.org/docs)
* [Clerk Documentation](https://clerk.com/docs)
* [Tailwind CSS Documentation](https://tailwindcss.com/docs)
# Build a Tweet SaaS with Next.js, Prisma Postgres, and Ollama (/docs/ai/tutorials/typefully-clone)
Introduction [#introduction]
In this comprehensive vibe coding tutorial, you'll build **TweetSmith**, a tweet polishing application that transforms your rough draft tweets into engaging, well-formatted content using AI. The twist? Everything runs locally on your machine with no API keys required for the AI.
You'll learn how to leverage AI tools to rapidly develop a full-stack application with:
* **[Next.js](https://nextjs.org/)** — React framework for production
* **[Prisma ORM](https://www.prisma.io/orm)** — Type-safe database access
* **[Prisma Postgres](https://www.prisma.io/postgres)** — Serverless PostgreSQL database
* **[Ollama](https://ollama.com/)** — Run LLMs locally on your machine
* **[UploadThing](https://uploadthing.com/)** — Easy file uploads for tweet images
* **[Lucide React](https://lucide.dev/)** — Beautiful icon library
By the end of this tutorial, you'll have a working application where users can paste draft tweets, transform them with AI, save their favorites, and even attach images, all built with AI-assisted development.
What is Vibe Coding?
Vibe coding is a development approach where you collaborate with AI assistants to build applications. You describe what you want to build, and the AI helps generate the code while you guide the direction and make architectural decisions.
Video tutorial [#video-tutorial]
Watch this step-by-step walkthrough of the entire build process:
Prerequisites [#prerequisites]
Before starting this tutorial, make sure you have:
* [Node.js 20+](https://nodejs.org) installed
* [Ollama](https://ollama.com/) installed on your machine
* An AI coding assistant ([Cursor](https://cursor.com), [Windsurf](https://windsurf.com), [GitHub Copilot](https://github.com/features/copilot), etc.)
* Basic familiarity with React and TypeScript
Recommended AI Models
For best results with vibe coding, we recommend using at least Claude Sonnet 4, Gemini 2.5 Pro, or GPT-4o. These models provide better code generation accuracy and understand complex architectural patterns.
1. Set up your local LLM [#1-set-up-your-local-llm]
Before we write any code, let's set up Ollama so your local AI is ready to transform tweets. This runs entirely on your machine — no API keys, no usage limits, no internet required.
Pull the Model [#pull-the-model]
Open your terminal and download the Gemma 3 model:
```bash
ollama pull gemma3:4b
```
You should see a progress indicator like "pulling manifest…95%". This downloads approximately 3.3GB.
Verify It's Working [#verify-its-working]
Test that the model responds:
```bash
ollama run gemma3:4b
```
Type something and confirm it responds. Press `Ctrl+C` to exit.
You can also verify the API is accessible:
```bash
curl http://localhost:11434/api/tags
```
You should see JSON output showing `gemma3:4b` is installed:
```json
{
"models": [{
"name": "gemma3:4b",
"family": "gemma3",
"parameter_size": "4.3B",
"quantization_level": "Q4_K_M"
}]
}
```
Why Gemma 3 4B?
This model is the sweet spot for local development:
* **4.3B parameters** — Smart enough for tweet formatting
* **Q4\_K\_M quantization** — Memory-efficient (\~3.3GB)
* **Runs great on M-series Macs** with 16GB RAM
* **No API keys or costs** — Completely free and private
Your local LLM is ready! Ollama runs as a background service, so you don't need to keep a terminal open.
2. Create Your Next.js Project [#2-create-your-nextjs-project]
Let's create a fresh Next.js application:
npm
pnpm
yarn
bun
```bash
npx create-next-app@latest tweetsmith
```
```bash
pnpm dlx create-next-app@latest tweetsmith
```
```bash
yarn dlx create-next-app@latest tweetsmith
```
```bash
bunx --bun create-next-app@latest tweetsmith
```
When prompted, select:
* TypeScript: **Yes**
* ESLint: **Yes**
* Tailwind CSS: **Yes**
* `src/` directory: **No**
* App Router: **Yes**
* Turbopack: **Yes** (optional)
* Import alias: **@/**\* (default)
Navigate into your project:
```bash
cd tweetsmith
```
Quick Check [#quick-check]
Start your development server to verify everything works:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
Open [http://localhost:3000](http://localhost:3000) — you should see the default Next.js page.
Good Practice: Commit Early and Often
Throughout this tutorial, we'll commit our changes regularly. This makes it easy to track progress and roll back if something goes wrong.
```bash
git init
git add .
git commit -m "Initial setup: Next.js app"
```
3. Build the TweetSmith UI [#3-build-the-tweetsmith-ui]
Now let's create a minimalist, dark-themed UI inspired by tools like [Typefully](https://typefully.com/). Copy and paste this prompt to your AI assistant:
```markdown
I have a fresh Next.js 15 project with Tailwind CSS already set up.
I need you to create a minimalist single-page UI for a TweetSmith app called "TweetSmith".
**Design requirements:**
- Dark theme only (no light/dark toggle)
- Typefully-inspired aesthetic: sophisticated, clean, minimal
- Color palette:
- Background: #141414 (soft charcoal)
- Card/inputs: #1c1c1c
- Borders: #2a2a2a
- Muted text: #888888
- Foreground/text: #fafafa
- Typography: Geist font (already configured), small refined sizes
- Labels should be uppercase with letter-spacing
**What to create:**
1. Update `app/globals.css` with the dark color palette and CSS variables
2. Update `app/layout.tsx` with proper metadata (title: "TweetSmith") and force the dark background
3. Create `app/components/TweetTransformer.tsx` - a client component with:
- A textarea input for draft tweets
- A character counter (X / 280)
- A "Transform" button (disabled when empty)
- An output section for the result (only visible when there's a result)
- Loading state ready for future API integration
- The handleTransform function should just console.log for now
4. Update `app/page.tsx` with:
- Simple header with app name and tagline
- The TweetTransformer component
- Subtle footer saying "powered by ollama"
Keep it minimal, no extra features, just clean functional UI. Maximum width should be max-w-md for a focused feel.
```
Quick Check [#quick-check-1]
1. Restart your dev server if needed
2. You should see a dark-themed page with a textarea and transform button
3. Type something and verify the character counter updates
4. The button should be disabled when the textarea is empty
Once it looks good, commit your changes:
```bash
git add .
git commit -m "Add TweetSmith UI"
```
4. Connect to Your Local LLM [#4-connect-to-your-local-llm]
Now let's wire up the UI to your local Ollama instance. We'll create a helper file and an API route.
Create the Ollama Helper [#create-the-ollama-helper]
Copy and paste this prompt:
```markdown
Create `app/lib/ollama.ts` - a helper file to communicate with a local Ollama LLM.
Requirements:
- Ollama runs at http://localhost:11434
- Model name: "gemma3:4b"
- Use the /api/generate endpoint
- Create TypeScript types for OllamaRequest and OllamaResponse
- Export a function `generateWithOllama(prompt: string)` that:
- Sends a POST request with the prompt
- Uses stream: false (no streaming, keep it simple)
- Returns the response text as a string
- Throws an error if the request fails
Keep it minimal with clear comments explaining what each part does.
```
Create the Transform API Route [#create-the-transform-api-route]
Copy and paste this prompt:
```markdown
Create `app/api/transform/route.ts` - a Next.js API route that transforms tweets.
Requirements:
- POST endpoint that accepts { draft: string } in the body
- Validate that draft exists and is a string (return 400 if invalid)
- Use the generateWithOllama function from "@/app/lib/ollama"
- Build a prompt that tells the LLM to:
- Act as a tweet formatter
- Make the draft cleaner, more engaging, well-formatted
- Keep it under 280 characters
- Return only the improved tweet, nothing else
- Return { transformed: string } on success
- Return { error: string } with status 500 if Ollama fails
- Add a helpful error message asking if Ollama is running
Use NextRequest and NextResponse from next/server.
```
Connect the Frontend [#connect-the-frontend]
Copy and paste this prompt:
```markdown
Update the TweetTransformer component to call the transform API:
1. Add an "error" state (useState) to handle errors
2. Update handleTransform to:
- Reset error and result states first
- Set loading to true
- Call POST /api/transform with { draft: draftTweet }
- On success: set the transformed tweet from response
- On error: set error message from the catch
- Use finally to always set loading to false
3. Display error message in red below the button when there's an error
Keep the existing UI structure, just wire up the real API call.
```
Quick Check [#quick-check-2]
1. Make sure Ollama is running in the background
2. Type a draft tweet like "just shipped a new feature, its pretty cool i think"
3. Click Transform
4. You should see a polished version appear after a few seconds
If you get an error, check that:
* Ollama is running (`curl http://localhost:11434/api/tags`)
* The model name matches (`gemma3:4b`)
5. Add Temperature for Variety [#5-add-temperature-for-variety]
You might notice the LLM returns the exact same output every time. That's because LLMs are deterministic by default — given the same input, they produce the same output. By adding a "temperature" parameter, we introduce controlled randomness that makes each response slightly different while keeping it coherent.
```markdown
Update the ollama.ts file to add temperature for response variety:
1. Add an optional "options" field to OllamaRequest type with temperature?: number
2. In the request body, add:
options: {
temperature: 0.7
}
```
What is Temperature?
Temperature controls randomness in LLM responses. A value of `0` means deterministic (same output every time), while `1` means maximum creativity. We use `0.7` as the sweet spot — creative enough to give variety, but coherent enough to stay on topic.
Now each transform will give slightly different results!
```bash
git add .
git commit -m "Connect to Ollama LLM for tweet transformation"
```
6. Add Filter Options [#6-add-filter-options]
Right now, every tweet gets the same treatment. But users have different needs — some want short, punchy tweets while others need the full 280 characters. Some love emojis, others prefer a cleaner look.
Let's give users control over the output with filters for character limits and emoji usage. We'll create a collapsible panel with intuitive controls.
First, install Lucide for icons:
npm
pnpm
yarn
bun
```bash
npm install lucide-react
```
```bash
pnpm add lucide-react
```
```bash
yarn add lucide-react
```
```bash
bun add lucide-react
```
Then copy and paste this prompt:
```markdown
Create `app/components/FilterOptions.tsx` with filters for tweet generation.
Requirements:
- Export a `Filters` type with: maxChars (number) and emojiMode ("none" | "few" | "many")
- Export two components:
1. `FilterButton` - a toggle button showing current filter values (e.g., "Filters 280 · few")
2. `FilterPanel` - the expanded controls panel
FilterButton props: isOpen, onToggle, filters
FilterPanel props: filters, onFiltersChange
FilterPanel should include:
- A range slider for maxChars (100-280, step 20)
- Three icon buttons for emoji mode using Lucide icons:
- Ban icon for "none"
- Smile icon for "few"
- SmilePlus icon for "many"
- Display inline with dividers between sections
- Compact design with small buttons (h-7 w-7)
Use SlidersHorizontal and ChevronDown from lucide-react for the button.
Style: dark theme, rounded-lg, border-border, bg-card.
```
7. Add Context Settings [#7-add-context-settings]
Filters control the format, but what about the *voice*? A tech founder tweets differently than a lifestyle blogger. By letting users define their personal context — their tone, style, and audience — the AI can generate tweets that actually sound like them.
We'll add a context panel where users can describe their voice, and this gets saved to localStorage so it persists across sessions.
```markdown
Create `app/components/ContextSettings.tsx` with context management.
Export two components:
1. `ContextButton` - toggle button with User icon from lucide-react
- Props: isOpen, onToggle, hasContext (boolean)
- Show a small dot indicator when context is set
2. `ContextPanel` - just the textarea
- Props: onContextChange
- Load/save to localStorage with key "TweetSmith-context"
Use User and ChevronDown icons from lucide-react.
Keep the textarea at 2 rows, placeholder about style/tone.
```
Integrate the Panels [#integrate-the-panels]
```markdown
Update `app/components/TweetTransformer.tsx` to use the new component structure.
Changes:
1. Import ContextButton, ContextPanel from ContextSettings
2. Import FilterButton, FilterPanel, Filters from FilterOptions
3. Add state for which panel is open: type OpenPanel = "none" | "context" | "filters"
4. Track hasContext state (check localStorage on mount)
Layout structure:
- Settings row: flex container with gap-2 containing both buttons INLINE
- Below the row: conditionally render either ContextPanel or FilterPanel (only one at a time)
- Clicking one panel closes the other
This keeps both buttons always on the same line, with expanded content appearing below.
Default filters: maxChars 280, emojiMode "few"
```
Update the API to Use Filters [#update-the-api-to-use-filters]
```markdown
Update `app/api/transform/route.ts` to use the filter values.
Key changes:
1. Extract filter values directly: maxChars and emojiMode with defaults (280, "few")
2. Build emoji rule as a simple string based on mode
3. Put STRICT LIMITS at the TOP of the prompt (most important):
- "Maximum {maxChars} characters (THIS IS MANDATORY)"
- Emoji rule
- "No hashtags"
4. Add context as "Author style:" if provided
5. Keep GUIDELINES brief: lead with value, sound human, be engaging
6. End with: 'Respond with ONLY the rewritten tweet. No quotes, no explanation.'
Remove any complex buildFilterRules function - inline everything for clarity.
The prompt should be shorter and more direct for better local LLM compliance.
```
Quick Check [#quick-check-3]
1. Open the Filters panel and adjust the character limit
2. Toggle between emoji modes
3. Add some context like "Tech founder, casual tone"
4. Transform a tweet and verify the output respects your settings
```bash
git add .
git commit -m "Add filter options and context settings"
```
8. Create a Tweet Preview Card [#8-create-a-tweet-preview-card]
Plain text output works, but it doesn't feel *real*. When users see their transformed tweet styled like an actual Twitter/X post — complete with profile picture, verified badge, and proper formatting — it becomes much easier to visualize and share.
Let's create a tweet preview card that mimics the real thing, with loading skeletons for a polished feel:
```markdown
Create `app/components/TweetPreview.tsx` - a tweet-like preview card with 3 states.
Props: content (string | null), isLoading (boolean)
Structure:
1. Header with profile image, name, verified badge, and handle
2. Content area (changes based on state)
3. Footer with character count or placeholder
Three states:
1. EMPTY (no content, not loading):
- Show placeholder text styled like a tweet but in text-muted
- Example: "Follow us on X to stay updated on all the latest features and releases from Prisma! 🚀\n\nYour polished tweet will appear here ✨"
- Footer shows "prisma.io"
2. LOADING (isLoading true):
- Show 3 animated skeleton bars with animate-pulse
- Different widths: 90%, 75%, 60%
- Footer skeleton bar
3. CONTENT (has content):
- Show the actual tweet text
- Copy button in header (using Copy/Check icons from lucide-react)
- Footer shows "X / 280 characters"
Use Image from next/image for the profile picture.
Add verified badge as inline SVG (Twitter blue checkmark).
```
Add a Logo [#add-a-logo]
Add a logo image (like `icon-logo.png`) to your `public/` folder, then:
```markdown
Update `app/page.tsx` to use a logo image instead of text for the header.
Changes:
1. Import Image from "next/image"
2. Replace the h1 text with an Image component:
- src="/icon-logo.png" (or your logo file)
- width={80} height={80}
- Add className="mb-3" for spacing
3. Keep the tagline text below: "polish your tweets with AI"
4. Use flex flex-col items-center on the header
The header should now show: Logo image centered, tagline below.
```
```bash
git add .
git commit -m "Add tweet preview card and logo"
```
9. Add Prisma Postgres [#9-add-prisma-postgres]
Now let's add a database to save favorite tweets! We'll use Prisma ORM with Prisma Postgres.
Install Dependencies [#install-dependencies]
npm
pnpm
yarn
bun
```bash
npm install prisma tsx --save-dev
npm install @prisma/adapter-pg @prisma/client dotenv
```
```bash
pnpm add prisma tsx --save-dev
pnpm add @prisma/adapter-pg @prisma/client dotenv
```
```bash
yarn add prisma tsx --dev
yarn add @prisma/adapter-pg @prisma/client dotenv
```
```bash
bun add prisma tsx --dev
bun add @prisma/adapter-pg @prisma/client dotenv
```
Initialize Prisma with a Cloud Database [#initialize-prisma-with-a-cloud-database]
User Action Required
The following command is **interactive** and requires your input. Run it in your terminal and follow the prompts.
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output ../app/generated/prisma
```
```bash
pnpm dlx prisma init --db --output ../app/generated/prisma
```
```bash
yarn dlx prisma init --db --output ../app/generated/prisma
```
```bash
bunx --bun prisma init --db --output ../app/generated/prisma
```
This command will:
1. Authenticate you with Prisma Console (if needed)
2. Ask you to choose a **region** (pick one close to you)
3. Ask for a **project name** (e.g., "TweetSmith")
4. Create a cloud Prisma Postgres database
5. Generate `prisma/schema.prisma`, `prisma.config.ts`, and `.env` with your `DATABASE_URL`
Important: Check Your DATABASE_URL
Ensure your `.env` file uses a standard PostgreSQL URL format:
```bash
DATABASE_URL="postgres://..."
```
If it shows `prisma+postgres://...`, get the TCP connection string from the [Prisma Console](https://console.prisma.io).
Update the Schema [#update-the-schema]
Replace the contents of `prisma/schema.prisma` with:
```prisma
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model SavedTweet {
id String @id @default(cuid())
original String // The draft tweet input
transformed String // The polished/transformed tweet
context String? // Optional user context/style used
imageUrl String? // Optional image URL
imageAlt String? // Optional alt text for accessibility
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
Create the Prisma Client [#create-the-prisma-client]
Create `lib/prisma.ts`:
```typescript
import { PrismaClient } from "../app/generated/prisma/client"
import { PrismaPg } from "@prisma/adapter-pg"
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
})
const globalForPrisma = global as unknown as { prisma: PrismaClient }
const prisma = globalForPrisma.prisma || new PrismaClient({
adapter,
})
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma
export default prisma
```
Add Database Scripts [#add-database-scripts]
Update your `package.json` scripts:
```json
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint",
"db:test": "tsx scripts/test-database.ts",
"db:studio": "prisma studio"
}
}
```
Create a Test Script [#create-a-test-script]
Create `scripts/test-database.ts`:
```typescript
import "dotenv/config"
import prisma from "../lib/prisma"
async function testDatabase() {
console.log("🔍 Testing Prisma Postgres connection...\n")
try {
console.log("✅ Connected to database!")
console.log("\n📝 Creating a test saved tweet...")
const newTweet = await prisma.savedTweet.create({
data: {
original: "just shipped a new feature, its pretty cool i think",
transformed: "Just shipped a new feature! 🚀 Pretty excited about this one ✨",
context: "Tech founder, casual tone",
},
})
console.log("✅ Created saved tweet:", newTweet)
console.log("\n📋 Fetching all saved tweets...")
const allTweets = await prisma.savedTweet.findMany()
console.log(`✅ Found ${allTweets.length} saved tweet(s)`)
console.log("\n🎉 All tests passed! Your database is working perfectly.\n")
} catch (error) {
console.error("❌ Error:", error)
process.exit(1)
}
}
testDatabase()
```
Push Schema and Test [#push-schema-and-test]
npm
pnpm
yarn
bun
```bash
npx prisma db push
npx prisma generate
npm run db:test
```
```bash
pnpm dlx prisma db push
pnpm dlx prisma generate
pnpm run db:test
```
```bash
yarn dlx prisma db push
yarn dlx prisma generate
yarn db:test
```
```bash
bunx --bun prisma db push
bun x prisma generate
bun run db:test
```
You should see success messages. Open Prisma Studio to view your data:
npm
pnpm
yarn
bun
```bash
npm run db:studio
```
```bash
pnpm run db:studio
```
```bash
yarn db:studio
```
```bash
bun run db:studio
```
Create the Tweets API [#create-the-tweets-api]
Copy and paste this prompt:
```markdown
Create `app/api/tweets/route.ts` with GET, POST, and DELETE handlers.
Requirements:
- GET: Fetch all saved tweets ordered by createdAt desc
- POST: Save a new tweet with { original, transformed, context?, imageUrl?, imageAlt? }
- DELETE: Delete a tweet by id (passed as query param ?id=xxx)
Use try-catch blocks and return appropriate error responses.
Import prisma from "../../../lib/prisma"
```
Quick Check [#quick-check-4]
Test the API with curl:
```bash
# Save a tweet
curl -X POST http://localhost:3000/api/tweets \
-H "Content-Type: application/json" \
-d '{"original":"test draft","transformed":"Test polished! ✨"}'
# Get all tweets
curl http://localhost:3000/api/tweets
```
```bash
git add .
git commit -m "Add Prisma Postgres database"
```
10. Add Save Functionality [#10-add-save-functionality]
Now that we have a database, let's put it to use! Users often want to save their best transformed tweets for later — maybe they're not ready to post yet, or they want to build a collection of polished content.
We'll add a save button to the tweet preview card with satisfying visual feedback:
```markdown
Add a Save button to save transformed tweets to the database.
Requirements:
- Add a Save button next to the Copy button in TweetPreview
- Use POST /api/tweets with { original, transformed, context }
- Pass original (draft) and context from TweetTransformer to TweetPreview
UX States:
- Default: Bookmark icon with hover scale effect
- Saving: Spinning Loader2 icon + "Saving" text
- Saved: Green tinted background (emerald-500/10), checkmark icon with zoom animation
Important: The "Saved" state must persist until a NEW tweet is generated. Use useRef to track previous content and useEffect to reset saved state only when content changes. Do not use setTimeout to reset the saved state.
Match the minimal dark aesthetic of the app (200ms ease-out transitions, subtle hover states).
```
11. Build the Tweet Library [#11-build-the-tweet-library]
Saving tweets is great, but users need a way to access them! Let's build a slide-in library panel where users can browse their saved tweets, copy them for posting, or even load them back as drafts to iterate further.
This is where the app starts feeling like a real product — a complete workflow from draft to polish to save to reuse:
```markdown
Add a Library feature to browse and reuse saved tweets.
Components to create:
- LibraryButton.tsx - Fixed top-right button with count badge
- LibraryPanel.tsx - Slide-in panel from right (360px, backdrop blur)
- SavedTweetCard.tsx - Tweet cards that look like published tweets
LibraryButton:
- Fixed position top-right (fixed top-6 right-6)
- Shows saved tweets count as badge
- Toggles panel open/close
LibraryPanel:
- Slides in from right with 300ms ease-out animation
- Backdrop overlay with blur
- Header with title, count, and close button
- Scrollable list of SavedTweetCard components
- Empty state with icon when no tweets saved
- Fetches tweets from GET /api/tweets when opened
SavedTweetCard:
- Looks like a real published tweet (profile image, name, verified badge, handle, date)
- Shows transformed tweet content only (not original)
- Footer: character count on left, Copy/Delete icons on right (subtle, brighten on hover)
- Click anywhere on card → loads transformed text into Draft textarea and closes panel
- Delete shows inline confirmation (Cancel/Delete buttons), not a modal
Integration:
- Add library state to TweetTransformer (isOpen, count)
- Fetch count on mount and after saving
- Pass onUseAsDraft callback to set draft and clear transformed tweet
- Refresh count when panel closes (in case tweets were deleted)
Styling: Match minimal dark aesthetic - subtle borders, muted colors, smooth 200ms transitions.
```
Quick Check [#quick-check-5]
1. Save a few transformed tweets
2. Click the Library button in the top-right
3. Verify your saved tweets appear in the panel
4. Click a tweet to load it back into the draft
5. Delete a tweet and verify it disappears
```bash
git add .
git commit -m "Add tweet library with save/browse/delete"
```
12. Add Theme Switcher [#12-add-theme-switcher]
Dark mode is standard, but why stop there? Let's add personality with multiple dark themes. Users can pick a vibe that matches their style — from purple twilight to warm desert tones to classic newspaper grey.
This is a small touch that makes the app feel more personal and polished:
```markdown
Add a theme system to my app with 3 dark themes and a minimal theme switcher.
THEMES:
1. "Disco" - Purple/violet twilight vibes
- Background: #17171c (deep blue-black)
- Accent: #a78bfa (soft violet)
2. "Dust" - Desert warmth, amber tones
- Background: #1a1816 (warm charcoal)
- Accent: #d4a574 (warm amber/sand)
3. "Press" - Old newspaper, pure greys
- Background: #262626 (true grey)
- Accent: #a3a3a3 (neutral grey)
IMPLEMENTATION:
- Use CSS custom properties (:root and [data-theme="..."]) for all colors
- Add a subtle radial gradient glow at the top of the page using the accent color
- Create a ThemeSwitcher component with small colored dots (one per theme)
- Place the switcher in the footer for minimal UI impact
- Persist theme choice in localStorage
- Add smooth transitions when switching themes (0.3s ease)
- Prevent transition flash on page load with a "no-transitions" class
UX REQUIREMENTS:
- Each dot shows the accent color of that theme
- Selected theme has a subtle ring + slight scale up
- Unselected themes are dimmed (opacity 40%) and brighten on hover
- Theme changes should animate smoothly across all UI elements
```
13. Add Smooth Animated Panels [#13-add-smooth-animated-panels]
You might have noticed that the filter and context panels appear/disappear abruptly. Good UX demands smooth transitions — they make the interface feel more responsive and polished.
We'll use the CSS Grid height animation trick to create buttery smooth expand/collapse animations without the layout jumps that plague traditional height transitions:
```markdown
Add smooth animated collapsible panels that expand/collapse without layout jumps.
ANIMATED PANEL COMPONENT:
Create a reusable AnimatedPanel component using the CSS Grid trick for height animation:
- Use display: grid with gridTemplateRows
- Closed state: gridTemplateRows: "0fr" (collapses to 0 height)
- Open state: gridTemplateRows: "1fr" (expands to content height)
- Wrap children in a div with overflow: hidden
- Add opacity fade: 0 when closed, 1 when open
- Transition: "grid-template-rows 0.25s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.2s ease"
COLLAPSE GAP TRICK:
If parent uses gap/space between items, add negative margin when closed to collapse the gap:
- marginTop: isOpen ? undefined : "-12px" (adjust based on your gap size)
- Animate the margin too for smooth effect
PREVENT SCROLLBAR LAYOUT SHIFT:
Add to your global CSS on html element:
- scrollbar-gutter: stable (reserves space for scrollbar)
- overflow-x: hidden (prevents horizontal scroll)
This creates buttery smooth expand/collapse without the jarring height jump or scrollbar layout shift.
```
```bash
git add .
git commit -m "Add themes and smooth animations"
```
14. Add Image Uploads [#14-add-image-uploads]
Tweets with images get significantly more engagement. Let's give users the ability to attach images to their polished tweets. We'll use UploadThing for simple, reliable file uploads with a smart pattern: preview locally first, only upload when saving.
This prevents orphaned files if users change their mind before saving:
Install UploadThing [#install-uploadthing]
npm
pnpm
yarn
bun
```bash
npm install uploadthing @uploadthing/react
```
```bash
pnpm add uploadthing @uploadthing/react
```
```bash
yarn add uploadthing @uploadthing/react
```
```bash
bun add uploadthing @uploadthing/react
```
Get Your API Token [#get-your-api-token]
1. Go to [uploadthing.com](https://uploadthing.com) and create an account
2. Create a new app in the dashboard
3. Copy your `UPLOADTHING_TOKEN` and add it to your `.env`:
```bash
UPLOADTHING_TOKEN=your_token_here
```
Implement Image Upload [#implement-image-upload]
```markdown
Add image upload to tweets using UploadThing.
Requirements:
1. Users should be able to attach ONE image to their tweet
2. The image should only be uploaded to UploadThing when clicking "Save" (not when selecting the image)
3. While editing, show a local preview using URL.createObjectURL() - this avoids orphaned uploads if the user changes their mind
4. Show upload progress in the Save button ("Uploading..." → "Saving...")
5. Allow removing the selected image before saving (X button on the image preview)
6. Display saved images in the tweet library/cards
Implementation steps:
1. Create UploadThing FileRouter at app/api/uploadthing/core.ts with a "tweetImage" route (4MB max, 1 file)
2. Create the route handler at app/api/uploadthing/route.ts
3. Create typed utilities at app/lib/uploadthing.ts with useUploadThing hook
4. Update TweetPreview component:
- Add file state (File object) and preview URL state
- Add hidden file input + "Add image" label/button
- Show image preview with remove button
- In handleSave: if file exists, call startUpload() first, then save tweet with the returned URL
5. Update SavedTweetCard to display imageUrl if present
The schema already has imageUrl and imageAlt fields.
Key pattern: Store File locally → preview with createObjectURL → upload only on save → save URL to database
```
Quick Check [#quick-check-6]
1. Transform a tweet
2. Click "Add image" and select a photo
3. Verify the preview appears with an X button to remove
4. Click Save and watch the button states: "Uploading..." → "Saving..." → "Saved!"
5. Open the Library and verify the image appears with the saved tweet
```bash
git add .
git commit -m "Add image upload with UploadThing"
```
Summary [#summary]
You've built a complete tweet polishing application with:
* ✅ Local AI with Ollama (no API keys!)
* ✅ Customizable filters and context
* ✅ Beautiful dark themes
* ✅ Cloud database with Prisma Postgres
* ✅ Image uploads with UploadThing
* ✅ Smooth animations and polished UX
What's Next? [#whats-next]
Here are some ideas to extend your app:
* Add user authentication with [Clerk](https://clerk.com)
* Add multiple LLM model options
* Implement tweet scheduling
* Add analytics to track transformations
* Create shareable public links
Resources [#resources]
* [Prisma Documentation](/orm)
* [Next.js Documentation](https://nextjs.org/docs)
* [Ollama Documentation](https://ollama.com/library)
* [UploadThing Documentation](https://docs.uploadthing.com)
* [Tailwind CSS Documentation](https://tailwindcss.com/docs)
* [Lucide Icons](https://lucide.dev/icons)
# apikey (/docs/cli/console/apikey)
The `prisma platform apikey` command manages connection strings for Prisma Console environments.
Usage [#usage]
```bash
prisma platform apikey [action] [options] --early-access
```
Actions [#actions]
| Action | Description |
| -------- | ------------------------------ |
| `show` | List all connection strings |
| `create` | Create a new connection string |
| `delete` | Delete a connection string |
Options [#options]
| Option | Description |
| --------------------- | ---------------------------------------------------------------------- |
| `-h`, `--help` | Display help message |
| `-e`, `--environment` | The environment ID (required for `show` and `create` commands) |
| `-a`, `--apikey` | The connection string ID (required for `delete` command) |
| `-n`, `--name` | Display name for the connection string (optional for `create` command) |
Examples [#examples]
List connection strings [#list-connection-strings]
npm
pnpm
yarn
bun
```bash
npx prisma platform apikey show --environment $ENVIRONMENT_ID --early-access
```
```bash
pnpm dlx prisma platform apikey show --environment $ENVIRONMENT_ID --early-access
```
```bash
yarn dlx prisma platform apikey show --environment $ENVIRONMENT_ID --early-access
```
```bash
bunx --bun prisma platform apikey show --environment $ENVIRONMENT_ID --early-access
```
Create a connection string [#create-a-connection-string]
npm
pnpm
yarn
bun
```bash
npx prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
```bash
pnpm dlx prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
```bash
yarn dlx prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
```bash
bunx --bun prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
Delete a connection string [#delete-a-connection-string]
npm
pnpm
yarn
bun
```bash
npx prisma platform apikey delete --apikey $API_KEY_ID --early-access
```
```bash
pnpm dlx prisma platform apikey delete --apikey $API_KEY_ID --early-access
```
```bash
yarn dlx prisma platform apikey delete --apikey $API_KEY_ID --early-access
```
```bash
bunx --bun prisma platform apikey delete --apikey $API_KEY_ID --early-access
```
# auth (/docs/cli/console/auth)
The `prisma platform auth` command manages authentication with Prisma Console.
Usage [#usage]
```bash
prisma platform auth [action] [options] --early-access
```
Actions [#actions]
| Action | Description |
| -------- | ------------------------------- |
| `login` | Log in to Console |
| `show` | Display authenticated user info |
| `logout` | Log out of Console |
Options [#options]
| Option | Description |
| -------------- | -------------------- |
| `-h`, `--help` | Display help message |
Examples [#examples]
Log in to Console [#log-in-to-console]
npm
pnpm
yarn
bun
```bash
npx prisma platform auth login --early-access
```
```bash
pnpm dlx prisma platform auth login --early-access
```
```bash
yarn dlx prisma platform auth login --early-access
```
```bash
bunx --bun prisma platform auth login --early-access
```
Display authenticated user [#display-authenticated-user]
npm
pnpm
yarn
bun
```bash
npx prisma platform auth show --early-access
```
```bash
pnpm dlx prisma platform auth show --early-access
```
```bash
yarn dlx prisma platform auth show --early-access
```
```bash
bunx --bun prisma platform auth show --early-access
```
Log out [#log-out]
npm
pnpm
yarn
bun
```bash
npx prisma platform auth logout --early-access
```
```bash
pnpm dlx prisma platform auth logout --early-access
```
```bash
yarn dlx prisma platform auth logout --early-access
```
```bash
bunx --bun prisma platform auth logout --early-access
```
# environment (/docs/cli/console/environment)
The `prisma platform environment` command manages environments within Prisma Console projects.
Usage [#usage]
```bash
prisma platform environment [action] [options] --early-access
```
Actions [#actions]
| Action | Description |
| -------- | ------------------------ |
| `show` | List all environments |
| `create` | Create a new environment |
| `delete` | Delete an environment |
Options [#options]
| Option | Description |
| --------------------- | ---------------------------------------------------------------- |
| `-h`, `--help` | Display help message |
| `-p`, `--project` | The project ID (required for `show` and `create` commands) |
| `-e`, `--environment` | The environment ID (required for `delete` command) |
| `-n`, `--name` | Display name for the environment (optional for `create` command) |
Examples [#examples]
List environments [#list-environments]
npm
pnpm
yarn
bun
```bash
npx prisma platform environment show --project $PROJECT_ID --early-access
```
```bash
pnpm dlx prisma platform environment show --project $PROJECT_ID --early-access
```
```bash
yarn dlx prisma platform environment show --project $PROJECT_ID --early-access
```
```bash
bunx --bun prisma platform environment show --project $PROJECT_ID --early-access
```
Create an environment [#create-an-environment]
npm
pnpm
yarn
bun
```bash
npx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
pnpm dlx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
yarn dlx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
bunx --bun prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
Delete an environment [#delete-an-environment]
npm
pnpm
yarn
bun
```bash
npx prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
```bash
pnpm dlx prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
```bash
yarn dlx prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
```bash
bunx --bun prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
# platform (/docs/cli/console)
The `prisma platform` command group provides tools to manage Prisma Console workspaces, projects, environments, and connection strings.
Legacy GraphQL API
These commands currently rely on a deprecated GraphQL API. They are being modernized to use the [Management API](/management-api) with improved authentication. Until the migration is complete, these commands remain in early access.
Usage [#usage]
```bash
prisma platform [command] [options] --early-access
```
Global options [#global-options]
| Option | Description |
| ---------------- | ---------------------------------------------------------------- |
| `-h`, `--help` | Display help message |
| `--early-access` | Enable early access Console features (required for all commands) |
Subcommands [#subcommands]
| Command | Description |
| --------------------------------------------------------- | ----------------------------- |
| [`prisma platform auth`](/cli/console/auth) | Manage Console authentication |
| [`prisma platform workspace`](/cli/console/workspace) | Manage workspaces |
| [`prisma platform project`](/cli/console/project) | Manage projects |
| [`prisma platform environment`](/cli/console/environment) | Manage environments |
| [`prisma platform apikey`](/cli/console/apikey) | Manage connection strings |
Examples [#examples]
```bash
# Authenticate with Console
prisma platform auth login --early-access
# List workspaces
prisma platform workspace show --early-access
# Create a project
prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
# Create an environment
prisma platform environment create --project $PROJECT_ID --name "production" --early-access
# Create a connection string
prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
See also [#see-also]
* [Console overview](/console)
* [Getting started with Console](/console/getting-started)
* [Management API](/management-api)
# platform (/docs/cli/console/platform)
The `prisma platform` command provides access to Prisma Console functionality for managing workspaces, projects, environments, and connection strings.
Usage [#usage]
```bash
prisma platform [subcommand] [options] --early-access
```
Subcommands [#subcommands]
| Subcommand | Description |
| ------------- | ----------------------------- |
| `auth` | Manage Console authentication |
| `workspace` | Manage workspaces |
| `project` | Manage projects |
| `environment` | Manage environments |
| `apikey` | Manage connection strings |
Examples [#examples]
Authenticate with Console [#authenticate-with-console]
Log in to your Console account (opens a browser window for GitHub authentication):
npm
pnpm
yarn
bun
```bash
npx prisma platform auth login --early-access
```
```bash
pnpm dlx prisma platform auth login --early-access
```
```bash
yarn dlx prisma platform auth login --early-access
```
```bash
bunx --bun prisma platform auth login --early-access
```
Display information about the currently authenticated user:
npm
pnpm
yarn
bun
```bash
npx prisma platform auth show --early-access
```
```bash
pnpm dlx prisma platform auth show --early-access
```
```bash
yarn dlx prisma platform auth show --early-access
```
```bash
bunx --bun prisma platform auth show --early-access
```
Log out of your Console account:
npm
pnpm
yarn
bun
```bash
npx prisma platform auth logout --early-access
```
```bash
pnpm dlx prisma platform auth logout --early-access
```
```bash
yarn dlx prisma platform auth logout --early-access
```
```bash
bunx --bun prisma platform auth logout --early-access
```
Manage workspaces [#manage-workspaces]
List all workspaces available to your account:
npm
pnpm
yarn
bun
```bash
npx prisma platform workspace show --early-access
```
```bash
pnpm dlx prisma platform workspace show --early-access
```
```bash
yarn dlx prisma platform workspace show --early-access
```
```bash
bunx --bun prisma platform workspace show --early-access
```
Manage projects [#manage-projects]
List all projects within a workspace:
npm
pnpm
yarn
bun
```bash
npx prisma platform project show --workspace $WORKSPACE_ID --early-access
```
```bash
pnpm dlx prisma platform project show --workspace $WORKSPACE_ID --early-access
```
```bash
yarn dlx prisma platform project show --workspace $WORKSPACE_ID --early-access
```
```bash
bunx --bun prisma platform project show --workspace $WORKSPACE_ID --early-access
```
Create a new project within a workspace:
npm
pnpm
yarn
bun
```bash
npx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
pnpm dlx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
yarn dlx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
bunx --bun prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
Delete a project:
npm
pnpm
yarn
bun
```bash
npx prisma platform project delete --project $PROJECT_ID --early-access
```
```bash
pnpm dlx prisma platform project delete --project $PROJECT_ID --early-access
```
```bash
yarn dlx prisma platform project delete --project $PROJECT_ID --early-access
```
```bash
bunx --bun prisma platform project delete --project $PROJECT_ID --early-access
```
Manage environments [#manage-environments]
List all environments within a project:
npm
pnpm
yarn
bun
```bash
npx prisma platform environment show --project $PROJECT_ID --early-access
```
```bash
pnpm dlx prisma platform environment show --project $PROJECT_ID --early-access
```
```bash
yarn dlx prisma platform environment show --project $PROJECT_ID --early-access
```
```bash
bunx --bun prisma platform environment show --project $PROJECT_ID --early-access
```
Create a new environment within a project:
npm
pnpm
yarn
bun
```bash
npx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
pnpm dlx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
yarn dlx prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
```bash
bunx --bun prisma platform environment create --project $PROJECT_ID --name "production" --early-access
```
Delete an environment:
npm
pnpm
yarn
bun
```bash
npx prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
```bash
pnpm dlx prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
```bash
yarn dlx prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
```bash
bunx --bun prisma platform environment delete --environment $ENVIRONMENT_ID --early-access
```
Manage connection strings [#manage-connection-strings]
List all connection strings for an environment:
npm
pnpm
yarn
bun
```bash
npx prisma platform apikey show --environment $ENVIRONMENT_ID --early-access
```
```bash
pnpm dlx prisma platform apikey show --environment $ENVIRONMENT_ID --early-access
```
```bash
yarn dlx prisma platform apikey show --environment $ENVIRONMENT_ID --early-access
```
```bash
bunx --bun prisma platform apikey show --environment $ENVIRONMENT_ID --early-access
```
Create a new connection string for an environment:
npm
pnpm
yarn
bun
```bash
npx prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
```bash
pnpm dlx prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
```bash
yarn dlx prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
```bash
bunx --bun prisma platform apikey create --environment $ENVIRONMENT_ID --name "production-key" --early-access
```
Delete a connection string:
npm
pnpm
yarn
bun
```bash
npx prisma platform apikey delete --apikey $API_KEY_ID --early-access
```
```bash
pnpm dlx prisma platform apikey delete --apikey $API_KEY_ID --early-access
```
```bash
yarn dlx prisma platform apikey delete --apikey $API_KEY_ID --early-access
```
```bash
bunx --bun prisma platform apikey delete --apikey $API_KEY_ID --early-access
```
Options [#options]
Authentication commands [#authentication-commands]
| Option | Description |
| -------------- | -------------------- |
| `-h`, `--help` | Display help message |
Workspace commands [#workspace-commands]
| Option | Description |
| -------------- | -------------------- |
| `-h`, `--help` | Display help message |
Project commands [#project-commands]
| Option | Description |
| ------------------- | ------------------------------------------------------------ |
| `-h`, `--help` | Display help message |
| `-w`, `--workspace` | The workspace ID (required for `show` and `create` commands) |
| `-p`, `--project` | The project ID (required for `delete` command) |
| `-n`, `--name` | Display name for the project (optional for `create` command) |
Environment commands [#environment-commands]
| Option | Description |
| --------------------- | ---------------------------------------------------------------- |
| `-h`, `--help` | Display help message |
| `-p`, `--project` | The project ID (required for `show` and `create` commands) |
| `-e`, `--environment` | The environment ID (required for `delete` command) |
| `-n`, `--name` | Display name for the environment (optional for `create` command) |
Connection string commands [#connection-string-commands]
| Option | Description |
| --------------------- | ---------------------------------------------------------------------- |
| `-h`, `--help` | Display help message |
| `-e`, `--environment` | The environment ID (required for `show` and `create` commands) |
| `-a`, `--apikey` | The connection string ID (required for `delete` command) |
| `-n`, `--name` | Display name for the connection string (optional for `create` command) |
Global options [#global-options]
| Option | Description |
| ---------------- | ---------------------------------------------------------------- |
| `--early-access` | Enable early access Console features (required for all commands) |
# project (/docs/cli/console/project)
The `prisma platform project` command manages projects within Prisma Console workspaces.
Usage [#usage]
```bash
prisma platform project [action] [options] --early-access
```
Actions [#actions]
| Action | Description |
| -------- | -------------------- |
| `show` | List all projects |
| `create` | Create a new project |
| `delete` | Delete a project |
Options [#options]
| Option | Description |
| ------------------- | ------------------------------------------------------------ |
| `-h`, `--help` | Display help message |
| `-w`, `--workspace` | The workspace ID (required for `show` and `create` commands) |
| `-p`, `--project` | The project ID (required for `delete` command) |
| `-n`, `--name` | Display name for the project (optional for `create` command) |
Examples [#examples]
List projects [#list-projects]
npm
pnpm
yarn
bun
```bash
npx prisma platform project show --workspace $WORKSPACE_ID --early-access
```
```bash
pnpm dlx prisma platform project show --workspace $WORKSPACE_ID --early-access
```
```bash
yarn dlx prisma platform project show --workspace $WORKSPACE_ID --early-access
```
```bash
bunx --bun prisma platform project show --workspace $WORKSPACE_ID --early-access
```
Create a project [#create-a-project]
npm
pnpm
yarn
bun
```bash
npx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
pnpm dlx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
yarn dlx prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
```bash
bunx --bun prisma platform project create --workspace $WORKSPACE_ID --name "My Project" --early-access
```
Delete a project [#delete-a-project]
npm
pnpm
yarn
bun
```bash
npx prisma platform project delete --project $PROJECT_ID --early-access
```
```bash
pnpm dlx prisma platform project delete --project $PROJECT_ID --early-access
```
```bash
yarn dlx prisma platform project delete --project $PROJECT_ID --early-access
```
```bash
bunx --bun prisma platform project delete --project $PROJECT_ID --early-access
```
# workspace (/docs/cli/console/workspace)
The `prisma platform workspace` command manages workspaces in Prisma Console.
Usage [#usage]
```bash
prisma platform workspace [action] [options] --early-access
```
Actions [#actions]
| Action | Description |
| ------ | ------------------- |
| `show` | List all workspaces |
Options [#options]
| Option | Description |
| -------------- | -------------------- |
| `-h`, `--help` | Display help message |
Examples [#examples]
List workspaces [#list-workspaces]
npm
pnpm
yarn
bun
```bash
npx prisma platform workspace show --early-access
```
```bash
pnpm dlx prisma platform workspace show --early-access
```
```bash
yarn dlx prisma platform workspace show --early-access
```
```bash
bunx --bun prisma platform workspace show --early-access
```
# execute (/docs/cli/db/execute)
The `prisma db execute` command applies a SQL script to the database without interacting with the Prisma migrations table.
This command is currently not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb).
Usage [#usage]
```bash
prisma db execute [options]
```
The datasource URL configuration is read from the Prisma config file (e.g., `prisma.config.ts`).
The script input must be provided using either `--file` or `--stdin`. The whole script is sent as a single command to the database.
The output is connector-specific and reports success or failure only—it's not meant for returning data.
Prerequisites [#prerequisites]
Configure your database connection in `prisma.config.ts`:
```prisma file=schema.prisma
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "sqlite"
}
```
```typescript file=prisma.config.ts
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Options [#options]
| Option | Description |
| -------------- | ----------------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--file` | Path to a file containing the script to execute |
Flags [#flags]
| Flag | Description |
| --------- | ---------------------------------------------------- |
| `--stdin` | Use terminal standard input as the script to execute |
Either `--file` or `--stdin` is required.
**Prisma v7 breaking change**: The `--schema` and `--url` options have been removed. Configure your database connection in `prisma.config.ts` instead.
Examples [#examples]
Execute a SQL file [#execute-a-sql-file]
npm
pnpm
yarn
bun
```bash
npx prisma db execute --file ./script.sql
```
```bash
pnpm dlx prisma db execute --file ./script.sql
```
```bash
yarn dlx prisma db execute --file ./script.sql
```
```bash
bunx --bun prisma db execute --file ./script.sql
```
Execute SQL from stdin [#execute-sql-from-stdin]
```bash
echo 'TRUNCATE TABLE dev;' | prisma db execute --stdin
```
See also [#see-also]
* [Migration troubleshooting in production](/orm/prisma-migrate/workflows/patching-and-hotfixing#fixing-failed-migrations-with-migrate-diff-and-db-execute)
# db (/docs/cli/db)
The `prisma db` command group provides tools to manage your database schema and lifecycle during development.
Usage [#usage]
```bash
prisma db [command] [options]
```
Global options [#global-options]
| Option | Description |
| -------------- | -------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
Subcommands [#subcommands]
| Command | Description |
| -------------------------------------- | ------------------------------------------------------------------------- |
| [`prisma db pull`](/cli/db/pull) | Pull the state from the database to the Prisma schema using introspection |
| [`prisma db push`](/cli/db/push) | Push the state from Prisma schema to the database during prototyping |
| [`prisma db seed`](/cli/db/seed) | Seed your database |
| [`prisma db execute`](/cli/db/execute) | Execute native commands to your database |
Examples [#examples]
```bash
# Pull schema from database
prisma db pull
# Push schema to database
prisma db push
# Seed the database
prisma db seed
# Execute a SQL script
prisma db execute --file ./script.sql
```
# pull (/docs/cli/db/pull)
The `prisma db pull` command connects to your database and adds Prisma models to your Prisma schema that reflect the current database schema.
Usage [#usage]
```bash
prisma db pull [options]
```
The datasource URL configuration is read from the Prisma config file (e.g., `prisma.config.ts`).
This command will overwrite the current `schema.prisma` file with the new schema. Back up your current schema or commit to version control before running `db pull` if it contains important modifications.
Introspection with `db pull` on the [MongoDB connector](/orm/core-concepts/supported-databases/mongodb) samples the data instead of reading a schema.
Prerequisites [#prerequisites]
Configure your database connection in `prisma.config.ts`:
```prisma file=schema.prisma
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "sqlite"
}
```
```typescript file=prisma.config.ts
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Flags [#flags]
| Flag | Description |
| -------------- | ---------------------------------------------- |
| `-h`, `--help` | Display help message |
| `--force` | Ignore current Prisma schema file |
| `--print` | Print the introspected Prisma schema to stdout |
Options [#options]
| Option | Description |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
| `--url` | Override the datasource URL from the Prisma config file |
| `--composite-type-depth` | Depth for introspecting composite types (e.g., MongoDB Embedded Documents). Default `-1` for infinite depth, `0` to disable |
| `--schemas` | Specify database schemas to introspect (overrides datasource block) |
| `--local-d1` | Generate a Prisma schema from a local Cloudflare D1 database |
Examples [#examples]
Introspect the database [#introspect-the-database]
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
Output:
```text
Introspecting based on datasource defined in schema.prisma …
✔ Introspected 2 models and wrote them into schema.prisma in 38ms
Run prisma generate to generate Prisma Client.
```
Specify a schema path [#specify-a-schema-path]
npm
pnpm
yarn
bun
```bash
npx prisma db pull --schema=./alternative/schema.prisma
```
```bash
pnpm dlx prisma db pull --schema=./alternative/schema.prisma
```
```bash
yarn dlx prisma db pull --schema=./alternative/schema.prisma
```
```bash
bunx --bun prisma db pull --schema=./alternative/schema.prisma
```
Print to stdout instead of writing to file [#print-to-stdout-instead-of-writing-to-file]
npm
pnpm
yarn
bun
```bash
npx prisma db pull --print
```
```bash
pnpm dlx prisma db pull --print
```
```bash
yarn dlx prisma db pull --print
```
```bash
bunx --bun prisma db pull --print
```
Force overwrite existing schema [#force-overwrite-existing-schema]
Ignore any customizations in the current schema:
npm
pnpm
yarn
bun
```bash
npx prisma db pull --force
```
```bash
pnpm dlx prisma db pull --force
```
```bash
yarn dlx prisma db pull --force
```
```bash
bunx --bun prisma db pull --force
```
Set composite type depth for MongoDB [#set-composite-type-depth-for-mongodb]
npm
pnpm
yarn
bun
```bash
npx prisma db pull --composite-type-depth=2
```
```bash
pnpm dlx prisma db pull --composite-type-depth=2
```
```bash
yarn dlx prisma db pull --composite-type-depth=2
```
```bash
bunx --bun prisma db pull --composite-type-depth=2
```
# push (/docs/cli/db/push)
The `prisma db push` command pushes the state of your Prisma schema to the database without using migrations. It creates the database if it does not exist.
This command is a good choice when you don't need to version schema changes, such as during prototyping and local development.
Usage [#usage]
```bash
prisma db push [options]
```
The datasource URL configuration is read from the Prisma config file (e.g., `prisma.config.ts`).
Prerequisites [#prerequisites]
Configure your database connection in `prisma.config.ts`:
```prisma file=schema.prisma
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "sqlite"
}
```
```typescript file=prisma.config.ts
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Options [#options]
| Option | Description |
| -------------------- | ------------------------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
| `--url` | Override the datasource URL from the Prisma config file |
| `--accept-data-loss` | Ignore data loss warnings |
| `--force-reset` | Force a reset of the database before push |
In Prisma v7, `db push` no longer runs `prisma generate` automatically. Run it explicitly if needed.
Examples [#examples]
Push the schema to the database [#push-the-schema-to-the-database]
npm
pnpm
yarn
bun
```bash
npx prisma db push
```
```bash
pnpm dlx prisma db push
```
```bash
yarn dlx prisma db push
```
```bash
bunx --bun prisma db push
```
Accept data loss [#accept-data-loss]
Proceed even if the changes might result in data loss:
npm
pnpm
yarn
bun
```bash
npx prisma db push --accept-data-loss
```
```bash
pnpm dlx prisma db push --accept-data-loss
```
```bash
yarn dlx prisma db push --accept-data-loss
```
```bash
bunx --bun prisma db push --accept-data-loss
```
Specify a schema path [#specify-a-schema-path]
npm
pnpm
yarn
bun
```bash
npx prisma db push --schema=/tmp/schema.prisma
```
```bash
pnpm dlx prisma db push --schema=/tmp/schema.prisma
```
```bash
yarn dlx prisma db push --schema=/tmp/schema.prisma
```
```bash
bunx --bun prisma db push --schema=/tmp/schema.prisma
```
Force reset before push [#force-reset-before-push]
Reset the database before applying changes:
npm
pnpm
yarn
bun
```bash
npx prisma db push --force-reset
```
```bash
pnpm dlx prisma db push --force-reset
```
```bash
yarn dlx prisma db push --force-reset
```
```bash
bunx --bun prisma db push --force-reset
```
See also [#see-also]
* [Conceptual overview of `db push` and when to use it over Prisma Migrate](/orm/prisma-migrate/workflows/prototyping-your-schema)
* [Schema prototyping with `db push`](/orm/prisma-migrate/workflows/prototyping-your-schema)
# seed (/docs/cli/db/seed)
The `prisma db seed` command seeds your database with initial data.
Usage [#usage]
```bash
prisma db seed [options]
```
Options [#options]
| Option | Description |
| -------------- | -------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--` | Pass custom arguments to the seed file |
The `--` delimiter allows you to pass custom arguments to your seed script (available in version 4.15.0+).
Examples [#examples]
Run the seed script [#run-the-seed-script]
npm
pnpm
yarn
bun
```bash
npx prisma db seed
```
```bash
pnpm dlx prisma db seed
```
```bash
yarn dlx prisma db seed
```
```bash
bunx --bun prisma db seed
```
Pass custom arguments [#pass-custom-arguments]
npm
pnpm
yarn
bun
```bash
npx prisma db seed -- --arg1 value1 --arg2 value2
```
```bash
pnpm dlx prisma db seed -- --arg1 value1 --arg2 value2
```
```bash
yarn dlx prisma db seed -- --arg1 value1 --arg2 value2
```
```bash
bunx --bun prisma db seed -- --arg1 value1 --arg2 value2
```
See also [#see-also]
* [Seeding your database](/orm/prisma-migrate/workflows/seeding)
# dev (/docs/cli/dev)
The `prisma dev` command starts a [local Prisma Postgres](/postgres/database/local-development) database that you can run Prisma ORM commands against. It's useful for development and testing and allows easy migration to [Prisma Postgres](/postgres) in production.
Usage [#usage]
```bash
prisma dev [options]
```
Options [#options]
| Option | Description | Default |
| ------------------ | --------------------------------------------------------- | --------- |
| `-n`, `--name` | Name of the server (helps isolate state between projects) | `default` |
| `-p`, `--port` | Main port number the Prisma Dev server will listen on | `51213` |
| `-P`, `--db-port` | Port number the database server will listen on | `51214` |
| `--shadow-db-port` | Port number the shadow database server will listen on | `51215` |
| `-d`, `--detach` | Run the server in the background | `false` |
| `--debug` | Enable debug logging | `false` |
Subcommands [#subcommands]
| Command | Description |
| ------------------------------------ | --------------------------------- |
| [`prisma dev ls`](/cli/dev/ls) | List available servers |
| [`prisma dev rm`](/cli/dev/rm) | Remove servers |
| [`prisma dev start`](/cli/dev/start) | Start one or more stopped servers |
| [`prisma dev stop`](/cli/dev/stop) | Stop servers |
Examples [#examples]
Start a local Prisma Postgres server [#start-a-local-prisma-postgres-server]
npm
pnpm
yarn
bun
```bash
npx prisma dev
```
```bash
pnpm dlx prisma dev
```
```bash
yarn dlx prisma dev
```
```bash
bunx --bun prisma dev
```
Output:
```text
✔ Great Success!
Your prisma dev server default is ready and listening on ports 63567-63569.
╭──────────────────────────────────╮
│[q]uit [h]ttp url [t]cp urls │
╰──────────────────────────────────╯
```
Start with a specific name [#start-with-a-specific-name]
Create a named instance for project isolation:
npm
pnpm
yarn
bun
```bash
npx prisma dev --name="mydbname"
```
```bash
pnpm dlx prisma dev --name="mydbname"
```
```bash
yarn dlx prisma dev --name="mydbname"
```
```bash
bunx --bun prisma dev --name="mydbname"
```
Run in detached mode [#run-in-detached-mode]
Run the server in the background:
npm
pnpm
yarn
bun
```bash
npx prisma dev --detach
```
```bash
pnpm dlx prisma dev --detach
```
```bash
yarn dlx prisma dev --detach
```
```bash
bunx --bun prisma dev --detach
```
This frees up your terminal. Use `prisma dev ls` to see running servers and `prisma dev stop` to stop them.
Specify custom ports [#specify-custom-ports]
npm
pnpm
yarn
bun
```bash
npx prisma dev --port 5000 --db-port 5001 --shadow-db-port 5002
```
```bash
pnpm dlx prisma dev --port 5000 --db-port 5001 --shadow-db-port 5002
```
```bash
yarn dlx prisma dev --port 5000 --db-port 5001 --shadow-db-port 5002
```
```bash
bunx --bun prisma dev --port 5000 --db-port 5001 --shadow-db-port 5002
```
# ls (/docs/cli/dev/ls)
The `prisma dev ls` command lists all available [local Prisma Postgres](/postgres/database/local-development) instances on your system.
Usage [#usage]
```bash
prisma dev ls [options]
```
Options [#options]
| Option | Description | Default |
| --------- | -------------------- | ------- |
| `--debug` | Enable debug logging | `false` |
Examples [#examples]
List all servers [#list-all-servers]
npm
pnpm
yarn
bun
```bash
npx prisma dev ls
```
```bash
pnpm dlx prisma dev ls
```
```bash
yarn dlx prisma dev ls
```
```bash
bunx --bun prisma dev ls
```
This shows all instances on your system with their current status and configuration.
# rm (/docs/cli/dev/rm)
The `prisma dev rm` command removes the data of one or more [local Prisma Postgres](/postgres/database/local-development) databases from your file system.
Usage [#usage]
```bash
prisma dev rm [options]
```
Arguments [#arguments]
| Argument | Description |
| -------- | ----------------------------------------------------- |
| `` | Name(s) or glob pattern(s) of the server(s) to remove |
Options [#options]
| Option | Description | Default |
| --------- | --------------------------------------------- | ------- |
| `--debug` | Enable debug logging | `false` |
| `--force` | Stop any running servers before removing them | `false` |
Without `--force`, the command fails if any server is running.
Examples [#examples]
Remove a specific database [#remove-a-specific-database]
npm
pnpm
yarn
bun
```bash
npx prisma dev rm mydb
```
```bash
pnpm dlx prisma dev rm mydb
```
```bash
yarn dlx prisma dev rm mydb
```
```bash
bunx --bun prisma dev rm mydb
```
Remove multiple databases with a pattern [#remove-multiple-databases-with-a-pattern]
Remove all databases starting with `mydb`:
npm
pnpm
yarn
bun
```bash
npx prisma dev rm mydb*
```
```bash
pnpm dlx prisma dev rm mydb*
```
```bash
yarn dlx prisma dev rm mydb*
```
```bash
bunx --bun prisma dev rm mydb*
```
Force remove a running database [#force-remove-a-running-database]
Stop and remove a database in one command:
npm
pnpm
yarn
bun
```bash
npx prisma dev rm --force mydb
```
```bash
pnpm dlx prisma dev rm --force mydb
```
```bash
yarn dlx prisma dev rm --force mydb
```
```bash
bunx --bun prisma dev rm --force mydb
```
The `rm` command is interactive and includes safety prompts to prevent accidental data loss.
# start (/docs/cli/dev/start)
The `prisma dev start` command starts existing [local Prisma Postgres](/postgres/database/local-development) instances in the background.
Usage [#usage]
```bash
prisma dev start [options]
```
Arguments [#arguments]
| Argument | Description |
| -------- | ---------------------------------------------------- |
| `` | Name(s) or glob pattern(s) of the server(s) to start |
Options [#options]
| Option | Description | Default |
| --------- | -------------------- | ------- |
| `--debug` | Enable debug logging | `false` |
This command only works with instances that already exist. Use `prisma dev` to create a new instance.
Examples [#examples]
Start a specific database [#start-a-specific-database]
npm
pnpm
yarn
bun
```bash
npx prisma dev start mydb
```
```bash
pnpm dlx prisma dev start mydb
```
```bash
yarn dlx prisma dev start mydb
```
```bash
bunx --bun prisma dev start mydb
```
Start multiple databases with a pattern [#start-multiple-databases-with-a-pattern]
Start all databases starting with `mydb`:
npm
pnpm
yarn
bun
```bash
npx prisma dev start mydb*
```
```bash
pnpm dlx prisma dev start mydb*
```
```bash
yarn dlx prisma dev start mydb*
```
```bash
bunx --bun prisma dev start mydb*
```
# stop (/docs/cli/dev/stop)
The `prisma dev stop` command stops one or more [local Prisma Postgres](/postgres/database/local-development) databases.
Usage [#usage]
```bash
prisma dev stop [options]
```
Arguments [#arguments]
| Argument | Description |
| -------- | --------------------------------------------------- |
| `` | Name(s) or glob pattern(s) of the server(s) to stop |
Options [#options]
| Option | Description | Default |
| --------- | -------------------- | ------- |
| `--debug` | Enable debug logging | `false` |
Examples [#examples]
Stop a specific database [#stop-a-specific-database]
npm
pnpm
yarn
bun
```bash
npx prisma dev stop mydb
```
```bash
pnpm dlx prisma dev stop mydb
```
```bash
yarn dlx prisma dev stop mydb
```
```bash
bunx --bun prisma dev stop mydb
```
Stop multiple databases with a pattern [#stop-multiple-databases-with-a-pattern]
Stop all databases starting with `mydb`:
npm
pnpm
yarn
bun
```bash
npx prisma dev stop mydb*
```
```bash
pnpm dlx prisma dev stop mydb*
```
```bash
yarn dlx prisma dev stop mydb*
```
```bash
bunx --bun prisma dev stop mydb*
```
The `stop` command is interactive and includes safety prompts to prevent accidental operations.
# deploy (/docs/cli/migrate/deploy)
The `prisma migrate deploy` command applies all pending migrations and creates the database if it doesn't exist. Primarily used in non-development environments.
This command is not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb). Use [`db push`](/cli/db/push) instead.
Usage [#usage]
```bash
prisma migrate deploy [options]
```
The datasource URL configuration is read from the Prisma config file (e.g., `prisma.config.ts`).
Characteristics [#characteristics]
* Does **not** look for drift in the database or changes in the Prisma schema
* Does **not** reset the database or generate artifacts
* Does **not** rely on a shadow database
Options [#options]
| Option | Description |
| -------------- | -------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
Examples [#examples]
Deploy pending migrations [#deploy-pending-migrations]
npm
pnpm
yarn
bun
```bash
npx prisma migrate deploy
```
```bash
pnpm dlx prisma migrate deploy
```
```bash
yarn dlx prisma migrate deploy
```
```bash
bunx --bun prisma migrate deploy
```
Specify a schema path [#specify-a-schema-path]
npm
pnpm
yarn
bun
```bash
npx prisma migrate deploy --schema=./alternative/schema.prisma
```
```bash
pnpm dlx prisma migrate deploy --schema=./alternative/schema.prisma
```
```bash
yarn dlx prisma migrate deploy --schema=./alternative/schema.prisma
```
```bash
bunx --bun prisma migrate deploy --schema=./alternative/schema.prisma
```
# dev (/docs/cli/migrate/dev)
The `prisma migrate dev` command creates and applies migrations during development. It requires a [shadow database](/orm/prisma-migrate/understanding-prisma-migrate/shadow-database).
**For use in development environments only.**
This command is not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb). Use [`db push`](/cli/db/push) instead.
Usage [#usage]
```bash
prisma migrate dev [options]
```
The datasource URL configuration is read from the Prisma config file (e.g., `prisma.config.ts`).
How it works [#how-it-works]
1. Reruns the existing migration history in the shadow database to detect schema drift
2. Applies pending migrations to the shadow database
3. Generates a new migration from any changes you made to the Prisma schema
4. Applies all unapplied migrations to the development database and updates the `_prisma_migrations` table
**Prisma v7**: `migrate dev` no longer automatically triggers `prisma generate` or seed scripts. Run them explicitly if needed.
Options [#options]
| Option | Description |
| --------------- | ------------------------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
| `--url` | Override the datasource URL from the Prisma config file |
| `-n`, `--name` | Name the migration |
| `--create-only` | Create a new migration but do not apply it |
If a [schema drift](/orm/prisma-migrate/understanding-prisma-migrate/shadow-database#detecting-schema-drift) is detected while running with `--create-only`, you will be prompted to reset your database.
Examples [#examples]
Create and apply migrations [#create-and-apply-migrations]
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev
```
```bash
pnpm dlx prisma migrate dev
```
```bash
yarn dlx prisma migrate dev
```
```bash
bunx --bun prisma migrate dev
```
Name the migration [#name-the-migration]
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name added_job_title
```
```bash
pnpm dlx prisma migrate dev --name added_job_title
```
```bash
yarn dlx prisma migrate dev --name added_job_title
```
```bash
bunx --bun prisma migrate dev --name added_job_title
```
Create migration without applying [#create-migration-without-applying]
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --create-only
```
```bash
pnpm dlx prisma migrate dev --create-only
```
```bash
yarn dlx prisma migrate dev --create-only
```
```bash
bunx --bun prisma migrate dev --create-only
```
This creates the migration file but doesn't apply it. Run `prisma migrate dev` again to apply.
Specify a schema path [#specify-a-schema-path]
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --schema=./alternative/schema.prisma
```
```bash
pnpm dlx prisma migrate dev --schema=./alternative/schema.prisma
```
```bash
yarn dlx prisma migrate dev --schema=./alternative/schema.prisma
```
```bash
bunx --bun prisma migrate dev --schema=./alternative/schema.prisma
```
See also [#see-also]
* [Conceptual overview of Prisma Migrate](/orm/prisma-migrate)
* [Developing with Prisma Migrate](/orm/prisma-migrate)
# diff (/docs/cli/migrate/diff)
The `prisma migrate diff` command compares two database schema sources and outputs a description of the migration needed to transform the first into the second.
This command is only partially supported for [MongoDB](/orm/core-concepts/supported-databases/mongodb). See options below for details.
Usage [#usage]
```bash
prisma migrate diff --from-... --to-...
```
The output can be a human-readable summary (default) or an executable script.
The `migrate diff` command can only compare database features [supported by Prisma](/orm/reference/database-features). Differences in unsupported features (views, triggers, etc.) won't be shown.
Prerequisites [#prerequisites]
If using `--from-config-datasource` or `--to-config-datasource`, configure your database connection in `prisma.config.ts`:
```prisma file=schema.prisma
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "sqlite"
}
```
```typescript file=prisma.config.ts
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Source types [#source-types]
Both sources must use the same database provider.
From options (one required) [#from-options-one-required]
| Option | Description | Notes |
| -------------------------- | ---------------------------------------- | ------------------------ |
| `--from-empty` | Assume the source is an empty data model | |
| `--from-schema` | Path to a Prisma schema file | |
| `--from-migrations` | Path to Prisma migrations directory | Not supported in MongoDB |
| `--from-config-datasource` | Use datasource from Prisma config file | Prisma v7+ |
To options (one required) [#to-options-one-required]
| Option | Description | Notes |
| ------------------------ | --------------------------------------------- | ------------------------ |
| `--to-empty` | Assume the destination is an empty data model | |
| `--to-schema` | Path to a Prisma schema file | |
| `--to-migrations` | Path to Prisma migrations directory | Not supported in MongoDB |
| `--to-config-datasource` | Use datasource from Prisma config file | Prisma v7+ |
Other options [#other-options]
| Option | Description | Notes |
| ---------------- | -------------------------------------------------------- | --------------------------- |
| `--config` | Custom path to your Prisma config file | |
| `--script` | Output a SQL script instead of human-readable summary | Not supported in MongoDB |
| `-o`, `--output` | Write to a file instead of stdout | Available since 5.12.1 |
| `--exit-code` | Change exit code behavior: Empty=0, Error=1, Not empty=2 | Default: Success=0, Error=1 |
| `--help` | Display help message | |
**Prisma v7 breaking change**: The `--from-url`, `--to-url`, `--from-schema-datasource`, `--to-schema-datasource`, and `--shadow-database-url` options have been removed. Use `--from-config-datasource` and `--to-config-datasource` instead.
Examples [#examples]
Compare database to schema [#compare-database-to-schema]
Roll forward after a migration failed:
npm
pnpm
yarn
bun
```bash
npx prisma migrate diff \
--from-config-datasource \
--to-schema=next_datamodel.prisma \
--script
```
```bash
pnpm dlx prisma migrate diff \
--from-config-datasource \
--to-schema=next_datamodel.prisma \
--script
```
```bash
yarn dlx prisma migrate diff \
--from-config-datasource \
--to-schema=next_datamodel.prisma \
--script
```
```bash
bunx --bun prisma migrate diff \
--from-config-datasource \
--to-schema=next_datamodel.prisma \
--script
```
Compare schema to database [#compare-schema-to-database]
npm
pnpm
yarn
bun
```bash
npx prisma migrate diff \
--from-schema=schema.prisma \
--to-config-datasource \
--script
```
```bash
pnpm dlx prisma migrate diff \
--from-schema=schema.prisma \
--to-config-datasource \
--script
```
```bash
yarn dlx prisma migrate diff \
--from-schema=schema.prisma \
--to-config-datasource \
--script
```
```bash
bunx --bun prisma migrate diff \
--from-schema=schema.prisma \
--to-config-datasource \
--script
```
Compare migrations to database [#compare-migrations-to-database]
Generate a migration for a hotfix already applied on production:
npm
pnpm
yarn
bun
```bash
npx prisma migrate diff \
--from-migrations ./migrations \
--to-config-datasource \
--script
```
```bash
pnpm dlx prisma migrate diff \
--from-migrations ./migrations \
--to-config-datasource \
--script
```
```bash
yarn dlx prisma migrate diff \
--from-migrations ./migrations \
--to-config-datasource \
--script
```
```bash
bunx --bun prisma migrate diff \
--from-migrations ./migrations \
--to-config-datasource \
--script
```
Pipe output to db execute [#pipe-output-to-db-execute]
npm
pnpm
yarn
bun
```bash
npx prisma migrate diff \
--from-config-datasource \
--to-schema=schema.prisma \
--script | prisma db execute --stdin
```
```bash
pnpm dlx prisma migrate diff \
--from-config-datasource \
--to-schema=schema.prisma \
--script | prisma db execute --stdin
```
```bash
yarn dlx prisma migrate diff \
--from-config-datasource \
--to-schema=schema.prisma \
--script | prisma db execute --stdin
```
```bash
bunx --bun prisma migrate diff \
--from-config-datasource \
--to-schema=schema.prisma \
--script | prisma db execute --stdin
```
Check if sources are in sync [#check-if-sources-are-in-sync]
Exits with code 2 if changes are detected:
npm
pnpm
yarn
bun
```bash
npx prisma migrate diff \
--exit-code \
--from-config-datasource \
--to-schema=schema.prisma
```
```bash
pnpm dlx prisma migrate diff \
--exit-code \
--from-config-datasource \
--to-schema=schema.prisma
```
```bash
yarn dlx prisma migrate diff \
--exit-code \
--from-config-datasource \
--to-schema=schema.prisma
```
```bash
bunx --bun prisma migrate diff \
--exit-code \
--from-config-datasource \
--to-schema=schema.prisma
```
See also [#see-also]
* [Migration troubleshooting in production](/orm/prisma-migrate/workflows/patching-and-hotfixing#fixing-failed-migrations-with-migrate-diff-and-db-execute)
# migrate (/docs/cli/migrate)
The `prisma migrate` command group provides tools to create and apply database migrations.
Prisma Migrate does not apply to MongoDB. Use [`db push`](/cli/db/push) instead.
Usage [#usage]
```bash
prisma migrate [command] [options]
```
Global options [#global-options]
| Option | Description |
| -------------- | -------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
Development commands [#development-commands]
| Command | Description |
| -------------------------------------------- | ------------------------------------------------------------------------ |
| [`prisma migrate dev`](/cli/migrate/dev) | Create a migration from schema changes, apply it, and trigger generators |
| [`prisma migrate reset`](/cli/migrate/reset) | Reset your database and apply all migrations (all data will be lost) |
Production/staging commands [#productionstaging-commands]
| Command | Description |
| ------------------------------------------------ | ---------------------------------------------------------------------------- |
| [`prisma migrate deploy`](/cli/migrate/deploy) | Apply pending migrations to the database |
| [`prisma migrate status`](/cli/migrate/status) | Check the status of your database migrations |
| [`prisma migrate resolve`](/cli/migrate/resolve) | Resolve issues with database migrations (baseline, failed migration, hotfix) |
Commands for any stage [#commands-for-any-stage]
| Command | Description |
| ------------------------------------------ | ------------------------------------------------------ |
| [`prisma migrate diff`](/cli/migrate/diff) | Compare the database schema from two arbitrary sources |
Examples [#examples]
```bash
# Create and apply a migration in development
prisma migrate dev
# Reset the database (development only)
prisma migrate reset
# Apply pending migrations in production
prisma migrate deploy
# Check migration status
prisma migrate status
# Compare database schemas
prisma migrate diff \
--from-config-datasource \
--to-schema=./prisma/schema.prisma \
--script
```
See also [#see-also]
* [Conceptual overview of Prisma Migrate](/orm/prisma-migrate)
* [Developing with Prisma Migrate](/orm/prisma-migrate)
# reset (/docs/cli/migrate/reset)
The `prisma migrate reset` command resets your database and re-applies all migrations.
**For use in development environments only.**
This command is not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb). Use [`db push`](/cli/db/push) instead.
Usage [#usage]
```bash
prisma migrate reset [options]
```
The datasource URL configuration is read from the Prisma config file (e.g., `prisma.config.ts`).
How it works [#how-it-works]
1. Drops the database/schema if possible, or performs a soft reset if the environment doesn't allow it
2. Creates a new database/schema with the same name
3. Applies all migrations
4. Runs seed scripts
Options [#options]
| Option | Description |
| --------------- | -------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
| `-f`, `--force` | Skip the confirmation prompt |
Examples [#examples]
Reset the database [#reset-the-database]
npm
pnpm
yarn
bun
```bash
npx prisma migrate reset
```
```bash
pnpm dlx prisma migrate reset
```
```bash
yarn dlx prisma migrate reset
```
```bash
bunx --bun prisma migrate reset
```
Skip confirmation prompt [#skip-confirmation-prompt]
npm
pnpm
yarn
bun
```bash
npx prisma migrate reset --force
```
```bash
pnpm dlx prisma migrate reset --force
```
```bash
yarn dlx prisma migrate reset --force
```
```bash
bunx --bun prisma migrate reset --force
```
Specify a schema path [#specify-a-schema-path]
npm
pnpm
yarn
bun
```bash
npx prisma migrate reset --schema=./alternative/schema.prisma
```
```bash
pnpm dlx prisma migrate reset --schema=./alternative/schema.prisma
```
```bash
yarn dlx prisma migrate reset --schema=./alternative/schema.prisma
```
```bash
bunx --bun prisma migrate reset --schema=./alternative/schema.prisma
```
AI safety guardrails [#ai-safety-guardrails]
Prisma ORM includes built-in safety checks to prevent accidental destructive commands when run through AI coding assistants.
When AI agents like Claude Code, Cursor, Gemini CLI, or others attempt `prisma migrate reset --force`, Prisma blocks execution and shows a protective error message.
To proceed, you must provide explicit consent. The AI agent will:
1. Explain what action it's attempting
2. Warn that this action irreversibly destroys all data
3. Confirm whether this is a development or production database
4. Ask for your explicit consent before proceeding
After consent, the AI sets the `PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION` environment variable and reruns the command.
# resolve (/docs/cli/migrate/resolve)
The `prisma migrate resolve` command allows you to solve migration history issues in production by marking a failed migration as already applied (supports baselining) or rolled back.
This command is not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb). Use [`db push`](/cli/db/push) instead.
Usage [#usage]
```bash
prisma migrate resolve [options]
```
The datasource URL configuration is read from the Prisma config file (e.g., `prisma.config.ts`).
This command can only be used with a failed migration. Using it with a successful migration results in an error.
Use cases [#use-cases]
* Recover from failed migrations
* Baseline databases when starting to use Prisma Migrate on existing databases
* Reconcile hotfixes done manually on databases with your migration history
Run `prisma migrate status` to identify if you need to use `resolve`.
Options [#options]
| Option | Description |
| --------------- | ------------------------------------------ |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
| `--applied` | Record a specific migration as applied |
| `--rolled-back` | Record a specific migration as rolled back |
You must specify either `--applied` or `--rolled-back`.
Examples [#examples]
Mark a migration as applied [#mark-a-migration-as-applied]
npm
pnpm
yarn
bun
```bash
npx prisma migrate resolve --applied 20201231000000_add_users_table
```
```bash
pnpm dlx prisma migrate resolve --applied 20201231000000_add_users_table
```
```bash
yarn dlx prisma migrate resolve --applied 20201231000000_add_users_table
```
```bash
bunx --bun prisma migrate resolve --applied 20201231000000_add_users_table
```
Mark a migration as rolled back [#mark-a-migration-as-rolled-back]
npm
pnpm
yarn
bun
```bash
npx prisma migrate resolve --rolled-back 20201231000000_add_users_table
```
```bash
pnpm dlx prisma migrate resolve --rolled-back 20201231000000_add_users_table
```
```bash
yarn dlx prisma migrate resolve --rolled-back 20201231000000_add_users_table
```
```bash
bunx --bun prisma migrate resolve --rolled-back 20201231000000_add_users_table
```
Specify a schema path [#specify-a-schema-path]
npm
pnpm
yarn
bun
```bash
npx prisma migrate resolve --rolled-back 20201231000000_add_users_table --schema=./schema.prisma
```
```bash
pnpm dlx prisma migrate resolve --rolled-back 20201231000000_add_users_table --schema=./schema.prisma
```
```bash
yarn dlx prisma migrate resolve --rolled-back 20201231000000_add_users_table --schema=./schema.prisma
```
```bash
bunx --bun prisma migrate resolve --rolled-back 20201231000000_add_users_table --schema=./schema.prisma
```
See also [#see-also]
* [Resolving migration history issues](https://pris.ly/d/migrate-resolve)
# status (/docs/cli/migrate/status)
The `prisma migrate status` command checks the migrations in `./prisma/migrations/*` and the entries in the `_prisma_migrations` table to report the state of your migrations.
This command is not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb). Use [`db push`](/cli/db/push) instead.
Usage [#usage]
```bash
prisma migrate status [options]
```
The datasource URL configuration is read from the Prisma config file (e.g., `prisma.config.ts`).
Options [#options]
| Option | Description |
| -------------- | -------------------------------------- |
| `-h`, `--help` | Display help message |
| `--config` | Custom path to your Prisma config file |
| `--schema` | Custom path to your Prisma schema |
Exit codes [#exit-codes]
In versions 4.3.0 and later, `prisma migrate status` exits with code 1 when:
* A database connection error occurs
* Migration files haven't been applied to the database
* Migration history has diverged from the database state
* No migration table is found
* Failed migrations are found
Example output [#example-output]
```text
Status
3 migrations found in prisma/migrations
Your local migration history and the migrations table from your database are different:
The last common migration is: 20201127134938_new_migration
The migration have not yet been applied:
20201208100950_test_migration
The migrations from the database are not found locally in prisma/migrations:
20201208100950_new_migration
```
Examples [#examples]
Check migration status [#check-migration-status]
npm
pnpm
yarn
bun
```bash
npx prisma migrate status
```
```bash
pnpm dlx prisma migrate status
```
```bash
yarn dlx prisma migrate status
```
```bash
bunx --bun prisma migrate status
```
Specify a schema path [#specify-a-schema-path]
npm
pnpm
yarn
bun
```bash
npx prisma migrate status --schema=./alternative/schema.prisma
```
```bash
pnpm dlx prisma migrate status --schema=./alternative/schema.prisma
```
```bash
yarn dlx prisma migrate status --schema=./alternative/schema.prisma
```
```bash
bunx --bun prisma migrate status --schema=./alternative/schema.prisma
```
# Database Metrics (/docs/console/features/metrics)
You can have a single workspace that hosts several databases. Within each database, you can view detailed reports on how your database is performing, with various metrics like:
* Average response size
* Average query duration
* Total egress
* Total operations
* Cache utilization
Databases [#databases]
For Prisma Postgres projects, the **Database** tab in the project view lets you configure and manage your databases. This interface provides tools to monitor and maintain your database resources. The **Connections** section displays a table with the following columns:
| Column Name | Description |
| ------------- | -------------------------------------------------------------------------------- |
| **Hint** | Provides the URL structure for the database in use. |
| **Static IP** | Indicates whether static IP is enabled for the database and associated products. |
| **Products** | Lists the products that are enabled using the database URL. |
| **Action** | Allows you to disable all active products and remove the connection. |
# Feature Maturity (/docs/console/more/feature-maturity)
Prisma releases updates to Console multiple times per week, as opposed to the Prisma ORM that we release on a set schedule every few weeks. This is why we consider the lifecycle and process for maturing features in Console differently.
You can [check out the releases and maturity process for the Prisma ORM](/orm/more/releases) for further details.
You can find information about releases across *all* Prisma tools and products in the [changelog](https://www.prisma.io/changelog).
Early Access [#early-access]
If a feature on the Console is labeled as **Early Access**:
* We have validated a problem and are considering a solution to it but are not certain whether that solution is complete or a perfect fit.
* We want to gather more feedback and adjust the solution as necessary, knowing that users are prepared for significant breaking changes.
* We reserve ourselves the right to throttle or remove access to a feature in Early Access to preserve the stability of the platform, or enforce its use to stay within the scope defined in our [Terms of Service](https://pris.ly/terms).
As always, your feedback in our [Discord](https://pris.ly/discord?utm_source=docs\&utm_medium=inline_text) is invaluable to shape the design of the features. This will help us ensure that they can solve your problems in the best way possible.
Preview [#preview]
If a feature on the Console is labeled as **Preview**:
* We have refined the software based on the valuable feedback we obtained during the Early Access phase.
* We developed the feature further, bringing it closer to the final version, though it's not completely ready for production usage.
* We have lifted the invite gate, so users no longer need an invitation to access the feature. Users just need to sign up to gain access.
* We have increased the stability of the software compared to the Early Access phase. While there might still be some issues, they should be less frequent and less critical.
* We use the Preview phase as a final stress test to ensure the product is ready for heavy production workloads.
We recommend testing the product in a staging environment and welcome any feedback in our [Discord](https://pris.ly/discord?utm_source=docs\&utm_medium=inline_text). This will assist us in improving the product for its final release.
# Support (/docs/console/more/support)
Your feedback is invaluable, and we encourage you to share your experiences with us on [Discord](https://pris.ly/discord?utm_source=docs\&utm_medium=intro_text).
Support [#support]
Your support options are based on your workspace's active plan. For more details, take a look at our [pricing page](https://www.prisma.io/pricing).
Community support [#community-support]
Reach out to us in our [Discord](https://pris.ly/discord?utm_source=docs\&utm_medium=inline_text).
Standard support [#standard-support]
* Email support, [support@prisma.io](mailto\:support@prisma.io), or reach out via the Console
* 2 business days, Mon-Fri, 9am-5pm CET
Premium support [#premium-support]
* Email support, [support@prisma.io](mailto\:support@prisma.io), or reach out via the Console
* 1 business hour, Mon-Fri, 9am-5pm CET
Dedicated support [#dedicated-support]
Dedicated contact person.
Deleting your PDP account [#deleting-your-pdp-account]
If you want to delete your PDP account, **email us at [support@prisma.io](mailto\:support@prisma.io)** specifying the email id or GitHub handle with which you signed up.
To ensure that you're not accidentally disabling any infrastructure powering one of your applications, we require that you **disable Accelerate in *all* environments of *all* your projects** that live in the account to be deleted.
Additionally there should be no active subscriptions in the account to be deleted. Please cancel any active subscriptions before requesting account deletion.
# Expand-and-contract migrations (/docs/guides/database/data-migration)
Introduction [#introduction]
When making changes to your database schema in production, it's crucial to ensure data consistency and avoid downtime. This guide shows you how to use the expand and contract pattern to safely migrate data between columns. We'll walk through a practical example of replacing a boolean field with an enum field while preserving existing data.
Prerequisites [#prerequisites]
Before starting this guide, make sure you have:
* Node.js installed (version 20 or higher)
* A Prisma ORM project with an existing schema
* A supported database (PostgreSQL, MySQL, SQLite, SQL Server, etc.)
* Access to both development and production databases
* Basic understanding of Git branching
* Basic familiarity with TypeScript
1. Set up your environment [#1-set-up-your-environment]
1.1. Review initial schema [#11-review-initial-schema]
Start with a basic schema containing a Post model:
```prisma
generator client {
provider = "prisma-client"
output = "./generated/prisma"
}
datasource db {
provider = "postgresql"
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
}
```
1.2. Configure Prisma [#12-configure-prisma]
Create a `prisma.config.ts` file in the root of your project with the following content:
```typescript title="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"),
},
});
```
You'll need to install the required packages. If you haven't already, install them using your package manager:
npm
pnpm
yarn
bun
```bash
npm install prisma @types/pg --save-dev
```
```bash
pnpm add prisma @types/pg --save-dev
```
```bash
yarn add prisma @types/pg --dev
```
```bash
bun add prisma @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg pg dotenv
```
```bash
pnpm add @prisma/client @prisma/adapter-pg pg dotenv
```
```bash
yarn add @prisma/client @prisma/adapter-pg pg dotenv
```
```bash
bun add @prisma/client @prisma/adapter-pg pg dotenv
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
1.3. Create a development branch [#13-create-a-development-branch]
Create a new branch for your changes:
```bash
git checkout -b create-status-field
```
2. Expand the schema [#2-expand-the-schema]
2.1. Add new column [#21-add-new-column]
Update your schema to add the new Status enum and field:
```prisma
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean? @default(false)
status Status @default(Unknown)
}
enum Status {
Unknown
Draft
InProgress
InReview
Published
}
```
2.2. Create migration [#22-create-migration]
Generate the migration:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name add-status-column
```
```bash
pnpm dlx prisma migrate dev --name add-status-column
```
```bash
yarn dlx prisma migrate dev --name add-status-column
```
```bash
bunx --bun prisma migrate dev --name add-status-column
```
Then generate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
3. Migrate the data [#3-migrate-the-data]
3.1. Create migration script [#31-create-migration-script]
Create a new TypeScript file for the data migration:
```typescript
import { PrismaClient } from "../generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
import "dotenv/config";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
const prisma = new PrismaClient({
adapter,
});
async function main() {
await prisma.$transaction(async (tx) => {
const posts = await tx.post.findMany();
for (const post of posts) {
await tx.post.update({
where: { id: post.id },
data: {
status: post.published ? "Published" : "Unknown",
},
});
}
});
}
main()
.catch(async (e) => {
console.error(e);
process.exit(1);
})
.finally(async () => await prisma.$disconnect());
```
3.2. Set up migration script [#32-set-up-migration-script]
Add the migration script to your package.json:
```json
{
"scripts": {
"data-migration:add-status-column": "tsx ./prisma/migrations//data-migration.ts"
}
}
```
3.3. Execute migration [#33-execute-migration]
1. Update your DATABASE\_URL to point to the production database
2. Run the migration script:
npm
pnpm
yarn
bun
```bash
npm run data-migration:add-status-column
```
```bash
pnpm run data-migration:add-status-column
```
```bash
yarn data-migration:add-status-column
```
```bash
bun run data-migration:add-status-column
```
4. Contract the schema [#4-contract-the-schema]
4.1. Create cleanup branch [#41-create-cleanup-branch]
Create a new branch for removing the old column:
```bash
git checkout -b drop-published-column
```
4.2. Remove old column [#42-remove-old-column]
Update your schema to remove the published field:
```prisma
model Post {
id Int @id @default(autoincrement())
title String
content String?
status Status @default(Unknown)
}
enum Status {
Draft
InProgress
InReview
Published
}
```
4.3. Generate cleanup migration [#43-generate-cleanup-migration]
Create and run the final migration:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name drop-published-column
```
```bash
pnpm dlx prisma migrate dev --name drop-published-column
```
```bash
yarn dlx prisma migrate dev --name drop-published-column
```
```bash
bunx --bun prisma migrate dev --name drop-published-column
```
Then generate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
5. Deploy to production [#5-deploy-to-production]
5.1. Set up deployment [#51-set-up-deployment]
Add the following command to your CI/CD pipeline:
npm
pnpm
yarn
bun
```bash
npx prisma migrate deploy
```
```bash
pnpm dlx prisma migrate deploy
```
```bash
yarn dlx prisma migrate deploy
```
```bash
bunx --bun prisma migrate deploy
```
5.2. Monitor deployment [#52-monitor-deployment]
Watch for any errors in your logs and monitor your application's behavior after deployment.
Troubleshooting [#troubleshooting]
Common issues and solutions [#common-issues-and-solutions]
1. **Migration fails due to missing default**
* Ensure you've added a proper default value
* Check that all existing records can be migrated
2. **Data loss prevention**
* Always backup your database before running migrations
* Test migrations on a copy of production data first
3. **Transaction rollback**
* If the data migration fails, the transaction will automatically rollback
* Fix any errors and retry the migration
Next steps [#next-steps]
Now that you've completed your first expand and contract migration, you can:
* Learn more about [Prisma Migrate](/orm/prisma-migrate)
* Explore [schema prototyping](/orm/prisma-migrate/workflows/prototyping-your-schema)
* Understand [customizing migrations](/orm/prisma-migrate/workflows/customizing-migrations)
For more information:
* [Expand and Contract Pattern Documentation](https://www.prisma.io/dataguide/types/relational/expand-and-contract-pattern)
* [Prisma Migrate Workflows](/orm/prisma-migrate/workflows/development-and-production)
# Multiple databases (/docs/guides/database/multiple-databases)
Introduction [#introduction]
This guide shows you how to use multiple databases using Prisma ORM in a single [Next.js app](https://nextjs.org/). You will learn how to connect to two different Prisma Postgres databases, manage migrations, and deploy your application to Vercel. This approach is useful for multi-tenant applications or when you need to separate concerns when managing connections to multiple databases.
Prerequisites [#prerequisites]
Before you begin, make sure that you have the following:
* Node.js 20+ installed.
* A [Prisma Data Platform account](https://pris.ly/pdp?utm_campaign=multi-client\&utm_source=docs).
* A Vercel account (if you plan to deploy your application).
1. Set up a Next.js project [#1-set-up-a-nextjs-project]
Create a new Next.js app using `create-next-app` from your desired directory:
npm
pnpm
yarn
bun
```bash
npx create-next-app@latest my-multi-client-app
```
```bash
pnpm dlx create-next-app@latest my-multi-client-app
```
```bash
yarn dlx create-next-app@latest my-multi-client-app
```
```bash
bunx --bun create-next-app@latest my-multi-client-app
```
You will be prompted to answer a few questions about your project. Select all of the defaults.
For completeness, those are:
* TypeScript
* ESLint
* Tailwind CSS
* No `src` directory
* App Router
* Turbopack
* Default custom import alias: `@/*`
Then, navigate to the project directory:
```bash
cd my-multi-client-app
```
2. Set up your databases and Prisma Clients [#2-set-up-your-databases-and-prisma-clients]
In this section, you will create two separate Prisma Postgres instances—one for user data and one for post data. You will also configure the Prisma schema and environment variables for each.
First, install Prisma and the required dependencies:
npm
pnpm
yarn
bun
```bash
npm install prisma tsx @types/pg --save-dev
```
```bash
pnpm add prisma tsx @types/pg --save-dev
```
```bash
yarn add prisma tsx @types/pg --dev
```
```bash
bun add prisma tsx @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
bun add @prisma/client @prisma/adapter-pg dotenv pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
You have installed the required dependencies for the project.
2.1. Create a Prisma Postgres instance to contain user data [#21-create-a-prisma-postgres-instance-to-contain-user-data]
Initialize Prisma with a [Prisma Postgres](/postgres) instance by running:
npm
pnpm
yarn
bun
```bash
npx prisma@latest init --db
```
```bash
pnpm dlx prisma@latest init --db
```
```bash
yarn dlx prisma@latest init --db
```
```bash
bunx --bun prisma@latest init --db
```
If you are not using a Prisma Postgres database, do not use the `--db` flag. Instead, create two PostgreSQL database instances and add their connection URLs to the `.env` file as `PPG_USER_DATABASE_URL` and `PPG_POST_DATABASE_URL`.
Follow the prompts to name your project and choose a database region.
The `prisma@latest init --db` command:
* Connects your CLI to your [Prisma Data Platform](https://console.prisma.io) account. If you are not logged in or do not have an account, your browser will open to guide you through creating a new account or signing into your existing one.
* Creates a `prisma` directory containing a `schema.prisma` file for your database models.
* Creates a `.env` file with your `DATABASE_URL` (e.g., `DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require"`).
Rename the `prisma` folder to `prisma-user-database`:
```bash
mv prisma prisma-user-database
```
Edit your `.env` file to rename `DATABASE_URL` to `PPG_USER_DATABASE_URL`:
```bash title=".env"
DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require" # [!code --]
PPG_USER_DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require" # [!code ++]
```
Open `prisma-user-database/schema.prisma` file and update it to define a `User` model. Also, set the environment variable and specify a [custom `output` directory](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider) for the generated Prisma Client:
```prisma title="prisma-user-database/schema.prisma"
generator client {
provider = "prisma-client"
output = "../prisma-user-database/user-database-client-types" // [!code ++]
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
} // [!code ++]
```
Create a `prisma.config.ts` file for the user database:
```typescript title="prisma-user-database/prisma.config.ts"
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config"; // [!code ++]
// [!code ++]
export default defineConfig({
// [!code ++]
schema: "prisma-user-database/schema.prisma", // [!code ++]
migrations: {
// [!code ++]
path: "prisma-user-database/migrations", // [!code ++]
}, // [!code ++]
datasource: {
// [!code ++]
url: env("PPG_USER_DATABASE_URL"), // [!code ++]
}, // [!code ++]
}); // [!code ++]
```
You'll need to install the `dotenv` package if you haven't already:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
Your user database schema is now ready.
2.2. Create a Prisma Postgres instance for post data [#22-create-a-prisma-postgres-instance-for-post-data]
Repeat the initialization for the post database:
npm
pnpm
yarn
bun
```bash
npx prisma init --db
```
```bash
pnpm dlx prisma init --db
```
```bash
yarn dlx prisma init --db
```
```bash
bunx --bun prisma init --db
```
After following the prompts, rename the new `prisma` folder to `prisma-post-database`:
```bash
mv prisma prisma-post-database
```
Rename the `DATABASE_URL` variable in `.env` to `PPG_POST_DATABASE_URL`:
```bash title=".env"
DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require" # [!code --]
PPG_POST_DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require" # [!code ++]
```
Edit the `prisma-post-database/schema.prisma` file to define a `Post` model. Also, update the datasource URL and set a [custom `output` directory](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider):
```prisma title="prisma-post-database/schema.prisma"
generator client {
provider = "prisma-client"
output = "../prisma-post-database/post-database-client-types" // [!code ++]
}
datasource db {
provider = "postgresql"
}
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
} // [!code ++]
```
Create a `prisma.config.ts` file for the post database:
```typescript title="prisma-post-database/prisma.config.ts"
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config"; // [!code ++]
// [!code ++]
export default defineConfig({
// [!code ++]
schema: "prisma-post-database/schema.prisma", // [!code ++]
migrations: {
// [!code ++]
path: "prisma-post-database/migrations", // [!code ++]
}, // [!code ++]
datasource: {
// [!code ++]
url: env("PPG_POST_DATABASE_URL"), // [!code ++]
}, // [!code ++]
}); // [!code ++]
```
Your post database schema is now set.
2.3. Add helper scripts and migrate the schemas [#23-add-helper-scripts-and-migrate-the-schemas]
To simplify your workflow, add helper scripts to your `package.json` file that run Prisma commands for both databases:
```json title="package.json"
"script":{
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint",
"postinstall": "npx prisma generate --schema ./prisma-user-database/schema.prisma && npx prisma generate --schema ./prisma-post-database/schema.prisma", // [!code ++]
"generate": "npx prisma generate --schema ./prisma-user-database/schema.prisma && npx prisma generate --schema ./prisma-post-database/schema.prisma", // [!code ++]
"migrate": "npx prisma migrate dev --schema ./prisma-user-database/schema.prisma && npx prisma migrate dev --schema ./prisma-post-database/schema.prisma", // [!code ++]
"deploy": "npx prisma migrate deploy --schema ./prisma-user-database/schema.prisma && npx prisma migrate deploy --schema ./prisma-post-database/schema.prisma", // [!code ++]
"studio": "npx prisma studio --schema ./prisma-user-database/schema.prisma --port 5555 & npx prisma studio --schema ./prisma-post-database/schema.prisma --port 5556" // [!code ++]
}
```
Here is an explanation of the custom scripts:
* `postinstall`: Runs immediately after installing dependencies to generate Prisma Clients for both the user and post databases using their respective schema files.
* `generate`: Manually triggers the generation of Prisma Clients for both schemas, ensuring your client code reflects the latest models.
* `migrate`: Applies pending migrations in development mode for both databases using [Prisma Migrate](/orm/prisma-migrate), updating their schemas based on changes in your Prisma files.
* `deploy`: Executes migrations in a production environment, synchronizing your live databases with your Prisma schemas.
* `studio`: Opens Prisma Studio for both databases simultaneously on different ports (`5555` for the user database and `5556` for the post database) for visual data management.
Run the migrations:
npm
pnpm
yarn
bun
```bash
npm run migrate
```
```bash
pnpm run migrate
```
```bash
yarn migrate
```
```bash
bun run migrate
```
When prompted, name the migration for each database accordingly.
3. Prepare the application to use multiple Prisma Clients [#3-prepare-the-application-to-use-multiple-prisma-clients]
Next, create a `lib` folder to store helper files for instantiating and exporting your Prisma Clients:
```bash
mkdir -p lib && touch lib/user-prisma-client.ts lib/post-prisma-client.ts
```
3.1. Instantiate and export the Prisma Client for the user database [#31-instantiate-and-export-the-prisma-client-for-the-user-database]
In `lib/user-prisma-client.ts`, add the following code:
```ts title="lib/user-prisma-client.ts"
import { PrismaClient } from "../prisma-user-database/user-database-client-types/client"; // [!code ++]
import { PrismaPg } from "@prisma/adapter-pg"; // [!code ++]
// [!code ++]
const adapter = new PrismaPg({
// [!code ++]
connectionString: process.env.PPG_USER_DATABASE_URL, // [!code ++]
}); // [!code ++]
// [!code ++]
const getPrisma = () =>
new PrismaClient({
// [!code ++]
adapter, // [!code ++]
}); // [!code ++]
// [!code ++]
const globalForUserDBPrismaClient = global as unknown as {
// [!code ++]
userDBPrismaClient: ReturnType; // [!code ++]
}; // [!code ++]
// [!code ++]
export const userDBPrismaClient = globalForUserDBPrismaClient.userDBPrismaClient || getPrisma(); // [!code ++] // [!code ++]
// [!code ++]
if (process.env.NODE_ENV !== "production")
// [!code ++]
globalForUserDBPrismaClient.userDBPrismaClient = userDBPrismaClient; // [!code ++]
```
3.2. Instantiate and export the Prisma Client for the post database [#32-instantiate-and-export-the-prisma-client-for-the-post-database]
In `lib/post-prisma-client.ts`, add this code:
```ts title="lib/post-prisma-client.ts"
import { PrismaClient } from "../prisma-post-database/post-database-client-types/client"; // [!code ++]
import { PrismaPg } from "@prisma/adapter-pg"; // [!code ++]
// [!code ++]
const adapter = new PrismaPg({
// [!code ++]
connectionString: process.env.PPG_POST_DATABASE_URL, // [!code ++]
}); // [!code ++]
// [!code ++]
const getPrisma = () =>
new PrismaClient({
// [!code ++]
adapter, // [!code ++]
}); // [!code ++]
// [!code ++]
const globalForPostDBPrismaClient = global as unknown as {
// [!code ++]
postDBPrismaClient: ReturnType; // [!code ++]
}; // [!code ++]
// [!code ++]
export const postDBPrismaClient = globalForPostDBPrismaClient.postDBPrismaClient || getPrisma(); // [!code ++] // [!code ++]
// [!code ++]
if (process.env.NODE_ENV !== "production")
// [!code ++]
globalForPostDBPrismaClient.postDBPrismaClient = postDBPrismaClient; // [!code ++]
```
4. Integrate multiple Prisma Clients in your Next.js app [#4-integrate-multiple-prisma-clients-in-your-nextjs-app]
Modify your application code to fetch data from both databases. Update the `app/page.tsx` file as follows:
```ts title="app/page.tsx"
import { postDBPrismaClient } from "@/lib/post-prisma-client"; // [!code ++]
import { userDBPrismaClient } from "@/lib/user-prisma-client"; // [!code ++]
// [!code ++]
export default async function Home() { // [!code ++]
const user = await userDBPrismaClient.user.findFirst(); // [!code ++]
const post = await postDBPrismaClient.post.findFirst(); // [!code ++]
// [!code ++]
return ( // [!code ++]
// [!code ++]
// [!code ++]
// [!code ++]
Multi-DB Showcase
// [!code ++]
// [!code ++]
Data fetched from two distinct databases. // [!code ++]
// [!code ++]
{post ? JSON.stringify(post, null, 2) : "No post data available."} // [!code ++]
// [!code ++]
// [!code ++]
// [!code ++]
// [!code ++]
); // [!code ++]
} // [!code ++]
```
4.1. Populate your databases with data [#41-populate-your-databases-with-data]
In a separate terminal window, open two instances of [Prisma Studio](/studio) to add data to your databases by running the script:
npm
pnpm
yarn
bun
```bash
npm run studio
```
```bash
pnpm run studio
```
```bash
yarn studio
```
```bash
bun run studio
```
This will open up two browser windows, one in `http://localhost:5555` and one in `http://localhost:5556`. Navigate to those windows and add sample data to both databases.
4.2. Run the development server [#42-run-the-development-server]
Before starting the development server, note that if you are using Next.js `v15.2.0`, do not use Turbopack as there is a known [issue](https://github.com/vercel/next.js/issues/76497). Remove Turbopack from your dev script by updating your `package.json`:
```json title="package.json"
"script":{
"dev": "next dev --turbopack", // [!code --]
"dev": "next dev", // [!code ++]
"build": "next build",
"start": "next start",
"lint": "next lint",
"postinstall": "npx prisma generate --schema ./prisma-user-database/schema.prisma && npx prisma generate --schema ./prisma-post-database/schema.prisma",
"generate": "npx prisma generate --schema ./prisma-user-database/schema.prisma && npx prisma generate --schema ./prisma-post-database/schema.prisma",
"migrate": "npx prisma migrate dev --schema ./prisma-user-database/schema.prisma && npx prisma migrate dev --schema ./prisma-post-database/schema.prisma",
"deploy": "npx prisma migrate deploy --schema ./prisma-user-database/schema.prisma && npx prisma migrate deploy --schema ./prisma-post-database/schema.prisma",
"studio": "npx prisma studio --schema ./prisma-user-database/schema.prisma --port 5555 & npx prisma studio --schema ./prisma-post-database/schema.prisma --port 5556"
}
```
In a separate terminal window, start the development server by running:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
Navigate to `http://localhost:3000` to see your Next.js app display data from both databases:
Congratulations, you have a Next.js app running with two Prisma Client instances querying different databases.
5. Deploy your Next.js app using multiple databases to Vercel [#5-deploy-your-nextjs-app-using-multiple-databases-to-vercel]
Deploy your app by following these steps:
1. Ensure your project is version-controlled and pushed to a GitHub repository. If you do not have a repository yet, [create one on GitHub](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-new-repository). Once the repository is ready, run the following commands:
```bash
git add .
git commit -m "Initial commit with Prisma Postgres integration"
git branch -M main
git remote add origin https://github.com//.git
git push -u origin main
```
Replace `` and `` with your GitHub username and the name of your repository.
2. Log in to [Vercel](https://vercel.com/) and navigate to your [Dashboard](https://vercel.com/docs/dashboard-features).
3. Create a new project. Follow Vercel's [Import an existing project](https://vercel.com/docs/getting-started-with-vercel/import) guide, but stop at [step 3](https://vercel.com/docs/getting-started-with-vercel/import#optionally-configure-any-settings) where you will configure environment variables *before* clicking **Deploy**.
4. Configure the `DATABASE_URL` environment variable:
1. Expand the **Environment variables** section.
2. Add the `PPG_USER_DATABASE_URL` environment variable:
* **Key**: `PPG_USER_DATABASE_URL`
* **Value**: Paste your user database connection URL, e.g. by copying it from the `.env` file in your project.
3. Add the `PPG_POST_DATABASE_URL` environment variable:
* **Key**: `PPG_POST_DATABASE_URL`
* **Value**: Paste your post database connection URL, e.g. by copying it from the `.env` file in your project.
Do not deploy without setting the environment variables. Your deployment will fail if the application cannot connect to the databases.
5. Click the **Deploy** button. Vercel will build your project and deploy it to a live URL.
Open the live URL provided by Vercel and verify that your application is working.
Congratulations! You have deployed an application that uses multiple Prisma Clients to query two different databases, and it is now live and fully operational on Vercel.
Next steps [#next-steps]
In this guide, you learned how to use multiple databases using Prisma ORM in a single Next.js app by:
* Setting up separate Prisma schemas for user and post databases.
* Configuring custom output directories and environment variables.
* Creating helper scripts to generate and migrate each schema.
* Instantiating and integrating multiple Prisma Clients into your application.
* Deploying your multi-database application to Vercel.
This approach allows you to maintain a clear separation of data models and simplifies multi-tenant or multi-database scenarios.
For further improvements in managing your project, consider using a monorepo setup. Check out our related guides:
* [How to use Prisma ORM in a pnpm workspaces monorepo](/guides/deployment/pnpm-workspaces)
* [How to use Prisma ORM with Turborepo](/guides/deployment/turborepo)
# Schema management in teams (/docs/guides/database/schema-changes)
Introduction [#introduction]
When working in a team, managing database schema changes can be challenging. This guide shows you how to effectively collaborate on schema changes using Prisma Migrate, ensuring that all team members can safely contribute to and incorporate schema changes.
Prerequisites [#prerequisites]
Before starting this guide, make sure you have:
* Node.js installed (version 20 or higher)
* A Prisma project set up with migrations
* A relational database (PostgreSQL, MySQL, SQLite, SQL Server, etc.)
* Basic understanding of Git
* Basic familiarity with Prisma Migrate
This guide **does not apply for MongoDB**.
Instead of `migrate dev`, [`db push`](/orm/prisma-migrate/workflows/prototyping-your-schema) is used for [MongoDB](/orm/core-concepts/supported-databases/mongodb).
1. Understand migration basics [#1-understand-migration-basics]
1.1. Migration order [#11-migration-order]
Migrations are **applied in the same order as they were created**. The creation date is part of the migration subfolder name - for example, `20210316081837-updated-fields` was created on `2021-03-16-08:18:37`.
1.2. Source control requirements [#12-source-control-requirements]
You should commit the following files to source control:
* The contents of the `.prisma/migrations` folder, including the `migration_lock.toml` file
* The Prisma Schema (`schema.prisma`)
Source-controlling the `schema.prisma` file is not enough - you must include your migration history because:
* Customized migrations contain information that cannot be represented in the Prisma schema
* The `prisma migrate deploy` command only runs migration files
1.3. Configure Prisma [#13-configure-prisma]
Create a `prisma.config.ts` file in the root of your project with the following content:
```typescript title="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"),
},
});
```
You'll need to install the `dotenv` package to load environment variables. If you haven't already, install it using your package manager:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
2. Incorporate team changes [#2-incorporate-team-changes]
2.1. Pull latest changes [#21-pull-latest-changes]
To incorporate changes from collaborators:
1. Pull the changed Prisma schema and `./prisma/migrations` folder
2. Run the migrate command:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev
```
```bash
pnpm dlx prisma migrate dev
```
```bash
yarn dlx prisma migrate dev
```
```bash
bunx --bun prisma migrate dev
```
2.2. Example scenario [#22-example-scenario]
Let's walk through a sample scenario with three developers sharing schema changes:
Before
After
```prisma title="schema.prisma"
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
```
```prisma title="schema.prisma"
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
favoriteColor String? // Added by Ania // [!code ++]
bestPacmanScore Int? // Added by you // [!code ++]
posts Post[]
}
// Added by Javier // [!code ++]
model Tag { // [!code ++]
tagName String @id // [!code ++]
tagCategory Category // [!code ++]
} // [!code ++]
```
3. Handle concurrent changes [#3-handle-concurrent-changes]
3.1. Developer A's changes [#31-developer-as-changes]
Ania adds a new field:
```prisma
model User {
/* ... */
favoriteColor String?
}
```
And generates a migration:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name new-field
```
```bash
pnpm dlx prisma migrate dev --name new-field
```
```bash
yarn dlx prisma migrate dev --name new-field
```
```bash
bunx --bun prisma migrate dev --name new-field
```
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
3.2. Developer B's changes [#32-developer-bs-changes]
Javier adds a new model:
```prisma
model Tag {
tagName String @id
tagCategory Category
}
```
And generates a migration:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name new-model
```
```bash
pnpm dlx prisma migrate dev --name new-model
```
```bash
yarn dlx prisma migrate dev --name new-model
```
```bash
bunx --bun prisma migrate dev --name new-model
```
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
3.3. Merge changes [#33-merge-changes]
The migration history now has two new migrations:
4. Integrate your changes [#4-integrate-your-changes]
4.1. Pull team changes [#41-pull-team-changes]
1. Pull the most recent changes:
* Two new migrations
* Updated schema file
2. Review the merged schema:
```prisma
model User {
/* ... */
favoriteColor String?
bestPacmanScore Int?
}
model Tag {
tagName String @id
tagCategory Category
posts Post[]
}
```
4.2. Generate your migration [#42-generate-your-migration]
Run the migrate command:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev
```
```bash
pnpm dlx prisma migrate dev
```
```bash
yarn dlx prisma migrate dev
```
```bash
bunx --bun prisma migrate dev
```
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
This will:
1. Apply your team's migrations
2. Create a new migration for your changes
3. Apply your new migration
4.3. Commit changes [#43-commit-changes]
Commit:
* The merged `schema.prisma`
* Your new migration file
Next steps [#next-steps]
Now that you understand team schema management, you can:
* Learn about [customizing migrations](/orm/prisma-migrate/workflows/customizing-migrations)
* Explore [deployment workflows](/orm/prisma-migrate/workflows/development-and-production)
For more information:
* [Prisma Migrate documentation](/orm/prisma-migrate)
* [Team development workflows](/orm/prisma-migrate/workflows/development-and-production)
# Bun workspaces (/docs/guides/deployment/bun-workspaces)
Introduction [#introduction]
This guide shows you how to use Prisma ORM in a [Bun Workspaces](https://bun.sh/docs/install/workspaces) monorepo. You'll set up a shared database package with Prisma ORM, then integrate it into a Next.js app in the same workspace.
Prerequisites [#prerequisites]
* [Bun](https://bun.sh/docs/installation) installed
* A [Prisma Postgres](/postgres) database (or another [supported database](/orm/reference/supported-databases))
1. Set up project [#1-set-up-project]
Before integrating Prisma ORM, you need to set up your project structure. Start by creating a new directory for your project (for example, `my-monorepo`) and initialize a Node.js project:
```bash
mkdir my-monorepo
cd my-monorepo
bun init -y
```
Next, add the `workspaces` array to your root `package.json` to define your workspace structure:
```json title="package.json"
{
"name": "my-monorepo", // [!code ++]
"workspaces": ["apps/*", "packages/*"] // [!code ++]
}
```
Finally, create directories for your applications and shared packages:
```bash
mkdir apps
mkdir -p packages/database
```
2. Set up database package [#2-set-up-database-package]
This section covers creating a standalone database package that uses Prisma ORM. The package will house all database models and the generated Prisma ORM client, making it reusable across your monorepo.
2.1. Install dependencies [#21-install-dependencies]
Navigate to the `packages/database` directory and initialize a new package:
```bash
cd packages/database
bun init
```
Install the required Prisma ORM packages and other dependencies:
```bash
bun add -d prisma typescript tsx @types/node @types/pg
bun add @prisma/client @prisma/adapter-pg pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
2.2. Set up Prisma ORM and schema [#22-set-up-prisma-orm-and-schema]
Initialize Prisma ORM with an instance of [Prisma Postgres](/postgres) in the `database` package by running the following command:
```bash
bunx prisma init --db
```
Enter a name for your project and choose a database region.
We're going to be using [Prisma Postgres](/postgres) in this guide. If you're not using a Prisma Postgres database, you won't need to add the `--db` flag.
This command:
* Connects your CLI to your [Prisma Data Platform](https://console.prisma.io) account. If you're not logged in or don't have an account, your browser will open to guide you through creating a new account or signing into your existing one.
* Creates a `prisma` directory containing a `schema.prisma` file for your database models.
* Creates a `prisma.config.ts` file (which uses `process.env["DATABASE_URL"]` and expects `dotenv`).
* Creates a `.env` file with your `DATABASE_URL` (e.g., for Prisma Postgres it should have something similar to `DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=eyJhbGciOiJIUzI..."`).
Edit the `schema.prisma` file to add a `User` model. The default generator already sets `output = "../generated/prisma"`:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
} // [!code ++]
```
If the generated `prisma.config.ts` comments mention installing `dotenv`, install it so environment variables load:
```bash
bun add dotenv
```
Add a `scripts` section to your database `package.json` (Bun init may not add one by default):
```json title="database/package.json"
{
"scripts": { // [!code ++]
"db:generate": "prisma generate", // [!code ++]
"db:migrate": "prisma migrate dev", // [!code ++]
"db:deploy": "prisma migrate deploy", // [!code ++]
"db:seed": "prisma db seed", // [!code ++]
"db:studio": "prisma studio" // [!code ++]
} // [!code ++]
}
```
Use [Prisma Migrate](/orm/prisma-migrate) to migrate your database changes:
```bash
bun run db:migrate
```
When prompted by the CLI, enter a descriptive name for your migration. After the migration completes, run generate so the Prisma ORM client is created:
```bash
bun run db:generate
```
Create a `client.ts` file to initialize the Prisma ORM client with a driver adapter:
```ts title="database/client.ts"
import { PrismaClient } from "./generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
// Use globalThis for broader environment compatibility
const globalForPrisma = globalThis as typeof globalThis & {
prisma?: PrismaClient;
};
export const prisma: PrismaClient =
globalForPrisma.prisma ??
new PrismaClient({
adapter,
});
if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = prisma;
}
```
Then, create an `index.ts` file to re-export the instance of the Prisma ORM client and all generated types:
```ts title="database/index.ts"
export { prisma } from "./client";
export * from "./generated/prisma/client";
```
2.3. Seed the database [#23-seed-the-database]
Add a seed script to populate the database with sample users. Create `prisma/seed.ts` in the database package:
```ts title="database/prisma/seed.ts"
import "dotenv/config";
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 });
async function main() {
await prisma.user.createMany({
data: [
{ email: "alice@example.com", name: "Alice" },
{ email: "bob@example.com", name: "Bob" },
{ email: "charlie@example.com", name: "Charlie" },
],
skipDuplicates: true,
});
console.log("Seed complete.");
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
Add the `seed` option to the existing `migrations` config in your database package's `prisma.config.ts` (add the `seed` line inside `migrations`):
```ts title="database/prisma.config.ts"
migrations: {
path: "prisma/migrations",
seed: "bun prisma/seed.ts", // [!code ++]
},
```
At this point, your shared database package is fully configured and ready for use across your monorepo.
2.4. Add root scripts [#24-add-root-scripts]
Add the following scripts to the root `package.json` of your monorepo. They let you run database and app commands from the root:
```json title="package.json"
"scripts": { // [!code ++]
"build": "bun run --filter database db:deploy && bun run --filter database db:generate && bun run --filter web build", // [!code ++]
"start": "bun run --filter web start", // [!code ++]
"dev": "bun run --filter database db:generate && bun run --filter web dev", // [!code ++]
"seed": "bun run --filter database db:seed", // [!code ++]
"studio": "bun run --filter database db:studio" // [!code ++]
} // [!code ++]
```
From the monorepo root, run `bun run seed` to add sample users. Run `bun run studio` to open [Prisma Studio](/studio) at [`http://localhost:5555`](http://localhost:5555) to view and edit your data.
3. Set up Next.js app [#3-set-up-nextjs-app]
Now that the database package is set up, create a frontend application (using Next.js) that uses the shared Prisma ORM client to interact with your database.
3.1. Create Next.js app [#31-create-nextjs-app]
Navigate to the `apps` directory:
```bash
cd ../../apps
```
Create a new Next.js app named `web`:
```bash
bun create next-app@latest web --yes
```
important
The `--yes` flag uses default configurations to bootstrap the Next.js app (which in this guide uses the app router without a `src/` directory). When prompted for a package manager, choose **Bun** so the app uses Bun within the workspace.
Additionally, the flag may automatically initialize a Git repository in the `web` folder. If that happens, please remove the `.git` directory by running `rm -r .git`.
Then, navigate into the web directory:
```bash
cd web/
```
Copy the `.env` file from the database package to ensure the same environment variables are available:
```bash
cp ../../packages/database/.env .
```
Open the `package.json` file of your Next.js app and add the shared `database` package as a dependency:
```json title="web/package.json"
"dependencies": {
"database": "workspace:*" // [!code ++]
}
```
Run the following command to install the `database` package:
```bash
bun install
```
3.2. Add database to app [#32-add-database-to-app]
Modify your Next.js application code to use the Prisma ORM client from the database package. Update `app/page.tsx` as follows:
```tsx title="app/page.tsx"
import { prisma } from "database";
export default async function Home() {
const user = await prisma.user.findFirst({
select: {
name: true,
},
});
return (
{user?.name &&
Hello from {user.name}
}
{!user?.name &&
No user has been added to the database yet.
}
);
}
```
This code demonstrates importing and using the shared Prisma ORM client to query your `User` model.
3.3. Run the app [#33-run-the-app]
Then head back to the root of the monorepo:
```bash
cd ../../
```
Start your development server by executing:
```bash
bun run dev
```
Open your browser at [`http://localhost:3000`](http://localhost:3000) to see your app in action. You can run `bun run studio` to open [Prisma Studio](/studio) at [`http://localhost:5555`](http://localhost:5555) to view and edit your data.
Next steps [#next-steps]
You have now created a monorepo that uses Prisma ORM, with a shared database package integrated into a Next.js application.
For further exploration and to enhance your setup, consider reading the [How to use Prisma ORM with Turborepo](/guides/deployment/turborepo) guide.
# Cloudflare D1 (/docs/guides/deployment/cloudflare-d1)
Introduction [#introduction]
This guide shows you how to use Prisma ORM with Cloudflare D1, a serverless SQL database that runs on Cloudflare's edge network. You'll learn how to set up Prisma ORM with D1, handle migrations, and deploy your application to Cloudflare Workers. You can find a [deployment-ready example on GitHub](https://github.com/prisma/prisma-examples/blob/latest/deployment-platforms/edge/cloudflare-workers/with-d1).
Prerequisites [#prerequisites]
Before starting this guide, make sure you have:
* A Cloudflare account
* Node.js installed (version 20 or higher)
* Wrangler CLI installed (version 3.39.0 or higher)
* Basic familiarity with Cloudflare Workers and D1
1. Create a new Cloudflare Worker and initialize Prisma ORM [#1-create-a-new-cloudflare-worker-and-initialize-prisma-orm]
Run the following command to create a [new Cloudflare Worker project](https://developers.cloudflare.com/d1/get-started/#1-create-a-worker):
npm
pnpm
yarn
bun
```bash
npm create cloudflare@latest d1-tutorial -- --type=hello-world --ts=true --git=true --deploy=false
```
```bash
pnpm create cloudflare d1-tutorial --type=hello-world --ts=true --git=true --deploy=false
```
```bash
yarn create cloudflare d1-tutorial --type=hello-world --ts=true --git=true --deploy=false
```
```bash
bunx create-cloudflare d1-tutorial --type hello-world --ts=true --git=true --deploy=false
```
Then navigate into the newly created directory:
```bash
cd d1-tutorial
```
And initialize Prisma ORM in the project:
npm
pnpm
yarn
bun
```bash
npx prisma init --datasource-provider sqlite
```
```bash
pnpm dlx prisma init --datasource-provider sqlite
```
```bash
yarn dlx prisma init --datasource-provider sqlite
```
```bash
bunx --bun prisma init --datasource-provider sqlite
```
And install the Prisma ORM CLI as a development dependency:
npm
pnpm
yarn
bun
```bash
npm install --save-dev prisma
```
```bash
pnpm add --save-dev prisma
```
```bash
yarn add --dev prisma
```
```bash
bun add --dev prisma
```
2. Configure Prisma schema [#2-configure-prisma-schema]
In your Prisma schema, set the `provider` of the `datasource` to `sqlite`. If you just bootstrapped the Prisma schema with `prisma init`, also be sure to add the `runtime = "cloudflare"` to the generator block and the following `User` model:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
runtime = "cloudflare"
}
datasource db {
provider = "sqlite"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
} // [!code ++]
```
3. Install dependencies [#3-install-dependencies]
Next, install the required packages:
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-d1 dotenv
```
```bash
pnpm add @prisma/client @prisma/adapter-d1 dotenv
```
```bash
yarn add @prisma/client @prisma/adapter-d1 dotenv
```
```bash
bun add @prisma/client @prisma/adapter-d1 dotenv
```
Also, be sure to use a version of the Wrangler CLI that's above [`wrangler@^3.39.0`](https://github.com/cloudflare/workers-sdk/releases/tag/wrangler%403.39.0), otherwise the `--remote` flag that's used in the next sections won't be available.
4. Create a D1 database [#4-create-a-d1-database]
Run the following command to create a new D1 database:
npm
pnpm
yarn
bun
```bash
npx wrangler@latest d1 create __YOUR_D1_DATABASE_NAME__
```
```bash
pnpm dlx wrangler@latest d1 create __YOUR_D1_DATABASE_NAME__
```
```bash
yarn dlx wrangler@latest d1 create __YOUR_D1_DATABASE_NAME__
```
```bash
bunx --bun wrangler@latest d1 create __YOUR_D1_DATABASE_NAME__
```
The `__YOUR_D1_DATABASE_NAME__` is a placeholder that should be replaced with the name you want to give your D1 database. For example, you can use `prisma-d1-example`.
This command will authenticate you with Cloudflare and ask you to select a Cloudflare account. After that, it will create a new D1 database and output the database ID and name:
```bash
✅ Successfully created DB '__YOUR_D1_DATABASE_NAME__' in region __REGION__
Created your new D1 database.
{
"d1_databases": [
{
"binding": "DB",
"database_name": "__YOUR_D1_DATABASE_NAME__",
"database_id": ""
}
]
}
```
Copy the terminal output and add the content to your `wrangler.jsonc` file. This file is used to configure your Cloudflare Worker and its bindings.
To connect your Workers with the D1 instance, add the following binding to your `wrangler.jsonc`:
```json title="wrangler.jsonc"
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "d1-tutorial",
"main": "src/index.ts",
"compatibility_date": "2025-08-05",
"d1_databases": [
{
"binding": "DB",
"database_name": "__YOUR_D1_DATABASE_NAME__", // to be replaced
"database_id": "__YOUR_D1_DATABASE_ID__" // to be replaced
}
]
}
```
The `__YOUR_D1_DATABASE_NAME__` and `__YOUR_D1_DATABASE_ID__` in the snippet above are placeholders that should be replaced with the database name and ID of your own D1 instance.
If you weren't able to grab the database ID from the terminal output, you can also find it in the Cloudflare Dashboard or by running `npx wrangler d1 list` and `npx wrangler d1 info __YOUR_D1_DATABASE_NAME__` in your terminal.
5. Set up database migrations [#5-set-up-database-migrations]
For Cloudflare D1, you'll use Prisma's migration workflow combined with Wrangler CLI to manage your database schema. Since D1 is a serverless SQLite database, we'll use `prisma migrate diff` to generate migration SQL and then apply it using Wrangler.
5.1 Set up environment variables [#51-set-up-environment-variables]
Add a `.env` file in the root of your project with your local database URL:
```text title=".env"
DATABASE_URL="file:./prisma/db.sqlite"
```
Also create a `prisma.config.ts` file in the root of your project:
```typescript title="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"),
},
});
```
5.2 Generate migration SQL [#52-generate-migration-sql]
First, create a migrations directory inside the `prisma` folder and create a file named `0001_init.sql`:
```bash
mkdir -p prisma/migrations
```
Now use `prisma migrate diff` to generate the SQL needed to create your database schema:
npm
pnpm
yarn
bun
```bash
npx prisma migrate diff \
--from-empty \
--to-schema prisma/schema.prisma \
--script > prisma/migrations/0001_init.sql
```
```bash
pnpm dlx prisma migrate diff \
--from-empty \
--to-schema prisma/schema.prisma \
--script > prisma/migrations/0001_init.sql
```
```bash
yarn dlx prisma migrate diff \
--from-empty \
--to-schema prisma/schema.prisma \
--script > prisma/migrations/0001_init.sql
```
```bash
bunx --bun prisma migrate diff \
--from-empty \
--to-schema prisma/schema.prisma \
--script > prisma/migrations/0001_init.sql
```
This command generates a SQL file that contains the statements needed to create your database tables. You can inspect the generated SQL in `prisma/migrations/0001_init.sql`.
5.3 Apply migrations to D1 [#53-apply-migrations-to-d1]
Now apply the migration to both your local and remote D1 databases using Wrangler:
npm
pnpm
yarn
bun
```bash
# Apply to local database
npx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --local --file="./prisma/migrations/0001_init.sql"
# Apply to remote database
npx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --remote --file="./prisma/migrations/0001_init.sql"
```
```bash
# Apply to local database
pnpm dlx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --local --file="./prisma/migrations/0001_init.sql"
# Apply to remote database
pnpm dlx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --remote --file="./prisma/migrations/0001_init.sql"
```
```bash
# Apply to local database
yarn dlx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --local --file="./prisma/migrations/0001_init.sql"
# Apply to remote database
yarn dlx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --remote --file="./prisma/migrations/0001_init.sql"
```
```bash
# Apply to local database
bun x wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --local --file="./prisma/migrations/0001_init.sql"
# Apply to remote database
bun x wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --remote --file="./prisma/migrations/0001_init.sql"
```
Replace `__YOUR_D1_DATABASE_NAME__` with the actual name of your D1 database that you created in step 4.
5.4 Add sample data [#54-add-sample-data]
Let's create some dummy data that we can query once the Worker is running:
npm
pnpm
yarn
bun
```bash
# For the local database
npx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('jane@prisma.io', 'Jane Doe (Local)');" --local
# For the remote database
npx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('jane@prisma.io', 'Jane Doe (Remote)');" --remote
```
```bash
# For the local database
pnpm dlx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('jane@prisma.io', 'Jane Doe (Local)');" --local
# For the remote database
pnpm dlx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('jane@prisma.io', 'Jane Doe (Remote)');" --remote
```
```bash
# For the local database
yarn dlx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('jane@prisma.io', 'Jane Doe (Local)');" --local
# For the remote database
yarn dlx wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('jane@prisma.io', 'Jane Doe (Remote)');" --remote
```
```bash
# For the local database
bun x wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('jane@prisma.io', 'Jane Doe (Local)');" --local
# For the remote database
bun x wrangler d1 execute __YOUR_D1_DATABASE_NAME__ --command "INSERT INTO \"User\" (\"email\", \"name\") VALUES ('jane@prisma.io', 'Jane Doe (Remote)');" --remote
```
For future schema changes, you can generate new migration files using:
npm
pnpm
yarn
bun
```bash
npx prisma migrate diff \
--from-local-d1 \
--to-schema prisma/schema.prisma \
--script > migrations/0002_add_new_field.sql
```
```bash
pnpm dlx prisma migrate diff \
--from-local-d1 \
--to-schema prisma/schema.prisma \
--script > migrations/0002_add_new_field.sql
```
```bash
yarn dlx prisma migrate diff \
--from-local-d1 \
--to-schema prisma/schema.prisma \
--script > migrations/0002_add_new_field.sql
```
```bash
bunx --bun prisma migrate diff \
--from-local-d1 \
--to-schema prisma/schema.prisma \
--script > migrations/0002_add_new_field.sql
```
Then apply them using the same `wrangler d1 execute` commands as shown above.
6. Implement the Worker [#6-implement-the-worker]
Before adding a Prisma Client query to your Worker, you need to generate Prisma Client with the following command:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
In order to query your database from the Worker using Prisma ORM, you need to:
1. Add the `DB` binding to the `Env` interface. This `DB` name matches the binding name you configured in `wrangler.jsonc`. (Alternatively, you can run [`npx wrangler types`](https://developers.cloudflare.com/workers/wrangler/commands/#types) to generate the `Env` type from the binding in a separate file called `worker-configuration.d.ts`.)
2. Instantiate `PrismaClient` using the `PrismaD1` driver adapter, passing `env.DB` which accesses your D1 database binding.
3. Send a query using Prisma Client and return the result.
Open `src/index.ts` and replace the entire content with the following:
```typescript title="src/index.ts"
import { PrismaClient } from "./generated/prisma/client";
import { PrismaD1 } from "@prisma/adapter-d1";
export interface Env {
DB: D1Database;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise {
const adapter = new PrismaD1(env.DB);
const prisma = new PrismaClient({ adapter });
const users = await prisma.user.findMany();
const result = JSON.stringify(users);
ctx.waitUntil(prisma.$disconnect()); // or just await prisma.$disconnect()
return new Response(result);
},
};
```
We explicitly call `prisma.$disconnect()` here to guarantee timely release of resources or else the
worker might run out of memory.
7. Run the Worker locally [#7-run-the-worker-locally]
With the database query in place and Prisma Client generated, you can run the Worker locally.
If your Worker needs any environment variables, create a `.dev.vars` file in the root of your project. For this example, we don't need any additional environment variables since the D1 binding is already configured in `wrangler.jsonc`.
Now run the Worker locally:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
Now you can open your browser at [`http://localhost:8787`](http://localhost:8787/) to see the result of the database query:
```js no-copy
[{ id: 1, email: "jane@prisma.io", name: "Jane Doe (Local)" }];
```
8. Deploy the Worker [#8-deploy-the-worker]
To deploy the Worker, run the following command:
npm
pnpm
yarn
bun
```bash
npm run deploy
```
```bash
pnpm run deploy
```
```bash
yarn deploy
```
```bash
bun run deploy
```
Your deployed Worker is accessible via `https://d1-tutorial.USERNAME.workers.dev` (replace `USERNAME` with your Cloudflare account username). If you navigate your browser to that URL, you should see the following data that's queried from your remote D1 database:
```js no-copy
[{ id: 1, email: "jane@prisma.io", name: "Jane Doe (Remote)" }];
```
Next steps [#next-steps]
Now that you've set up Prisma ORM with Cloudflare D1, you can:
* Add more complex queries using Prisma's powerful query API
* Set up Prisma Studio for database management
* Implement database monitoring
* Add automated tests
For more information:
* [Prisma ORM documentation](/orm)
* [Prisma Client API reference](/orm/prisma-client/setup-and-configuration/introduction)
* [Cloudflare D1 documentation](https://developers.cloudflare.com/d1)
# Cloudflare Workers (/docs/guides/deployment/cloudflare-workers)
Introduction [#introduction]
Prisma ORM provides type-safe database access, and [Cloudflare Workers](https://workers.cloudflare.com/) enables you to deploy serverless code at the edge. Together with [Prisma Postgres](https://www.prisma.io/postgres), you get a globally distributed backend with low-latency database access.
In this guide, you'll learn to integrate Prisma ORM with a Prisma Postgres database in a Cloudflare Workers project. You can find a complete example of this guide on [GitHub](https://github.com/prisma/prisma-examples/tree/latest/orm/cloudflare-workers).
Prerequisites [#prerequisites]
* [Node.js 20+](https://nodejs.org)
* A [Cloudflare account](https://dash.cloudflare.com/sign-up/workers-and-pages)
1. Set up your project [#1-set-up-your-project]
Create a new Cloudflare Workers project:
npm
pnpm
yarn
bun
```bash
npm create cloudflare@latest prisma-cloudflare-worker -- --type=hello-world --ts=true --git=true --deploy=false
```
```bash
pnpm create cloudflare prisma-cloudflare-worker --type=hello-world --ts=true --git=true --deploy=false
```
```bash
yarn create cloudflare prisma-cloudflare-worker --type=hello-world --ts=true --git=true --deploy=false
```
```bash
bunx create-cloudflare prisma-cloudflare-worker --type hello-world --ts=true --git=true --deploy=false
```
Navigate into the newly created project directory:
```bash
cd prisma-cloudflare-worker
```
2. Install and configure Prisma [#2-install-and-configure-prisma]
2.1. Install dependencies [#21-install-dependencies]
To get started with Prisma, you'll need to install a few dependencies:
npm
pnpm
yarn
bun
```bash
npm install prisma dotenv-cli @types/pg --save-dev
```
```bash
pnpm add prisma dotenv-cli @types/pg --save-dev
```
```bash
yarn add prisma dotenv-cli @types/pg --dev
```
```bash
bun add prisma dotenv-cli @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
bun add @prisma/client @prisma/adapter-pg dotenv pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Once installed, initialize Prisma in your project:
npm
pnpm
yarn
bun
```bash
npx prisma init --db
```
```bash
pnpm dlx prisma init --db
```
```bash
yarn dlx prisma init --db
```
```bash
bunx --bun prisma init --db
```
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My Cloudflare Workers Project"
This will create:
* A `prisma/` directory with a `schema.prisma` file
* A `prisma.config.ts` file with your Prisma configuration
* A `.env` file with a `DATABASE_URL` already set
2.2. Enable Node.js compatibility in Cloudflare Workers [#22-enable-nodejs-compatibility-in-cloudflare-workers]
Cloudflare Workers needs Node.js compatibility enabled to work with Prisma. Add the `nodejs_compat` compatibility flag to your `wrangler.jsonc`:
```json title="wrangler.jsonc"
{
"name": "prisma-cloudflare-worker",
"main": "src/index.ts",
"compatibility_flags": ["nodejs_compat"], // [!code ++]
"compatibility_date": "2024-01-01"
}
```
2.3. Define your Prisma Schema [#23-define-your-prisma-schema]
In the `prisma/schema.prisma` file, add the following `User` model and set the runtime to `cloudflare`:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
runtime = "cloudflare" // [!code ++]
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String // [!code ++]
name String // [!code ++]
} // [!code ++]
```
Both the `cloudflare` and `workerd` runtimes are supported. Read more about runtimes [here](/orm/prisma-schema/overview/generators#field-reference).
This creates a `User` model with an auto-incrementing ID, email, and name.
2.4. Configure Prisma scripts [#24-configure-prisma-scripts]
Add the following scripts to your `package.json` to work with Prisma in the Cloudflare Workers environment:
```json title="package.json"
{
"scripts": {
"migrate": "prisma migrate dev", // [!code ++]
"generate": "prisma generate", // [!code ++]
"studio": "prisma studio" // [!code ++]
// ... existing scripts
}
}
```
2.5. Run migrations and generate Prisma Client [#25-run-migrations-and-generate-prisma-client]
Now, run the following command to create the database tables:
npm
pnpm
yarn
bun
```bash
npm run migrate
```
```bash
pnpm run migrate
```
```bash
yarn migrate
```
```bash
bun run migrate
```
When prompted, name your migration (e.g., `init`).
Then generate the Prisma Client:
npm
pnpm
yarn
bun
```bash
npm run generate
```
```bash
pnpm run generate
```
```bash
yarn generate
```
```bash
bun run generate
```
This generates the Prisma Client in the `src/generated/prisma/client` directory.
3. Integrate Prisma into Cloudflare Workers [#3-integrate-prisma-into-cloudflare-workers]
3.1. Import Prisma Client and configure types [#31-import-prisma-client-and-configure-types]
At the top of `src/index.ts`, import the generated Prisma Client and the PostgreSQL adapter, and define the `Env` interface for type-safe environment variables:
```typescript title="src/index.ts"
import { PrismaClient } from "./generated/prisma/client"; // [!code ++]
import { PrismaPg } from "@prisma/adapter-pg"; // [!code ++]
// [!code ++]
export interface Env {
// [!code ++]
DATABASE_URL: string; // [!code ++]
} // [!code ++]
export default {
async fetch(request, env, ctx): Promise {
return new Response("Hello World!");
},
} satisfies ExportedHandler;
```
3.2. Handle favicon requests [#32-handle-favicon-requests]
Add a check to filter out favicon requests, which browsers automatically send and can clutter your logs:
```typescript title="src/index.ts"
import { PrismaClient } from "./generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
export interface Env {
DATABASE_URL: string;
}
export default {
async fetch(request, env, ctx): Promise {
const path = new URL(request.url).pathname; // [!code ++]
if (path === "/favicon.ico")
// [!code ++]
return new Response("Resource not found", {
// [!code ++]
status: 404, // [!code ++]
headers: {
// [!code ++]
"Content-Type": "text/plain", // [!code ++]
}, // [!code ++]
}); // [!code ++]
return new Response("Hello World!");
},
} satisfies ExportedHandler;
```
3.3. Initialize the Prisma Client [#33-initialize-the-prisma-client]
Create a database adapter and initialize Prisma Client with it. This must be done for each request in edge environments:
```typescript title="src/index.ts"
import { PrismaClient } from "./generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
export interface Env {
DATABASE_URL: string;
}
export default {
async fetch(request, env, ctx): Promise {
const path = new URL(request.url).pathname;
if (path === "/favicon.ico")
return new Response("Resource not found", {
status: 404,
headers: {
"Content-Type": "text/plain",
},
});
const adapter = new PrismaPg({
// [!code ++]
connectionString: env.DATABASE_URL, // [!code ++]
}); // [!code ++]
// [!code ++]
const prisma = new PrismaClient({
// [!code ++]
adapter, // [!code ++]
}); // [!code ++]
return new Response("Hello World!");
},
} satisfies ExportedHandler;
```
In edge environments like Cloudflare Workers, you create a new Prisma Client instance per request. This is different from long-running Node.js servers where you typically instantiate a single client and reuse it.
3.4. Create a user and query the database [#34-create-a-user-and-query-the-database]
Now use Prisma Client to create a new user and count the total number of users:
```typescript title="src/index.ts"
import { PrismaClient } from "./generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
export interface Env {
DATABASE_URL: string;
}
export default {
async fetch(request, env, ctx): Promise {
const path = new URL(request.url).pathname;
if (path === "/favicon.ico")
return new Response("Resource not found", {
status: 404,
headers: {
"Content-Type": "text/plain",
},
});
const adapter = new PrismaPg({
connectionString: env.DATABASE_URL,
});
const prisma = new PrismaClient({
adapter,
});
const user = await prisma.user.create({
// [!code ++]
data: {
// [!code ++]
email: `Prisma-Postgres-User-${Math.ceil(Math.random() * 1000)}@gmail.com`, // [!code ++]
name: "Jon Doe", // [!code ++]
}, // [!code ++]
}); // [!code ++]
// [!code ++]
const userCount = await prisma.user.count(); // [!code ++]
return new Response("Hello World!");
},
} satisfies ExportedHandler;
```
3.5. Return the results [#35-return-the-results]
Finally, update the response to display the newly created user and the total user count:
```typescript title="src/index.ts"
import { PrismaClient } from "./generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
export interface Env {
DATABASE_URL: string;
}
export default {
async fetch(request, env, ctx): Promise {
const path = new URL(request.url).pathname;
if (path === "/favicon.ico")
return new Response("Resource not found", {
status: 404,
headers: {
"Content-Type": "text/plain",
},
});
const adapter = new PrismaPg({
connectionString: env.DATABASE_URL,
});
const prisma = new PrismaClient({
adapter,
});
const user = await prisma.user.create({
data: {
email: `Prisma-Postgres-User-${Math.ceil(Math.random() * 1000)}@gmail.com`,
name: "Jon Doe",
},
});
const userCount = await prisma.user.count();
return new Response(`\ // [!code highlight]
Created new user: ${user.name} (${user.email}). // [!code highlight]
Number of users in the database: ${userCount}. // [!code highlight]
`); // [!code highlight]
},
} satisfies ExportedHandler;
```
3.6. Test your Worker locally [#36-test-your-worker-locally]
First, generate the TypeScript types for your Worker environment:
npm
pnpm
yarn
bun
```bash
npx wrangler types --no-strict-vars
```
```bash
pnpm dlx wrangler types --no-strict-vars
```
```bash
yarn dlx wrangler types --no-strict-vars
```
```bash
bunx --bun wrangler types --no-strict-vars
```
Then start the development server:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
Open [`http://localhost:8787`](http://localhost:8787) in your browser. Each time you refresh the page, a new user will be created. You should see output similar to:
```
Created new user: Jon Doe (Prisma-Postgres-User-742@gmail.com).
Number of users in the database: 5.
```
3.7. Inspect your data with Prisma Studio [#37-inspect-your-data-with-prisma-studio]
To view your database contents, open Prisma Studio:
npm
pnpm
yarn
bun
```bash
npm run studio
```
```bash
pnpm run studio
```
```bash
yarn studio
```
```bash
bun run studio
```
This will open a browser window where you can view and edit your `User` table data.
4. Deploy to Cloudflare Workers [#4-deploy-to-cloudflare-workers]
4.1. Set your database URL as a secret [#41-set-your-database-url-as-a-secret]
Before deploying, you need to set your `DATABASE_URL` as a secret in Cloudflare Workers. This keeps your database connection string secure in production.
npm
pnpm
yarn
bun
```bash
npx wrangler secret put DATABASE_URL
```
```bash
pnpm dlx wrangler secret put DATABASE_URL
```
```bash
yarn dlx wrangler secret put DATABASE_URL
```
```bash
bunx --bun wrangler secret put DATABASE_URL
```
When prompted, paste your database connection string from the `.env` file.
4.2. Deploy your Worker [#42-deploy-your-worker]
Deploy your Worker to Cloudflare:
npm
pnpm
yarn
bun
```bash
npm run deploy
```
```bash
pnpm run deploy
```
```bash
yarn deploy
```
```bash
bun run deploy
```
Once deployed, Cloudflare will provide you with a URL where your Worker is live (e.g., `https://prisma-postgres-worker.your-subdomain.workers.dev`).
Visit the URL in your browser, and you'll see your Worker creating users in production!
Summary [#summary]
You've successfully created a Cloudflare Workers application with Prisma ORM connected to a Prisma Postgres database. Your Worker is now running at the edge with low-latency database access.
Next steps [#next-steps]
Now that you have a working Cloudflare Workers app connected to a Prisma Postgres database, you can:
* Add routes to handle different HTTP methods (GET, POST, PUT, DELETE)
* Extend your Prisma schema with more models and relationships
* Implement authentication and authorization
* Use [Hono](https://hono.dev/) for a more robust routing framework with Cloudflare Workers (see our [Hono guide](/guides/frameworks/hono))
More info [#more-info]
* [Prisma Documentation](/orm)
* [Cloudflare Workers Documentation](https://developers.cloudflare.com/workers/)
* [Deploy to Cloudflare](/orm/prisma-client/deployment/edge/deploy-to-cloudflare)
# Docker (/docs/guides/deployment/docker)
This guide walks you through setting up a Prisma ORM application within a Docker environment. You'll learn how to configure a Node.js project, integrate Prisma for database management, and orchestrate the application using Docker Compose. By the end, you'll have a fully functional Prisma application running in a Docker container.
Prerequisites [#prerequisites]
* [Docker](https://docs.docker.com/) and [Docker Compose](https://docs.docker.com/compose/) installed
* Node.js version: A [compatible Node.js version](/guides/upgrade-prisma-orm/v6#minimum-supported-nodejs-versions), required for Prisma 6.
See our [system requirements](/orm/reference/system-requirements) for all minimum version requirements.
Before starting, ensure that no PostgreSQL services are running locally, and that the following ports are free to avoid conflicts: `5432` (PostgreSQL), `3000` (application server) or `5555` (Prisma Studio server).
To stop existing PostgreSQL services, use:
```bash
sudo systemctl stop postgresql # Linux
brew services stop postgresql # macOS
net stop postgresql # Windows (Run as Administrator)
```
To stop all running Docker containers and free up ports:
```bash
docker ps -q | xargs docker stop
```
1. Set up your Node.js and Prisma application [#1-set-up-your-nodejs-and-prisma-application]
Let's start by creating a simple Node.js application with Prisma ORM and [Express.js](https://expressjs.com/).
1.1. Initialize your project [#11-initialize-your-project]
First, create a new project directory and initialize a Node.js project:
npm
pnpm
yarn
bun
```bash
mkdir docker-test
cd docker-test
npm init -y
```
```bash
mkdir docker-test
cd docker-test
pnpm init -y
```
```bash
mkdir docker-test
cd docker-test
yarn init -y
```
```bash
mkdir docker-test
cd docker-test
bun init -y
```
This will generate a `package.json` file:
```json title="package.json"
{
"name": "docker-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {},
"keywords": [],
"author": "",
"license": "ISC"
}
```
1.2. Install required dependencies [#12-install-required-dependencies]
Next, install the Prisma CLI as a development dependency and Express.js for the server:
npm
pnpm
yarn
bun
```bash
npm install prisma @types/pg --save-dev
```
```bash
pnpm add prisma @types/pg --save-dev
```
```bash
yarn add prisma @types/pg --dev
```
```bash
bun add prisma @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg pg dotenv express
```
```bash
pnpm add @prisma/client @prisma/adapter-pg pg dotenv express
```
```bash
yarn add @prisma/client @prisma/adapter-pg pg dotenv express
```
```bash
bun add @prisma/client @prisma/adapter-pg pg dotenv express
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
1.3. Set up Prisma ORM [#13-set-up-prisma-orm]
Now, initialize Prisma to generate the necessary files:
npm
pnpm
yarn
bun
```bash
npx prisma init --output ../generated/prisma
```
```bash
pnpm dlx prisma init --output ../generated/prisma
```
```bash
yarn dlx prisma init --output ../generated/prisma
```
```bash
bunx --bun prisma init --output ../generated/prisma
```
This creates:
* A `prisma` folder containing `schema.prisma`, where you will define your database schema.
* An `.env` file in the project root, which stores environment variables.
Add a `User` model to the `schema.prisma` file located in the `prisma/schema.prisma` folder:
```prisma title="prisma/schema.prisma"
datasource db {
provider = "postgresql"
}
generator client {
provider = "prisma-client"
output = "../generated/prisma_client" // [!code ++]
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
createdAt DateTime @default(now()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
} // [!code ++]
```
In the `schema.prisma` file, we specify a [custom `output` path](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider) where Prisma will generate its types. This ensures Prisma's types are resolved correctly across different package managers and can be accessed by application consistently inside the container without any permission issues. In this guide, the types will be generated in the `./generated/prisma_client` directory.
Now, create a `prisma.config.ts` file in the root of your project:
```typescript title="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"),
},
});
```
You'll need to install the `dotenv` package to load environment variables:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
1.4. Create an Express.js server [#14-create-an-expressjs-server]
With the Prisma schema in place, let's create an Express.js server to interact with the database. Start by creating an `index.js` file:
```bash
touch index.js
```
Add the following code to set up a basic Express server:
```js title="index.js"
const express = require("express"); // [!code ++]
const { PrismaClient } = require("./generated/prisma_client/client"); // [!code ++]
const { PrismaPg } = require("@prisma/adapter-pg"); // [!code ++]
// [!code ++]
const adapter = new PrismaPg({
// [!code ++]
connectionString: process.env.DATABASE_URL, // [!code ++]
}); // [!code ++]
// [!code ++]
const app = express(); // [!code ++]
const prisma = new PrismaClient({
// [!code ++]
adapter, // [!code ++]
}); // [!code ++]
app.use(express.json()); // [!code ++]
// [!code ++]
// Get all users // [!code ++]
app.get("/", async (req, res) => {
// [!code ++]
const userCount = await prisma.user.count(); // [!code ++]
res.json(
// [!code ++]
userCount == 0 // [!code ++]
? "No users have been added yet." // [!code ++]
: "Some users have been added to the database.", // [!code ++]
); // [!code ++]
}); // [!code ++]
// [!code ++]
const PORT = 3000; // [!code ++]
// [!code ++]
app.listen(PORT, () => {
// [!code ++]
console.log(`Server is running on http://localhost:${PORT}`); // [!code ++]
}); // [!code ++]
```
Update the `package.json` scripts to include commands for running the server and deploying migrations:
```json title="package.json"
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1", // [!code --]
"dev": "node index.js", // [!code ++]
"db:deploy": "npx prisma migrate deploy && npx prisma generate" // [!code ++]
}
```
Now that the application is set up, let's move on to configuring a PostgreSQL database using Docker Compose.
2. Set up a PostgreSQL database with Docker Compose [#2-set-up-a-postgresql-database-with-docker-compose]
To perform database migrations, we'll create a standalone PostgreSQL database using Docker Compose.
2.1. Create a Docker Compose file for PostgreSQL [#21-create-a-docker-compose-file-for-postgresql]
Create a `docker-compose.postgres.yml` file in the root directory:
```yml title="docker-compose.postgres.yml"
version: '3.7' // [!code ++]
// [!code ++]
services: // [!code ++]
postgres: // [!code ++]
image: postgres:15 // [!code ++]
restart: always // [!code ++]
environment: // [!code ++]
- POSTGRES_DB=postgres // [!code ++]
- POSTGRES_USER=postgres // [!code ++]
- POSTGRES_PASSWORD=prisma // [!code ++]
ports: // [!code ++]
- "5432:5432" // [!code ++]
networks: // [!code ++]
- prisma-network // [!code ++]
healthcheck: // [!code ++]
test: ["CMD-SHELL", "pg_isready -U prisma -d postgres"] // [!code ++]
interval: 5s // [!code ++]
timeout: 2s // [!code ++]
retries: 20 // [!code ++]
volumes: // [!code ++]
- postgres_data:/var/lib/postgresql/data // [!code ++]
command: postgres -c listen_addresses='*' // [!code ++]
logging: // [!code ++]
options: // [!code ++]
max-size: "10m" // [!code ++]
max-file: "3" // [!code ++]
// [!code ++]
networks: // [!code ++]
prisma-network: // [!code ++]
// [!code ++]
volumes: // [!code ++]
postgres_data: // [!code ++]
```
2.2. Start the PostgreSQL container [#22-start-the-postgresql-container]
Run the following command to start the database:
```bash
docker compose -f docker-compose.postgres.yml up -d
```
2.3. Perform database migrations [#23-perform-database-migrations]
With the database running, update the `.env` file with the following database connection url:
```bash title=".env"
DATABASE_URL="postgresql://postgres:prisma@localhost:5432/postgres?schema=public" # [!code highlight]
```
Run the migration to create the database schema:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
Then generate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
This should generate a `migrations` folder in the `prisma` folder and the Prisma Client in the `generated/prisma_client` directory.
2.4. Test the application [#24-test-the-application]
Start the server and verify it works:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
Visit [`http://localhost:3000`](http://localhost:3000) to see the message:
```bash
No users have been added yet.
```
Stop the local server.
2.5. Clean up the standalone database [#25-clean-up-the-standalone-database]
Once testing is complete, remove the standalone PostgreSQL container:
```bash
docker compose -f docker-compose.postgres.yml down --remove-orphans
```
This command will:
* Stop running containers.
* Remove containers.
* Remove the default network created by Docker Compose.
* Remove associated volumes (if not named explicitly).
Now that we've tested the application locally, let's containerize it using Docker.
3. Run the app and database together with Docker Compose [#3-run-the-app-and-database-together-with-docker-compose]
We'll now containerize the application using Docker, ensuring it can run in any environment.
To do that create a `Dockerfile` in project root:
```bash
touch Dockerfile
```
For the next step, you'll need to choose between two options for the base image: `node:alpine` (lightweight) or `node:slim` (stable). Both options are fully supported by Prisma ORM, but may have to be configured differently.
3.1. Option 1: Use Linux Alpine (node:alpine) as a base image [#31-option-1-use-linux-alpine-nodealpine-as-a-base-image]
The `node:alpine` image is based on Alpine Linux, a lightweight Linux distribution that uses the `musl` C standard library. It's perfect if you want to keep your container small and efficient. Prisma supports Alpine on `amd64` out of the box, and supports it on `arm64` since `prisma@4.10.0`.
Add the following content to the `Dockerfile`:
```shell title="Dockerfile"
FROM node:lts-alpine3.17
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
CMD ["sh", "-c", "npm run db:deploy && npm run dev"]
```
When running on Linux Alpine, Prisma downloads engines that are compiled for the `musl` C standard library. Please don't install `glibc` on Alpine (e.g., via the `libc6-compat` package), as that would prevent Prisma from running successfully.
Related Docker images:
* `node:lts-alpine`
* `node:16-alpine`
* `node:14-alpine`
3.1. Option 2: Use Linux Debian (node:slim) as a base image [#31-option-2-use-linux-debian-nodeslim-as-a-base-image]
The `node:slim` image is based on Linux Debian, a stable and widely supported distribution that uses the `glibc` C standard library. It is mostly supported out of the box on `amd64` and `arm64`, making it a good choice if you're running into compatibility issues with Alpine or need a more production-ready environment. However, some older versions of this image may come without `libssl` installed, so it's sometimes necessary to install it manually.
Add the following content to the `Dockerfile`:
```shell title="Dockerfile"
FROM node:slim
RUN apt-get update -y \
&& apt-get install -y openssl
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
CMD ["sh", "-c", "npm run db:deploy && npm run dev"]
```
Related Docker images:
* `node:lts-slim`
* `node:bullseye-slim`
* `node:buster-slim`
* `node:stretch-slim`
3.2. Create and configure a Docker Compose file [#32-create-and-configure-a-docker-compose-file]
Now that the `Dockerfile` is ready, we'll use Docker Compose to manage both the app and the database together. This makes it easy to start, stop, and manage the entire setup.
Create a `docker-compose.yml` file in your project folder:
```bash
touch docker-compose.yml
```
Add the following configuration to the file:
```yml title="docker-compose.yml"
version: '3.7' // [!code ++]
// [!code ++]
services: // [!code ++]
postgres_db: // [!code ++]
image: postgres:15 // [!code ++]
hostname: postgres_db // [!code ++]
container_name: postgres_db // [!code ++]
restart: always // [!code ++]
environment: // [!code ++]
POSTGRES_DB: postgres // [!code ++]
POSTGRES_USER: postgres // [!code ++]
POSTGRES_PASSWORD: prisma // [!code ++]
ports: // [!code ++]
- '5432:5432' // [!code ++]
networks: // [!code ++]
- prisma-network // [!code ++]
healthcheck: // [!code ++]
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"] // [!code ++]
interval: 5s // [!code ++]
timeout: 2s // [!code ++]
retries: 20 // [!code ++]
// [!code ++]
server: // [!code ++]
build: // [!code ++]
context: . // [!code ++]
dockerfile: Dockerfile // [!code ++]
ports: // [!code ++]
- '3000:3000' // [!code ++]
stdin_open: true // [!code ++]
tty: true # Keeps the container running for debugging // [!code ++]
depends_on: // [!code ++]
postgres_db: // [!code ++]
condition: service_healthy // [!code ++]
env_file: // [!code ++]
- .env.prod // [!code ++]
networks: // [!code ++]
- prisma-network // [!code ++]
networks: // [!code ++]
prisma-network: // [!code ++]
name: prisma-network // [!code ++]
```
3.3. Configure environment variable for the container [#33-configure-environment-variable-for-the-container]
Before running the app, we need to configure the environment variables. Create a `.env.prod` file:
```
touch .env.prod
```
Add the following database connection url to the `.env.prod` file:
```bash title=".env.prod"
DATABASE_URL="postgresql://postgres:prisma@postgres_db:5432/postgres?schema=public" # [!code highlight]
```
3.4. Build and run the application [#34-build-and-run-the-application]
With everything set up, it's time to build and run the app using Docker Compose. Run the following command:
```bash
docker compose -f docker-compose.yml up --build -d
```
Visit `http://localhost:3000` to see your app running with the message:
```bash
No users have been added yet.
```
3.5. Bonus: Add Prisma Studio for database management [#35-bonus-add-prisma-studio-for-database-management]
[Prisma Studio](/studio) offers a graphical user interface (GUI) that allows you to view and manage your database directly in the browser. It's a great tool for debugging and managing your data during development.
To add Prisma Studio to your Docker setup, update the `docker-compose.yml` file:
```yml title="docker.compose.yml"
version: '3.7'
services:
postgres_db:
image: postgres:15
hostname: postgres_db
container_name: postgres_db
restart: always
environment:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: prisma
ports:
- '5432:5432'
networks:
- prisma-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
interval: 5s
timeout: 2s
retries: 20
server:
build:
context: .
dockerfile: Dockerfile
ports:
- '3000:3000'
stdin_open: true
tty: true # Keeps the container running for debugging
depends_on:
postgres_db:
condition: service_healthy
env_file:
- .env.prod
networks:
- prisma-network
prisma-studio: // [!code ++]
image: node:lts-alpine3.17 // [!code ++]
working_dir: /usr/src/app // [!code ++]
volumes: // [!code ++]
- .:/usr/src/app // [!code ++]
command: npx prisma studio --port 5555 --browser none // [!code ++]
ports: // [!code ++]
- "5555:5555" // [!code ++]
env_file: // [!code ++]
- .env.prod // [!code ++]
networks: // [!code ++]
- prisma-network // [!code ++]
depends_on: // [!code ++]
postgres_db: // [!code ++]
condition: service_healthy // [!code ++]
server: // [!code ++]
condition: service_started // [!code ++]
networks:
prisma-network:
name: prisma-network
```
This will start Prisma Studio at [`http://localhost:5555`](http://localhost:5555) alongside the main app at [`http://localhost:3000`](http://localhost:3000). You can use Prisma Studio to manage your database with a GUI.
Run the following command to start everything:
```bash
docker compose -f docker-compose.yml up --build -d
```
By following this guide, you've successfully containerized your Prisma app and database using Docker Compose.
# pnpm workspaces (/docs/guides/deployment/pnpm-workspaces)
Prisma is a powerful ORM for managing your database, and when combined with [pnpm Workspaces](https://pnpm.io/workspaces), you can maintain a lean and modular monorepo architecture. In this guide, we’ll walk through setting up Prisma in its own package within a pnpm Workspaces monorepo, enabling maintainable type sharing and efficient database management across your apps.
What you'll learn: [#what-youll-learn]
* How to initialize a monorepo using pnpm Workspaces.
* Steps to integrate Prisma as a standalone package.
* How to generate and share the Prisma Client across packages.
* Integrating the Prisma package into an application within your workspace.
1. Prepare your project and configure pnpm workspaces [#1-prepare-your-project-and-configure-pnpm-workspaces]
Before integrating Prisma, you need to set up your project structure. Start by creating a new directory for your project (for example, `my-monorepo`) and initialize a Node.js project:
```bash
mkdir my-monorepo
cd my-monorepo
pnpm init
```
Next, create a `pnpm-workspace.yaml` file to define your workspace structure and pin the Prisma version:
```bash
touch pnpm-workspace.yaml
```
Add the following configuration to `pnpm-workspace.yaml`:
```yaml title="pnpm-workspace.yaml"
packages:
- "apps/*"
- "packages/*"
catalogs:
prisma:
prisma: latest
```
The `catalogs` help you pin a certain version of prisma across your repositories. You can learn more about them [here](https://pnpm.io/catalogs). *Explicitly* pin the latest version of [prisma](https://www.npmjs.com/package/prisma) in the `pnpm-workspace.yaml` file. At the time of writing, this is version `6.3.1`.
Finally, create directories for your applications and shared packages:
```bash
mkdir apps
mkdir -p packages/database
```
2. Setup the shared database package [#2-setup-the-shared-database-package]
This section covers creating a standalone database package that uses Prisma. The package will house all database models and the generated Prisma Client, making it reusable across your monorepo.
2.1. Initialize the package and install dependencies [#21-initialize-the-package-and-install-dependencies]
Navigate to the `packages/database` directory and initialize a new package:
```bash
cd packages/database
pnpm init
```
Add Prisma as a development dependency in your `package.json` using the pinned `catalog`:
```json title="database/package.json"
"devDependencies": { // [!code ++]
"prisma": "catalog:prisma" // [!code ++]
} // [!code ++]
```
Then install Prisma:
```bash
pnpm install
```
Then, add additional dependencies:
```bash
pnpm add typescript tsx @types/node @types/pg -D
pnpm add @prisma/adapter-pg pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Initialize a `tsconfig.json` file for your `database` package:
```bash
pnpm tsc --init
```
2.2. Setup Prisma ORM in your database package [#22-setup-prisma-orm-in-your-database-package]
Initialize Prisma ORM with an instance of [Prisma Postgres](/postgres) in the `database` package by running the following command:
```bash
pnpm prisma init --db
```
Enter a name for your project and choose a database region.
We're going to be using [Prisma Postgres](/postgres) in this guide. If you're not using a Prisma Postgres database, you won't need to add the `--db` flag.
This command:
* Connects your CLI to your [Prisma Data Platform](https://console.prisma.io) account. If you're not logged in or don't have an account, your browser will open to guide you through creating a new account or signing into your existing one.
* Creates a `prisma` directory containing a `schema.prisma` file for your database models.
* Creates a `.env` file with your `DATABASE_URL` (e.g., for Prisma Postgres it should have something similar to `DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=eyJhbGciOiJIUzI..."`).
Edit the `schema.prisma` file to define a `User` model in your database and specify a [custom `output` directory](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider) to generate the Prisma Client. This ensures that generated types are resolved correctly:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/client" // [!code ++]
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
} // [!code ++]
```
Now, create a `prisma.config.ts` file in the `database` package to configure Prisma:
```typescript title="database/prisma.config.ts"
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config"; // [!code ++]
// [!code ++]
export default defineConfig({
// [!code ++]
schema: "prisma/schema.prisma", // [!code ++]
migrations: {
// [!code ++]
path: "prisma/migrations", // [!code ++]
}, // [!code ++]
datasource: {
// [!code ++]
url: env("DATABASE_URL"), // [!code ++]
}, // [!code ++]
}); // [!code ++]
```
You'll need to install the `dotenv` package to load environment variables from the `.env` file:
```bash
pnpm add dotenv
```
Next, add helper scripts to your `package.json` to simplify Prisma commands:
```json title="database/package.json"
{
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1", // [!code --]
"db:generate": "prisma generate", // [!code ++]
"db:migrate": "prisma migrate dev", // [!code ++]
"db:deploy": "prisma migrate deploy", // [!code ++]
"db:studio": "prisma studio" // [!code ++]
}
}
```
Use [Prisma Migrate](/orm/prisma-migrate) to migrate your database changes:
```bash
pnpm run db:migrate
```
When prompted by the CLI, enter a descriptive name for your migration.
Once the migration is successful, create a `client.ts` file to initialize Prisma Client with a driver adapter:
```ts title="database/client.ts"
import { PrismaClient } from "./generated/client"; // [!code ++]
import { PrismaPg } from "@prisma/adapter-pg"; // [!code ++]
// [!code ++]
const adapter = new PrismaPg({
// [!code ++]
connectionString: process.env.DATABASE_URL, // [!code ++]
}); // [!code ++]
// [!code ++]
// Use globalThis for broader environment compatibility // [!code ++]
const globalForPrisma = globalThis as typeof globalThis & {
// [!code ++]
prisma?: PrismaClient; // [!code ++]
}; // [!code ++]
// [!code ++]
// Named export with global memoization // [!code ++]
export const prisma: PrismaClient = // [!code ++]
globalForPrisma.prisma ??
new PrismaClient({
// [!code ++]
adapter, // [!code ++]
}); // [!code ++]
// [!code ++]
if (process.env.NODE_ENV !== "production") {
// [!code ++]
globalForPrisma.prisma = prisma; // [!code ++]
} // [!code ++]
```
Then, create an `index.ts` file to re-export the instance of Prisma Client and all generated types:
```ts title="database/index.ts"
export { prisma } from "./client"; // [!code ++]
export * from "./generated/client"; // [!code ++]
```
At this point, your shared database package is fully configured and ready for use across your monorepo.
3. Set up and integrate your frontend application [#3-set-up-and-integrate-your-frontend-application]
Now that the database package is set up, create a frontend application (using Next.js) that uses the shared Prisma Client to interact with your database.
3.1. Bootstrap a Next.js application [#31-bootstrap-a-nextjs-application]
Navigate to the `apps` directory:
```bash
cd ../../apps
```
Create a new Next.js app named `web`:
```bash
pnpm create next-app@latest web --yes
```
important
The `--yes` flag uses default configurations to bootstrap the Next.js app (which in this guide uses the app router without a `src/` directory and `pnpm` as the installer).
Additionally, the flag may automatically initialize a Git repository in the `web` folder. If that happens, please remove the `.git` directory by running `rm -r .git`.
Then, navigate into the web directory:
```bash
cd web/
```
Copy the `.env` file from the database package to ensure the same environment variables are available:
```bash
cp ../../packages/database/.env .
```
Open the `package.json` file of your Next.js app and add the shared `database` package as a dependency:
```json title="web/package.json"
"dependencies": {
"database": "workspace:*", // [!code ++]
// additional dependencies
// ...
}
```
Run the following command to install the `database` package:
```bash
pnpm install
```
3.2. Integrate the shared database package in your app code [#32-integrate-the-shared-database-package-in-your-app-code]
Modify your Next.js application code to use Prisma Client from the database package. Update `app/page.tsx` as follows:
```tsx title="app/page.tsx"
import { prisma } from "database"; // [!code ++]
// [!code ++]
export default async function Home() {
// [!code ++]
const user = await prisma.user.findFirst({
// [!code ++]
select: {
// [!code ++]
name: true, // [!code ++]
}, // [!code ++]
}); // [!code ++]
// [!code ++]
return (
// [!code ++]
{" "}
// [!code ++]
{user?.name &&
Hello from {user.name}
} // [!code ++]
{!user?.name &&
No user has been added to the database yet.
} // [!code ++]
// [!code ++]
); // [!code ++]
} // [!code ++]
```
This code demonstrates importing and using the shared Prisma Client to query your `User` model.
3.3. Add helper scripts and run your application [#33-add-helper-scripts-and-run-your-application]
Add the following scripts to the root `package.json` of your monorepo. They ensure that database migrations, type generation, and app builds run in the proper order:
```json
"scripts": {
"build": "pnpm --filter database db:deploy && pnpm --filter database db:generate && pnpm --filter web build", // [!code ++]
"start": "pnpm --filter web start", // [!code ++]
"dev": "pnpm --filter database db:generate && pnpm --filter web dev", // [!code ++]
"studio": "pnpm --filter database db:studio" // [!code ++]
}
```
3.4. Run your application [#34-run-your-application]
Then head back to the root of the monorepo:
```bash
cd ../../
```
Start your development server by executing:
```bash
pnpm run dev
```
Open your browser at [`http://localhost:3000`](http://localhost:3000) to see your app in action.
3.5. (Optional) Add data to your database using Prisma Studio [#35-optional-add-data-to-your-database-using-prisma-studio]
There shouldn't be data in your database yet. You can execute `pnpm run studio` in your CLI to start a [Prisma Studio](/studio) in [`http://localhost:5555`](http://localhost:5555) to interact with your database and add data to it.
Next Steps [#next-steps]
You have now created a monorepo that uses Prisma ORM effectively, with a shared database package integrated into a Next.js application.
For further exploration and to enhance your setup, consider reading the [How to use Prisma ORM with Turborepo](/guides/deployment/turborepo) guide.
# Turborepo (/docs/guides/deployment/turborepo)
Prisma is a powerful ORM for managing databases, and [Turborepo](https://turborepo.dev/docs) simplifies monorepo workflows. By combining these tools, you can create a scalable, modular architecture for your projects.
This guide will show you how to set up Prisma as a standalone package in a Turborepo monorepo, enabling efficient configuration, type sharing, and database management across multiple apps.
What you'll learn: [#what-youll-learn]
* How to set up Prisma in a Turborepo monorepo.
* Steps to generate and reuse PrismaClient across packages.
* Integrating the Prisma package into other applications in the monorepo.
Prerequisites [#prerequisites]
* [Node.js 20.19.0+](https://nodejs.org/)
* [TypeScript 5.4.0+](https://www.typescriptlang.org/)
1. Set up your project [#1-set-up-your-project]
To set up a Turborepo monorepo named `turborepo-prisma`, run the following command:
npm
pnpm
yarn
bun
```bash
npx create-turbo@latest turborepo-prisma
```
```bash
pnpm dlx create-turbo@latest turborepo-prisma
```
```bash
yarn dlx create-turbo@latest turborepo-prisma
```
```bash
bunx --bun create-turbo@latest turborepo-prisma
```
You'll be prompted to select your package manager, this guide will use `npm`:
* *Which package manager do you want to use?* `npm`
After the setup, navigate to the project root directory:
```bash
cd turborepo-prisma
```
2. Add a new database package to the monorepo [#2-add-a-new-database-package-to-the-monorepo]
2.1 Create the package and install Prisma [#21-create-the-package-and-install-prisma]
Create a `database` directory inside `packages` and navigate into it:
```bash
mkdir -p packages/database
cd packages/database
```
Then initialize it with a `package.json`:
```json title="packages/database/package.json"
{
"name": "@repo/db",
"version": "0.0.0"
}
```
Then install the required Prisma ORM dependencies:
npm
pnpm
yarn
bun
```bash
npm install prisma --save-dev
npm install @prisma/client @prisma/adapter-pg pg dotenv
```
```bash
pnpm add prisma --save-dev
pnpm add @prisma/client @prisma/adapter-pg pg dotenv
```
```bash
yarn add prisma --dev
yarn add @prisma/client @prisma/adapter-pg pg dotenv
```
```bash
bun add prisma --dev
bun add @prisma/client @prisma/adapter-pg pg dotenv
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
2.2. Initialize Prisma and define models [#22-initialize-prisma-and-define-models]
Inside the `database` directory, initialize Prisma by running:
npm
pnpm
yarn
bun
```bash
npx prisma init --db
```
```bash
pnpm dlx prisma init --db
```
```bash
yarn dlx prisma init --db
```
```bash
bunx --bun prisma init --db
```
You'll be prompted to authenticate in Prisma Console, choose a project name, and pick a region for your Prisma Postgres database.
This will create several files inside `packages/database`:
* A `prisma` directory with a `schema.prisma` file.
* A `prisma.config.ts` file for configuring Prisma.
* A Prisma Postgres database.
* A `.env` file containing the `DATABASE_URL` in the `packages/database` directory.
In the `packages/database/prisma/schema.prisma` file, add the following models:
```prisma title="packages/database/prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
posts Post[] // [!code ++]
} // [!code ++]
// [!code ++]
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
published Boolean @default(false) // [!code ++]
authorId Int // [!code ++]
author User @relation(fields: [authorId], references: [id]) // [!code ++]
} // [!code ++]
```
The `prisma.config.ts` file created in the `packages/database` directory should look like this:
```typescript title="packages/database/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"),
},
});
```
It is recommended to add `packages/database/generated` to your root `.gitignore` because generated Prisma Client code is a build artifact that can be recreated with `db:generate`.
The importance of generating Prisma types in a custom directory [#the-importance-of-generating-prisma-types-in-a-custom-directory]
In the `schema.prisma` file, we specify a custom [`output`](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider) path where Prisma will generate its types. This ensures Prisma's types are resolved correctly across different package managers.
In this guide, the types will be generated in the `database/generated/prisma` directory.
2.3. Add scripts and run migrations [#23-add-scripts-and-run-migrations]
Let's add some scripts to the `package.json` inside `packages/database`:
```json title="packages/database/package.json"
{
"name": "@repo/db",
"version": "0.0.0",
"type": "module", // [!code ++]
"scripts": {
// [!code ++]
"db:generate": "prisma generate", // [!code ++]
"db:migrate": "prisma migrate dev", // [!code ++]
"db:deploy": "prisma migrate deploy" // [!code ++]
}, // [!code ++]
"devDependencies": {
"prisma": "^7.0.0"
},
"dependencies": {
"@prisma/client": "^7.0.0",
"@prisma/adapter-pg": "^7.0.0",
"pg": "^8.0.0",
"dotenv": "^16.0.0"
}
}
```
Let's also add these scripts to `turbo.json` in the root and ensure that `DATABASE_URL` is added to the environment:
```json title="turbo.json"
{
"$schema": "https://turborepo.dev/schema.json",
"ui": "tui",
"globalEnv": ["DATABASE_URL"], // [!code ++]
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": [".next/**", "!.next/cache/**"]
},
"lint": {
"dependsOn": ["^lint"]
},
"check-types": {
"dependsOn": ["^check-types"]
},
"dev": {
"cache": false,
"persistent": true
},
"db:generate": { // [!code ++]
"cache": false // [!code ++]
}, // [!code ++]
"db:migrate": { // [!code ++]
"cache": false // [!code ++]
}, // [!code ++]
"db:deploy": { // [!code ++]
"cache": false // [!code ++]
} // [!code ++]
}
}
```
Run your first migration and generate Prisma Client
Navigate to the project root and run the following command to create and apply your first migration:
npm
pnpm
yarn
bun
```bash
npx turbo run db:migrate -- --name init
```
```bash
pnpm dlx turbo run db:migrate -- --name init
```
```bash
yarn dlx turbo run db:migrate -- --name init
```
```bash
bunx --bun turbo run db:migrate -- --name init
```
In Prisma 7, `migrate dev` no longer runs `prisma generate` automatically, so run generate explicitly:
npm
pnpm
yarn
bun
```bash
npx turbo run db:generate
```
```bash
pnpm dlx turbo run db:generate
```
```bash
yarn dlx turbo run db:generate
```
```bash
bunx --bun turbo run db:generate
```
Use the same `npx turbo run db:generate` command after future schema changes.
2.4. Export the Prisma client and types [#24-export-the-prisma-client-and-types]
Next, export the generated types and an instance of `PrismaClient` so it can be used in your applications.
In the `packages/database` directory, create a `src` folder and add a `client.ts` file. This file will define an instance of `PrismaClient`:
```ts title="packages/database/src/client.ts"
import { PrismaClient } from "../generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
export const prisma =
globalForPrisma.prisma ||
new PrismaClient({
adapter,
});
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
```
Then create an `index.ts` file in the `src` folder to re-export the generated prisma types and the `PrismaClient` instance:
```ts title="packages/database/src/index.ts"
export { prisma } from "./client"; // exports instance of prisma
export * from "../generated/prisma/client"; // exports generated types from prisma
```
Follow the [Just-in-Time packaging pattern](https://turborepo.dev/docs/core-concepts/internal-packages#just-in-time-packages) and create an entrypoint to the package inside `packages/database/package.json`:
If you're not using a bundler, use the [Compiled Packages](https://turborepo.dev/docs/core-concepts/internal-packages#compiled-packages) strategy instead.
```json title="packages/database/package.json"
{
"name": "@repo/db",
"version": "0.0.0",
"type": "module",
"scripts": {
"db:generate": "prisma generate",
"db:migrate": "prisma migrate dev",
"db:deploy": "prisma migrate deploy"
},
"devDependencies": {
"prisma": "^7.0.0"
},
"dependencies": {
"@prisma/client": "^7.0.0",
"@prisma/adapter-pg": "^7.0.0",
"pg": "^8.0.0",
"dotenv": "^16.0.0"
},
"exports": {
// [!code ++]
".": "./src/index.ts" // [!code ++]
} // [!code ++]
}
```
By completing these steps, you'll make the Prisma types and `PrismaClient` instance accessible throughout the monorepo.
3. Import the database package in the web app [#3-import-the-database-package-in-the-web-app]
The `turborepo-prisma` project should have an app called `web` at `apps/web`. Add the `database` dependency to `apps/web/package.json`:
npm
pnpm
bun
```json
{
// ...
"dependencies": {
"@repo/db": "*" // [!code ++]
// ...
}
// ...
}
```
```json
{
// ...
"dependencies": {
"@repo/db": "workspace:*" // [!code ++]
// ...
}
// ...
}
```
```json
{
// ...
"dependencies": {
"@repo/db": "workspace:*" // [!code ++]
// ...
}
// ...
}
```
Run your package manager's install command from the project root to link the workspace dependency:
npm
pnpm
yarn
bun
```bash
npm install
```
```bash
pnpm install
```
```bash
yarn install
```
```bash
bun install
```
Let's import the instantiated `prisma` client from the `database` package in the `web` app.
In the `apps/web/app` directory, open the `page.tsx` file and add the following code:
```tsx title="apps/web/app/page.tsx"
import styles from "./page.module.css";
import { prisma } from "@repo/db";
export default async function Home() {
const user = await prisma.user.findFirst();
return
{user?.name ?? "No user added yet"}
;
}
```
Then, create a `.env` file in the `web` directory and copy into it the contents of the `.env` file from the `/database` directory containing the `DATABASE_URL`:
```text title="apps/web/.env"
DATABASE_URL="Same database URL as used in the database directory"
```
If you want to use a single `.env` file in the root directory across your apps and packages in a Turborepo setup, consider using a package like [`dotenvx`](https://dotenvx.com/docs/monorepos/turborepo).
To implement this, update the `package.json` files for each package or app to ensure they load the required environment variables from the shared `.env` file. For detailed instructions, refer to the [`dotenvx` guide for Turborepo](https://dotenvx.com/docs/monorepos/turborepo).
Keep in mind that Turborepo [recommends using separate `.env` files for each package](https://turborepo.dev/docs/crafting-your-repository/using-environment-variables#use-env-files-in-packages) to promote modularity and avoid potential conflicts.
4. Configure task dependencies in Turborepo [#4-configure-task-dependencies-in-turborepo]
The `db:generate` script is essential for `dev` and `build` tasks in a monorepo setup.
If a new developer runs `turbo dev` on an application without first running `db:generate`, they will encounter errors.
To prevent this, ensure that `db:generate` is always executed before running `dev` or `build`. Keep `db:deploy` uncached for staging/production migration runs in CI. Here's how to configure this in your `turbo.json` file:
```json title="turbo.json"
{
"$schema": "https://turborepo.dev/schema.json",
"ui": "tui",
"globalEnv": ["DATABASE_URL"],
"tasks": {
"build": {
"dependsOn": ["^build", "^db:generate"], // [!code highlight]
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": [".next/**", "!.next/cache/**"]
},
"lint": {
"dependsOn": ["^lint"]
},
"check-types": {
"dependsOn": ["^check-types"]
},
"dev": {
"dependsOn": ["^db:generate"], // [!code ++]
"cache": false,
"persistent": true
},
"db:generate": {
"cache": false
},
"db:migrate": {
"cache": false
},
"db:deploy": {
"cache": false
}
}
}
```
5. Run the project in development [#5-run-the-project-in-development]
Then from the project root run the project:
npm
pnpm
yarn
bun
```bash
npx turbo run dev --filter=web
```
```bash
pnpm dlx turbo run dev --filter=web
```
```bash
yarn dlx turbo run dev --filter=web
```
```bash
bunx --bun turbo run dev --filter=web
```
Navigate to the `http://localhost:3000` and you should see the message:
```
No user added yet
```
You can add users to your database by creating a seed script or manually by using [Prisma Studio](/studio).
To use Prisma Studio to add manually data via a GUI, navigate inside the `packages/database` directory and run `prisma studio` using your package manager:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
This command starts a server with a GUI at [http://localhost:5555](http://localhost:5555), allowing you to view and modify your data.
Congratulations, you're done setting up Prisma for Turborepo!
Next Steps [#next-steps]
* Expand your Prisma models to handle more complex data relationships.
* Implement additional CRUD operations to enhance your application's functionality.
* Check out [Prisma Postgres](https://www.prisma.io/postgres) to see how you can scale your application.
More Info [#more-info]
* [Turborepo Docs](https://turborepo.dev/docs)
* [Next.js Docs](https://nextjs.org/docs)
* [Prisma ORM Docs](/orm)
# Astro (/docs/guides/frameworks/astro)
Introduction [#introduction]
Prisma ORM offers type-safe database access, and [Astro](https://astro.build/) is built for performance. Together with [Prisma Postgres](https://www.prisma.io/postgres), you get a fast, content-first stack with zero cold starts and end-to-end speed.
In this guide, you'll learn to integrate Prisma ORM with a Prisma Postgres database in an Astro project from scratch. You can find a complete example of this guide on [GitHub](https://github.com/prisma/prisma-examples/tree/latest/orm/astro).
Prerequisites [#prerequisites]
* [Node.js 20+](https://nodejs.org)
* [Astro VSCode extension (recommended)](https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode)
1. Set up your project [#1-set-up-your-project]
Create a new Astro project:
npm
pnpm
yarn
bun
```bash
npx create-astro@latest
```
```bash
pnpm dlx create-astro@latest
```
```bash
yarn dlx create-astro@latest
```
```bash
bunx --bun create-astro@latest
```
* *Where should we create your new project?* `astro-prisma`
* *How would you like to start your new project?* `Use minimal (empty) template `
* *Install dependencies? (recommended)* `Yes`
* *Initialize a new git repository? (optional)* `Yes`
Navigate into the newly created project directory:
```bash
cd astro-prisma
```
2. Install and Configure Prisma [#2-install-and-configure-prisma]
2.1. Install dependencies [#21-install-dependencies]
To get started with Prisma, you'll need to install a few dependencies:
npm
pnpm
yarn
bun
```bash
npm install prisma tsx @types/pg --save-dev
```
```bash
pnpm add prisma tsx @types/pg --save-dev
```
```bash
yarn add prisma tsx @types/pg --dev
```
```bash
bun add prisma tsx @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
bun add @prisma/client @prisma/adapter-pg dotenv pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Once installed, initialize Prisma in your project:
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output ../prisma/generated
```
```bash
pnpm dlx prisma init --db --output ../prisma/generated
```
```bash
yarn dlx prisma init --db --output ../prisma/generated
```
```bash
bunx --bun prisma init --db --output ../prisma/generated
```
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My Astro Project"
This will create:
* A `prisma/` directory with a `schema.prisma` file
* A `prisma.config.ts` file for configuring Prisma
* A `.env` file with a `DATABASE_URL` already set
2.2. Define your Prisma Schema [#22-define-your-prisma-schema]
In the `prisma/schema.prisma` file, add the following models and change the generator to use the `prisma-client` provider:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../prisma/generated"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
posts Post[] // [!code ++]
} // [!code ++]
// [!code ++]
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
published Boolean @default(false) // [!code ++]
authorId Int // [!code ++]
author User @relation(fields: [authorId], references: [id]) // [!code ++]
} // [!code ++]
```
This creates two models: `User` and `Post`, with a one-to-many relationship between them.
2.3 Add dotenv to prisma.config.ts [#23-add-dotenv-to-prismaconfigts]
To get access to the variables in the `.env` file, they can either be loaded by your runtime, or by using `dotenv`.
Include an import for `dotenv` at the top of the `prisma.config.ts`
```ts
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
2.4. Run migrations and generate Prisma Client [#24-run-migrations-and-generate-prisma-client]
Now, run the following command to create the database tables:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
Then generate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
2.5. Seed the database [#25-seed-the-database]
Let's add some seed data to populate the database with sample users and posts.
Create a new file called `seed.ts` in the `prisma/` directory:
```typescript title="prisma/seed.ts"
import { PrismaClient, Prisma } from "../prisma/generated/client";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
const userData: Prisma.UserCreateInput[] = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://www.twitter.com/prisma",
published: true,
},
],
},
},
];
export async function main() {
console.log("Starting to seed...");
for (const u of userData) {
await prisma.user.upsert({
where: { email: u.email },
update: {},
create: u,
});
}
console.log("Seeding finished.");
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
Now, tell Prisma how to run this script by updating your `prisma.config.ts`:
```ts title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: `tsx prisma/seed.ts`,
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Run the seed script:
npm
pnpm
yarn
bun
```bash
npx prisma db seed
```
```bash
pnpm dlx prisma db seed
```
```bash
yarn dlx prisma db seed
```
```bash
bunx --bun prisma db seed
```
And open Prisma Studio to inspect your data:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
3. Integrate Prisma into Astro [#3-integrate-prisma-into-astro]
3.1. Create TypeScript environment definitions [#31-create-typescript-environment-definitions]
First, create an `env.d.ts` file in your `src` directory to provide TypeScript definitions for environment variables:
```typescript title="src/env.d.ts"
interface ImportMetaEnv {
readonly DATABASE_URL: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
```
3.2. Create a Prisma Client [#32-create-a-prisma-client]
Inside of `/src`, create a `lib` directory and a `prisma.ts` file inside it. This file will be used to create and export your Prisma Client instance.
```bash
mkdir src/lib
touch src/lib/prisma.ts
```
Set up the Prisma client like this:
```typescript title="src/lib/prisma.ts"
import { PrismaClient } from "../../prisma/generated/client";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: import.meta.env.DATABASE_URL,
});
const prisma = new PrismaClient({
adapter,
});
export default prisma;
```
We recommend using a connection pooler (like [Prisma Accelerate](https://www.prisma.io/accelerate)) to manage database connections efficiently.
If you choose not to use one, **avoid** instantiating `PrismaClient` globally in long-lived environments. Instead, create and dispose of the client per request to prevent exhausting your database connections.
3.3. Create an API route [#33-create-an-api-route]
An API route is the best way to fetch data from your database in an Astro app.
Create a new file called `api/users.ts` in the `src/pages` directory:
```bash
mkdir src/pages/api
touch src/pages/api/users.ts
```
Now, create a GET route that fetches the `Users` data from your database, making sure to include each user's `Posts` by adding them to the `include` field:
```typescript title="src/pages/api/users.ts"
import type { APIRoute } from "astro";
import prisma from "../../lib/prisma";
export const GET: APIRoute = async () => {
const users = await prisma.user.findMany({
include: { posts: true },
});
return new Response(JSON.stringify(users), {
headers: { "Content-Type": "application/json" },
});
};
```
3.4. Fetch the data from the API route (Recommended Method) [#34-fetch-the-data-from-the-api-route-recommended-method]
Instead of using `fetch()` with HTTP requests, Astro recommends importing endpoint functions directly. This approach is more efficient and avoids URL parsing issues.
Start by creating a new type that combines the `User` and `Post` models called `UserWithPosts`:
```tsx title="src/pages/index.astro"
---
import type { User, Post } from "../../prisma/generated/client"; // [!code ++]
import { GET } from "./api/users.ts"; // [!code ++]
// [!code ++]
type UserWithPosts = User & { posts: Post[] }; // [!code ++]
// [!code ++]
const response = await GET(Astro); // [!code ++]
const users: UserWithPosts[] = await response.json(); // [!code ++]
---
Astro + Prisma
// [!code ++]
```
3.5. Run your app [#35-run-your-app]
Now start your development server to see your Astro app in action:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
Open your browser at [`http://localhost:4321`](http://localhost:4321) to see the users and their posts displayed on the page.
Summary [#summary]
You're done! You've just created an Astro app with Prisma that's connected to a Prisma Postgres database. Below are some next steps to explore, as well as some more resources to help you get started expanding your project.
Next Steps [#next-steps]
Now that you have a working Astro app connected to a Prisma Postgres database, you can:
* Extend your Prisma schema with more models and relationships
* Add create/update/delete routes and forms
* Explore authentication and validation
More Info [#more-info]
* [Prisma Documentation](/orm)
* [Astro Documentation](https://astro.build/docs)
# Elysia (/docs/guides/frameworks/elysia)
Introduction [#introduction]
[Elysia](https://elysiajs.com/) is an ergonomic web framework for building high-performance backend servers with Bun. It offers end-to-end type safety, an expressive API, and exceptional performance. Combined with Prisma ORM and [Prisma Postgres](https://www.prisma.io/postgres), you get a fast, type-safe backend stack.
In this guide, you'll learn to integrate Prisma ORM with a Prisma Postgres database in an Elysia application. You can find a complete example of this guide on [GitHub](https://github.com/prisma/prisma-examples/tree/latest/orm/elysia).
Prerequisites [#prerequisites]
* [Bun](https://bun.sh/docs/installation) installed on your system
1. Set up your project [#1-set-up-your-project]
Create a new Elysia project using the Bun scaffolding command:
```bash
bun create elysia elysia-prisma
```
Navigate to the project directory:
```bash
cd elysia-prisma
```
2. Install and configure Prisma [#2-install-and-configure-prisma]
2.1. Install dependencies [#21-install-dependencies]
Install the required Prisma packages, database adapter, and Prismabox (for generated TypeBox schemas):
```bash
bun add -d prisma bun-types
bun add @prisma/client @prisma/adapter-pg pg prismabox
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Once installed, initialize Prisma in your project:
```bash
bunx --bun prisma init --db --output ../src/generated/prisma
```
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My Elysia Project"
This will create:
* A `prisma/` directory with a `schema.prisma` file
* A `prisma.config.ts` file for configuring Prisma
* A `.env` file with a `DATABASE_URL` already set
2.2. Define your Prisma Schema [#22-define-your-prisma-schema]
In the `prisma/schema.prisma` file, mirror the example app structure with Prismabox TypeBox generators and a `Todo` model:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
generator prismabox {
provider = "prismabox"
typeboxImportDependencyName = "elysia"
typeboxImportVariableName = "t"
inputModel = true
output = "../src/generated/prismabox"
}
datasource db {
provider = "postgresql"
}
model Todo { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
completed Boolean @default(false) // [!code ++]
createdAt DateTime @default(now()) // [!code ++]
updatedAt DateTime @updatedAt // [!code ++]
} // [!code ++]
```
This matches the Prisma Elysia example: it generates Prisma Client to `src/generated/prisma` and Prismabox TypeBox schemas to `src/generated/prismabox`.
What is Prismabox? [#what-is-prismabox]
* A Prisma generator that reads your Prisma schema and emits Elysia-friendly TypeBox models.
* Generates files like `src/generated/prismabox/Todo.ts` (and one per model) with `TodoPlain`, `TodoPlainInputCreate`, etc.
* Use those generated models in routes to validate requests/responses and keep Elysia types in sync with your Prisma schema (also useful for OpenAPI/Eden).
2.3. Run migrations and generate Prisma Client [#23-run-migrations-and-generate-prisma-client]
Run the following commands to create the database tables and generate the Prisma Client:
```bash
bunx --bun prisma migrate dev --name init
bunx --bun prisma generate
```
2.4. Seed the database [#24-seed-the-database]
Add some seed data to populate the database with sample todos (mirrors the example repo).
Create a new file called `seed.ts` in the `prisma/` directory:
```typescript title="prisma/seed.ts"
import { PrismaClient } from "../src/generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
if (!process.env.DATABASE_URL) {
throw new Error("DATABASE_URL is not set");
}
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });
const todoData = [
{ title: "Learn Elysia" },
{ title: "Learn Prisma" },
{ title: "Build something awesome", completed: true },
];
async function main() {
console.log("Start seeding...");
for (const todo of todoData) {
const created = await prisma.todo.create({
data: todo,
});
console.log(`Created todo with id: ${created.id}`);
}
console.log("Seeding finished.");
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
```
Run the seed script:
```bash
bunx --bun prisma db seed
```
And open Prisma Studio to inspect your data:
```bash
bunx --bun prisma studio
```
3. Integrate Prisma into Elysia [#3-integrate-prisma-into-elysia]
3.1. Create a Prisma Client instance [#31-create-a-prisma-client-instance]
Inside the `src/` directory, create a `lib` directory with a `prisma.ts` file. This file will create and export your Prisma Client instance and add the following code:
```typescript title="src/lib/prisma.ts"
import { PrismaClient } from "../generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
throw new Error("DATABASE_URL is not set");
}
const adapter = new PrismaPg({ connectionString: databaseUrl });
export const prisma = new PrismaClient({ adapter });
```
3.2. Create API routes [#32-create-api-routes]
Update your `src/index.ts` file to match the Prisma Elysia example, including Prismabox-generated validation types:
```typescript title="src/index.ts"
import { Elysia, t } from "elysia";
import { prisma } from "./lib/prisma";
import { TodoPlain, TodoPlainInputCreate, TodoPlainInputUpdate } from "./generated/prismabox/Todo";
const app = new Elysia()
// Health check
.get("/", () => {
return { message: "Hello Elysia with Prisma!" };
})
// Get all todos
.get(
"/todos",
async () => {
const todos = await prisma.todo.findMany({
orderBy: { createdAt: "desc" },
});
return todos;
},
{
response: t.Array(TodoPlain),
},
)
// Get a single todo by ID
.get(
"/todos/:id",
async ({ params, set }) => {
const id = Number(params.id);
const todo = await prisma.todo.findUnique({
where: { id },
});
if (!todo) {
set.status = 404;
return { error: "Todo not found" };
}
return todo;
},
{
params: t.Object({
id: t.Numeric(),
}),
response: {
200: TodoPlain,
404: t.Object({
error: t.String(),
}),
},
},
)
// Create a new todo
.post(
"/todos",
async ({ body }) => {
const todo = await prisma.todo.create({
data: {
title: body.title,
},
});
return todo;
},
{
body: TodoPlainInputCreate,
response: TodoPlain,
},
)
// Update a todo
.put(
"/todos/:id",
async ({ params, body, set }) => {
const id = Number(params.id);
try {
const todo = await prisma.todo.update({
where: { id },
data: {
title: body.title,
completed: body.completed,
},
});
return todo;
} catch {
set.status = 404;
return { error: "Todo not found" };
}
},
{
params: t.Object({
id: t.Numeric(),
}),
body: TodoPlainInputUpdate,
response: {
200: TodoPlain,
404: t.Object({
error: t.String(),
}),
},
},
)
// Toggle todo completion
.patch(
"/todos/:id/toggle",
async ({ params, set }) => {
const id = Number(params.id);
try {
const todo = await prisma.todo.findUnique({
where: { id },
});
if (!todo) {
set.status = 404;
return { error: "Todo not found" };
}
const updated = await prisma.todo.update({
where: { id },
data: { completed: !todo.completed },
});
return updated;
} catch {
set.status = 404;
return { error: "Todo not found" };
}
},
{
params: t.Object({
id: t.Numeric(),
}),
response: {
200: TodoPlain,
404: t.Object({
error: t.String(),
}),
},
},
)
// Delete a todo
.delete(
"/todos/:id",
async ({ params, set }) => {
const id = Number(params.id);
try {
const todo = await prisma.todo.delete({
where: { id },
});
return todo;
} catch {
set.status = 404;
return { error: "Todo not found" };
}
},
{
params: t.Object({
id: t.Numeric(),
}),
response: {
200: TodoPlain,
404: t.Object({
error: t.String(),
}),
},
},
)
.listen(3000);
console.log(`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`);
```
This creates the same endpoints as the official example:
* `GET /` - Health check
* `GET /todos` - Fetch all todos (newest first)
* `GET /todos/:id` - Fetch a single todo
* `POST /todos` - Create a todo
* `PUT /todos/:id` - Update a todo
* `PATCH /todos/:id/toggle` - Toggle completion
* `DELETE /todos/:id` - Delete a todo
Prismabox generates the `TodoPlain`/`TodoPlainInput*` TypeBox schemas so responses and request bodies are validated and typed.
3.3. Run the application [#33-run-the-application]
Start your Elysia server:
```bash
bun run dev
```
You should see `🦊 Elysia is running at localhost:3000` in the console.
3.4. Test the API [#34-test-the-api]
Test the endpoints using `curl`:
```bash
# Health check
curl http://localhost:3000/ | jq
# Get all todos
curl http://localhost:3000/todos | jq
# Get a single todo
curl http://localhost:3000/todos/1 | jq
# Create a new todo
curl -X POST http://localhost:3000/todos \
-H "Content-Type: application/json" \
-d '{"title": "Ship the Prisma + Elysia guide"}' | jq
# Toggle completion
curl -X PATCH http://localhost:3000/todos/1/toggle | jq
# Update a todo
curl -X PUT http://localhost:3000/todos/1 \
-H "Content-Type: application/json" \
-d '{"title": "Updated title", "completed": true}' | jq
# Delete a todo
curl -X DELETE http://localhost:3000/todos/1 | jq
```
You're done! You've created an Elysia app with Prisma that's connected to a Prisma Postgres database.
Next steps [#next-steps]
Now that you have a working Elysia app connected to a Prisma Postgres database, you can:
* Extend your Prisma schema with more models and relationships
* Add update and delete endpoints
* Explore authentication with [Elysia plugins](https://elysiajs.com/plugins/overview.html)
* Use [Eden](https://elysiajs.com/eden/overview.html) for end-to-end type-safe API calls
More info [#more-info]
* [Prisma Documentation](/orm)
* [Elysia Documentation](https://elysiajs.com/)
* [Elysia with Prisma Guide](https://elysiajs.com/integrations/prisma.html)
# Hono (/docs/guides/frameworks/hono)
Introduction [#introduction]
Prisma ORM offers type-safe database access, and [Hono](https://hono.dev/) is built for fast, lightweight web apps. Together with [Prisma Postgres](https://www.prisma.io/postgres), you get a fast, lightweight backend, that can be deployed through Node.js, Cloudflare, or many other runtimes.
In this guide, you'll learn to integrate Prisma ORM with a Prisma Postgres database in a Hono backend application. You can find a complete example of this guide on [GitHub](https://github.com/prisma/prisma-examples/tree/latest/orm/hono).
Prerequisites [#prerequisites]
* [Node.js 20+](https://nodejs.org)
1. Set up your project [#1-set-up-your-project]
Create a new Hono project:
npm
pnpm
yarn
bun
```bash
npm create hono@latest
```
```bash
pnpm create hono
```
```bash
yarn create hono
```
```bash
bunx create-hono
```
* *Target directory?* `my-app`
* *Which template do you want to use?* `nodejs`
* *Install dependencies? (recommended)* `Yes`
* *Which package manager do you want to use?* `npm`
2. Install and configure Prisma [#2-install-and-configure-prisma]
2.1. Install dependencies [#21-install-dependencies]
To get started with Prisma, you'll need to install a few dependencies:
npm
pnpm
yarn
bun
```bash
npm install prisma tsx @types/pg --save-dev
```
```bash
pnpm add prisma tsx @types/pg --save-dev
```
```bash
yarn add prisma tsx @types/pg --dev
```
```bash
bun add prisma tsx @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
bun add @prisma/client @prisma/adapter-pg dotenv pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Once installed, initialize Prisma in your project:
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output ../src/generated/prisma
```
```bash
pnpm dlx prisma init --db --output ../src/generated/prisma
```
```bash
yarn dlx prisma init --db --output ../src/generated/prisma
```
```bash
bunx --bun prisma init --db --output ../src/generated/prisma
```
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My Hono Project"
This will create:
* A `prisma/` directory with a `schema.prisma` file
* A `prisma.config.ts` with your Prisma configuration
* A `.env` file with a `DATABASE_URL` already set
2.2. Define your Prisma Schema [#22-define-your-prisma-schema]
In the `prisma/schema.prisma` file, add the following models and change the generator to use the `prisma-client` provider:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
posts Post[] // [!code ++]
} // [!code ++]
// [!code ++]
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
published Boolean @default(false) // [!code ++]
authorId Int // [!code ++]
author User @relation(fields: [authorId], references: [id]) // [!code ++]
} // [!code ++]
```
This creates two models: `User` and `Post`, with a one-to-many relationship between them.
In `prisma.config.ts`, import `dotenv` at the top of the file
```typescript title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";
import "dotenv/config"; // [!code ++]
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
2.3. Configure the Prisma Client generator [#23-configure-the-prisma-client-generator]
Now, run the following command to create the database tables and generate the Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
2.4. Seed the database [#24-seed-the-database]
Let's add some seed data to populate the database with sample users and posts.
Create a new file called `seed.ts` in the `prisma/` directory:
```typescript title="prisma/seed.ts"
import { PrismaClient, Prisma } from "../src/generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
const userData: Prisma.UserCreateInput[] = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://www.twitter.com/prisma",
published: true,
},
],
},
},
];
export async function main() {
for (const u of userData) {
await prisma.user.create({ data: u });
}
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
Now, tell Prisma how to run this script by updating your `prisma.config.ts`:
```typescript title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";
import "dotenv/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx prisma/seed.ts", // [!code ++]
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Run the seed script:
npm
pnpm
yarn
bun
```bash
npx prisma db seed
```
```bash
pnpm dlx prisma db seed
```
```bash
yarn dlx prisma db seed
```
```bash
bunx --bun prisma db seed
```
And open Prisma Studio to inspect your data:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
3. Integrate Prisma into Hono [#3-integrate-prisma-into-hono]
3.1. Create a Prisma middleware [#31-create-a-prisma-middleware]
Inside of `/src`, create a `lib` directory and a `prisma.ts` file inside it. This file will be used to create and export your Prisma Client instance. Set up the Prisma client like this:
```tsx title="src/lib/prisma.ts"
import type { Context, Next } from "hono";
import { PrismaClient } from "../generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
import "dotenv/config";
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
throw new Error("DATABASE_URL is not set");
}
const adapter = new PrismaPg({
connectionString: databaseUrl,
});
const prisma = new PrismaClient({ adapter });
function withPrisma(c: Context, next: Next) {
if (!c.get("prisma")) {
c.set("prisma", prisma);
}
return next();
}
export default withPrisma;
```
We recommend using a connection pooler (like [Prisma Accelerate](https://www.prisma.io/accelerate)) to manage database connections efficiently.
If you choose not to use one, in long-lived environments (for example, a Node.js server) instantiate a single `PrismaClient` and reuse it across requests to avoid exhausting database connections. In serverless environments or when using a pooler (for example, Accelerate), creating a client per request is acceptable.
3.2 Environment Variables & Types [#32-environment-variables--types]
By default, Hono does not load any environment variables from a `.env`. `dotenv` handles this and will be read that file and expose them via `process.env`. Hono can get additional types to know that the `withPrisma` middleware will set a `prisma`
key on the Hono context
```ts title="src/index.ts"
import { Hono } from "hono";
import { serve } from "@hono/node-server";
import type { PrismaClient } from "./generated/prisma/client.js"; // [!code ++]
type ContextWithPrisma = {
// [!code ++]
Variables: {
// [!code ++]
prisma: PrismaClient; // [!code ++]
}; // [!code ++]
}; // [!code ++]
const app = new Hono(); // [!code highlight]
app.get("/", (c) => {
return c.text("Hello Hono!");
});
serve(
{
fetch: app.fetch,
port: 3000,
},
(info) => {
console.log(`Server is running on http://localhost:${info.port}`);
},
);
```
If using Cloudflare Workers, the environment variables will automatically be set to Hono's context, so `dotenv` can be skipped.
3.3. Create A GET Route [#33-create-a-get-route]
Fetch data from the database using Hono's `app.get` function. This will perform any database queries
and return the data as JSON.
Create a new route inside of `src/index.ts`:
Now, create a GET route that fetches the `Users` data from your database, making sure to include each user's `Posts` by adding them to the `include` field:
```ts title="src/index.ts"
import withPrisma from "./lib/prisma.js";
app.get("/users", withPrisma, async (c) => {
const prisma = c.get("prisma");
const users = await prisma.user.findMany({
include: { posts: true },
});
return c.json({ users });
});
```
3.4. Display The Data [#34-display-the-data]
Start the Hono app by call the `dev` script in the `package.json`
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
There should be a "Server is running on [http://localhost:3000](http://localhost:3000)" log printed out. From here, the data
can be viewed by visiting `http://localhost:3000/users` or by running `curl` from the command line
```bash
curl http://localhost:3000/users | jq
```
You're done! You've created a Hono app with Prisma that's connected to a Prisma Postgres database.
For next steps there are some resources below for you to explore as well as next steps for expanding
your project.
Next Steps [#next-steps]
Now that you have a working Hono app connected to a Prisma Postgres database, you can:
* Extend your Prisma schema with more models and relationships
* Add create/update/delete routes and forms
* Explore authentication and validation
More Info [#more-info]
* [Prisma Documentation](/orm)
* [Hono Documentation](https://hono.dev/docs/)
# NestJS (/docs/guides/frameworks/nestjs)
Introduction [#introduction]
This guide shows you how to use Prisma ORM with [NestJS](https://nestjs.com/), a progressive Node.js framework for building efficient and scalable server-side applications. You'll build a REST API with NestJS that uses Prisma ORM to store and retrieve data from a database.
[Prisma ORM](https://www.prisma.io) is an open-source ORM for Node.js and TypeScript. It is used as an **alternative** to writing plain SQL, or using another database access tool such as SQL query builders (like [knex.js](https://knexjs.org/)) or ORMs (like [TypeORM](https://typeorm.io/) and [Sequelize](https://sequelize.org/)). Prisma currently supports PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and CockroachDB.
While Prisma can be used with plain JavaScript, it embraces TypeScript and provides a level of type-safety that goes beyond the guarantees other ORMs in the TypeScript ecosystem offer.
You can find a ready-to-run example [here](https://github.com/prisma/prisma-examples/tree/latest/orm/nest)
Prerequisites [#prerequisites]
* [Node.js 20+](https://nodejs.org)
1. Create your NestJS project [#1-create-your-nestjs-project]
Install the NestJS CLI and create a new project:
npm
pnpm
yarn
bun
```bash
npm install -g @nestjs/cli
```
```bash
pnpm add -g @nestjs/cli
```
```bash
yarn global add @nestjs/cli
```
```bash
bun add --global @nestjs/cli
```
```bash
nest new nestjs-prisma
```
When prompted, select **npm** as your package manager. Navigate to the project directory:
```bash
cd nestjs-prisma
```
You can run `npm start` to start your application at `http://localhost:3000/`. Over the course of this guide, you'll add routes to store and retrieve data about *users* and *posts*.
In `package.json`, add the `type` field set to `"module"`:
```json title="package.json"
{
"type": "module" // [!code ++]
}
```
2. Set up Prisma [#2-set-up-prisma]
2.1. Install Prisma and dependencies [#21-install-prisma-and-dependencies]
Install the necessary Prisma packages and database drivers:
npm
pnpm
yarn
bun
```bash
npm install prisma --save-dev
```
```bash
pnpm add prisma --save-dev
```
```bash
yarn add prisma --dev
```
```bash
bun add prisma --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg pg
```
```bash
bun add @prisma/client @prisma/adapter-pg pg
```
If you are using a different database provider (MySQL, SQL Server), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
2.2. Initialize Prisma [#22-initialize-prisma]
Initialize Prisma in your project:
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output ../src/generated/prisma
```
```bash
pnpm dlx prisma init --db --output ../src/generated/prisma
```
```bash
yarn dlx prisma init --db --output ../src/generated/prisma
```
```bash
bunx --bun prisma init --db --output ../src/generated/prisma
```
This creates a new `prisma` directory with the following contents:
* `schema.prisma`: Specifies your database connection and contains the database schema
* `prisma.config.ts`: A configuration file for your projects
* `.env`: A [dotenv](https://github.com/motdotla/dotenv) file, typically used to store your database credentials in a group of environment variables
2.3. Set the generator output path [#23-set-the-generator-output-path]
Specify your output `path` for the generated Prisma client by either passing `--output ../src/generated/prisma` during `prisma init` or directly in your Prisma schema:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
```
2.4. Configure your database connection [#24-configure-your-database-connection]
Your database connection is configured in the `datasource` block in your `schema.prisma` file. By default it's set to `postgresql` which is what you need for this guide.
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
```
Now, open up `.env` and you should see a `DATABASE_URL` already specified:
```text title=".env"
DATABASE_URL=""
```
Make sure you have a [ConfigModule](https://docs.nestjs.com/techniques/configuration) configured, otherwise the `DATABASE_URL` variable will not be picked up from `.env`.
2.5. Define your data model [#25-define-your-data-model]
Add the following two models to your `schema.prisma` file:
```prisma title="prisma/schema.prisma"
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean? @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
```
2.6. Create and run your migration [#26-create-and-run-your-migration]
With your Prisma models in place, you can generate your SQL migration files and run them against the database. Run the following commands in your terminal:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
This `prisma migrate dev` command generates SQL files and directly runs them against the database. In this case, the following migration files was created in the existing `prisma` directory:
```bash
$ tree prisma
prisma
├── migrations
│ └── 20201207100915_init
│ └── migration.sql
└── schema.prisma
```
2.7. Generate Prisma Client [#27-generate-prisma-client]
Once installed, you can run the generate command to generate the types and Client needed for your project. If any changes are made to your schema, you will need to rerun the `generate` command to keep those types in sync.
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
3. Create a Prisma service [#3-create-a-prisma-service]
You're now able to send database queries with Prisma Client. When setting up your NestJS application, you'll want to abstract away the Prisma Client API for database queries within a service. To get started, you can create a new `PrismaService` that takes care of instantiating `PrismaClient` and connecting to your database.
Inside the `src` directory, create a new file called `prisma.service.ts` and add the following code to it:
```typescript title="src/prisma.service.ts"
import { Injectable } from "@nestjs/common";
import { PrismaClient } from "./generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
@Injectable()
export class PrismaService extends PrismaClient {
constructor() {
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL as string,
});
super({ adapter });
}
}
```
4. Create User and Post services [#4-create-user-and-post-services]
Next, you can write services that you can use to make database calls for the `User` and `Post` models from your Prisma schema.
4.1. Create the User service [#41-create-the-user-service]
Still inside the `src` directory, create a new file called `user.service.ts` and add the following code to it:
```typescript title="src/user.service.ts"
import { Injectable } from "@nestjs/common";
import { PrismaService } from "./prisma.service.js";
import { User, Prisma } from "./generated/prisma/client.js";
@Injectable()
export class UserService {
constructor(private prisma: PrismaService) {}
async user(userWhereUniqueInput: Prisma.UserWhereUniqueInput): Promise {
return this.prisma.user.findUnique({
where: userWhereUniqueInput,
});
}
async users(params: {
skip?: number;
take?: number;
cursor?: Prisma.UserWhereUniqueInput;
where?: Prisma.UserWhereInput;
orderBy?: Prisma.UserOrderByWithRelationInput;
}): Promise {
const { skip, take, cursor, where, orderBy } = params;
return this.prisma.user.findMany({
skip,
take,
cursor,
where,
orderBy,
});
}
async createUser(data: Prisma.UserCreateInput): Promise {
return this.prisma.user.create({
data,
});
}
async updateUser(params: {
where: Prisma.UserWhereUniqueInput;
data: Prisma.UserUpdateInput;
}): Promise {
const { where, data } = params;
return this.prisma.user.update({
data,
where,
});
}
async deleteUser(where: Prisma.UserWhereUniqueInput): Promise {
return this.prisma.user.delete({
where,
});
}
}
```
Notice how you're using Prisma Client's generated types to ensure that the methods that are exposed by your service are properly typed. You therefore save the boilerplate of typing your models and creating additional interface or DTO files.
4.2. Create the Post service [#42-create-the-post-service]
Now do the same for the `Post` model.
Still inside the `src` directory, create a new file called `post.service.ts` and add the following code to it:
```typescript title="src/post.service.ts"
import { Injectable } from "@nestjs/common";
import { PrismaService } from "./prisma.service.js";
import { Post, Prisma } from "./generated/prisma/client.js";
@Injectable()
export class PostService {
constructor(private prisma: PrismaService) {}
async post(postWhereUniqueInput: Prisma.PostWhereUniqueInput): Promise {
return this.prisma.post.findUnique({
where: postWhereUniqueInput,
});
}
async posts(params: {
skip?: number;
take?: number;
cursor?: Prisma.PostWhereUniqueInput;
where?: Prisma.PostWhereInput;
orderBy?: Prisma.PostOrderByWithRelationInput;
}): Promise {
const { skip, take, cursor, where, orderBy } = params;
return this.prisma.post.findMany({
skip,
take,
cursor,
where,
orderBy,
});
}
async createPost(data: Prisma.PostCreateInput): Promise {
return this.prisma.post.create({
data,
});
}
async updatePost(params: {
where: Prisma.PostWhereUniqueInput;
data: Prisma.PostUpdateInput;
}): Promise {
const { data, where } = params;
return this.prisma.post.update({
data,
where,
});
}
async deletePost(where: Prisma.PostWhereUniqueInput): Promise {
return this.prisma.post.delete({
where,
});
}
}
```
Your `UserService` and `PostService` currently wrap the CRUD queries that are available in Prisma Client. In a real world application, the service would also be the place to add business logic to your application. For example, you could have a method called `updatePassword` inside the `UserService` that would be responsible for updating the password of a user.
5. Implement REST API routes [#5-implement-rest-api-routes]
5.1. Create the controller [#51-create-the-controller]
Finally, you'll use the services you created in the previous sections to implement the different routes of your app. For the purpose of this guide, you'll put all your routes into the already existing `AppController` class.
Replace the contents of the `app.controller.ts` file with the following code:
```typescript title="src/app.controller.ts"
import { Controller, Get, Param, Post, Body, Put, Delete } from "@nestjs/common";
import { UserService } from "./user.service.js";
import { PostService } from "./post.service.js";
import { User as UserModel } from "./generated/prisma/client.js";
import { Post as PostModel } from "./generated/prisma/client.js";
@Controller()
export class AppController {
constructor(
private readonly UserService: UserService,
private readonly postService: PostService,
) {}
@Get("post/:id")
async getPostById(@Param("id") id: string): Promise {
return this.postService.post({ id: Number(id) });
}
@Get("feed")
async getPublishedPosts(): Promise {
return this.postService.posts({
where: { published: true },
});
}
@Get("filtered-posts/:searchString")
async getFilteredPosts(@Param("searchString") searchString: string): Promise {
return this.postService.posts({
where: {
OR: [
{
title: { contains: searchString },
},
{
content: { contains: searchString },
},
],
},
});
}
@Post("post")
async createDraft(
@Body() postData: { title: string; content?: string; authorEmail: string },
): Promise {
const { title, content, authorEmail } = postData;
return this.postService.createPost({
title,
content,
author: {
connect: { email: authorEmail },
},
});
}
@Post("user")
async signupUser(@Body() userData: { name?: string; email: string }): Promise {
return this.UserService.createUser(userData);
}
@Put("publish/:id")
async publishPost(@Param("id") id: string): Promise {
return this.postService.updatePost({
where: { id: Number(id) },
data: { published: true },
});
}
@Delete("post/:id")
async deletePost(@Param("id") id: string): Promise {
return this.postService.deletePost({ id: Number(id) });
}
}
```
This controller implements the following routes:
GET [#get]
* `/post/:id`: Fetch a single post by its `id`
* `/feed`: Fetch all *published* posts
* `/filtered-posts/:searchString`: Filter posts by `title` or `content`
POST [#post]
* `/post`: Create a new post
* Body:
* `title: String` (required): The title of the post
* `content: String` (optional): The content of the post
* `authorEmail: String` (required): The email of the user that creates the post
* `/user`: Create a new user
* Body:
* `email: String` (required): The email address of the user
* `name: String` (optional): The name of the user
PUT [#put]
* `/publish/:id`: Publish a post by its `id`
DELETE [#delete]
* `/post/:id`: Delete a post by its `id`
5.2. Register services in the app module [#52-register-services-in-the-app-module]
Remember to register the new services in the app module.
Update `src/app.module.ts` to register all services:
```typescript title="src/app.module.ts"
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { ConfigModule } from "@nestjs/config";
import { AppService } from "./app.service.js";
import { PrismaService } from "./prisma.service.js"; // [!code ++]
import { UserService } from "./user.service.js"; // [!code ++]
import { PostService } from "./post.service.js"; // [!code ++]
@Module({
imports: [ConfigModule.forRoot()],
controllers: [AppController],
providers: [AppService, PrismaService, UserService, PostService], // [!code ++]
})
export class AppModule {}
```
6. Test your API [#6-test-your-api]
Start your application:
npm
pnpm
yarn
bun
```bash
npm start
```
```bash
pnpm start
```
```bash
yarn start
```
```bash
bun start
```
Test your endpoints with curl, [Postman](https://www.postman.com/), or [HTTPie](https://httpie.io/).
**Create a user:**
```bash
curl -X POST http://localhost:3000/user \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "email": "alice@prisma.io"}'
```
**Create a post:**
```bash
curl -X POST http://localhost:3000/post \
-H "Content-Type: application/json" \
-d '{"title": "Hello World", "authorEmail": "alice@prisma.io"}'
```
**Get published posts:**
```bash
curl http://localhost:3000/feed
```
**Publish a post:**
```bash
curl -X PUT http://localhost:3000/publish/1
```
**Search posts:**
```bash
curl http://localhost:3000/filtered-posts/hello
```
Summary [#summary]
In this guide, you learned how to use Prisma ORM with NestJS to implement a REST API. The controller that implements the routes of the API is calling a `PrismaService` which in turn uses Prisma Client to send queries to a database to fulfill the data needs of incoming requests.
If you want to learn more about using NestJS with Prisma, be sure to check out the following resources:
* [NestJS & Prisma](https://www.prisma.io/nestjs)
* [Ready-to-run example projects for REST & GraphQL](https://github.com/prisma/prisma-examples/)
* [Production-ready starter kit](https://github.com/notiz-dev/nestjs-prisma-starter#instructions)
* [Video: Accessing Databases using NestJS with Prisma (5min)](https://www.youtube.com/watch?v=UlVJ340UEuk\&ab_channel=Prisma) by [Marc Stammerjohann](https://github.com/marcjulian)
# Next.js (/docs/guides/frameworks/nextjs)
Introduction [#introduction]
This guide shows you how to use Prisma with Next.js, a fullstack React framework. You'll learn how to create a [Prisma Postgres](/postgres) instance, set up Prisma ORM with Next.js, handle migrations, and deploy your application to Vercel.
You can find a [deployment-ready example on GitHub](https://github.com/prisma/prisma-examples/blob/latest/orm/nextjs).
Prerequisites [#prerequisites]
* [Node.js](https://nodejs.org) v20.19+, v22.12+, or v24.0+
* A Vercel account (if you want to deploy your application)
1. Set up your project [#1-set-up-your-project]
From the directory where you want to create your project, run `create-next-app` to create a new Next.js app that you will be using for this guide.
npm
pnpm
yarn
bun
```bash
npx create-next-app@latest nextjs-prisma
```
```bash
pnpm dlx create-next-app@latest nextjs-prisma
```
```bash
yarn dlx create-next-app@latest nextjs-prisma
```
```bash
bunx --bun create-next-app@latest nextjs-prisma
```
You will be prompted to answer a few questions about your project. Select all of the defaults.
For reference, those are:
* TypeScript
* ESLint
* Tailwind CSS
* No `src` directory
* App Router
* Turbopack
* No customized import alias
Then, navigate to the project directory:
```bash
cd nextjs-prisma
```
2. Install and Configure Prisma [#2-install-and-configure-prisma]
2.1. Install dependencies [#21-install-dependencies]
To get started with Prisma, you'll need to install a few dependencies:
npm
pnpm
yarn
bun
```bash
npm install prisma tsx @types/pg --save-dev
```
```bash
pnpm add prisma tsx @types/pg --save-dev
```
```bash
yarn add prisma tsx @types/pg --dev
```
```bash
bun add prisma tsx @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
bun add @prisma/client @prisma/adapter-pg dotenv pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Once installed, initialize Prisma in your project:
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output ../app/generated/prisma
```
```bash
pnpm dlx prisma init --db --output ../app/generated/prisma
```
```bash
yarn dlx prisma init --db --output ../app/generated/prisma
```
```bash
bunx --bun prisma init --db --output ../app/generated/prisma
```
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My \***\*\_\_\*\*** Project"
This will create:
* A `prisma` directory with a `schema.prisma` file.
* A `prisma.config.ts` file for configuring Prisma.
* A Prisma Postgres database.
* A `.env` file containing the `DATABASE_URL` at the project root.
The `app/generated/prisma` output directory for the generated Prisma Client will be created when you run `prisma generate` or `prisma migrate dev` in a later step.
2.2. Define your Prisma Schema [#22-define-your-prisma-schema]
In the `prisma/schema.prisma` file, add the following models:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
posts Post[] // [!code ++]
} // [!code ++]
// [!code ++]
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
published Boolean @default(false) // [!code ++]
authorId Int // [!code ++]
author User @relation(fields: [authorId], references: [id]) // [!code ++]
} // [!code ++]
```
This creates two models: `User` and `Post`, with a one-to-many relationship between them.
2.3 Add dotenv to prisma.config.ts [#23-add-dotenv-to-prismaconfigts]
To get access to the variables in the `.env` file, they can either be loaded by your runtime, or by using `dotenv`.
Include an import for `dotenv` at the top of the `prisma.config.ts`
```typescript title="prisma.config.ts"
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
2.4. Run migrations and generate Prisma Client [#24-run-migrations-and-generate-prisma-client]
Now, run the following command to create the database tables:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
Then generate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
2.5. Seed the database [#25-seed-the-database]
Add some seed data to populate the database with sample users and posts.
Create a new file called `seed.ts` in the `prisma/` directory:
```typescript title="prisma/seed.ts"
import { PrismaClient, Prisma } from "../app/generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
import "dotenv/config";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
const prisma = new PrismaClient({
adapter,
});
const userData: Prisma.UserCreateInput[] = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://www.twitter.com/prisma",
published: true,
},
],
},
},
];
export async function main() {
for (const u of userData) {
await prisma.user.create({ data: u });
}
}
main();
```
Now, tell Prisma how to run this script by updating your `prisma.config.ts`:
```typescript title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: `tsx prisma/seed.ts`, // [!code ++]
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Finally, run `prisma db seed` to seed your database with the initial data we defined in the `seed.ts` file.
Run the seed script:
npm
pnpm
yarn
bun
```bash
npx prisma db seed
```
```bash
pnpm dlx prisma db seed
```
```bash
yarn dlx prisma db seed
```
```bash
bunx --bun prisma db seed
```
And open Prisma Studio to inspect your data:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
2.6 Set up Prisma Client [#26-set-up-prisma-client]
Now that you have a database with some initial data, you can set up Prisma Client and connect it to your database.
At the root of your project, create a new `lib` directory and add a `prisma.ts` file to it.
```bash
mkdir -p lib && touch lib/prisma.ts
```
Now, add the following code to your `lib/prisma.ts` file:
```typescript title="lib/prisma.ts" showLineNumbers
import { PrismaClient } from "../app/generated/prisma/client"; // [!code ++]
import { PrismaPg } from "@prisma/adapter-pg"; // [!code ++]
// [!code ++]
const globalForPrisma = global as unknown as {
// [!code ++]
prisma: PrismaClient; // [!code ++]
}; // [!code ++]
// [!code ++]
const adapter = new PrismaPg({
// [!code ++]
connectionString: process.env.DATABASE_URL, // [!code ++]
}); // [!code ++]
// [!code ++]
const prisma =
globalForPrisma.prisma ||
new PrismaClient({
// [!code ++]
adapter, // [!code ++]
}); // [!code ++]
// [!code ++]
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma; // [!code ++]
// [!code ++]
export default prisma; // [!code ++]
```
This file creates a Prisma Client and attaches it to the global object so that only one instance of the client is created in your application. This helps resolve issues with hot reloading that can occur when using Prisma ORM with Next.js in development mode.
You'll use this client in the next section to run your first queries.
3. Query your database with Prisma ORM [#3-query-your-database-with-prisma-orm]
Now that you have an initialized Prisma Client, a connection to your database, and some initial data, you can start querying your data with Prisma ORM.
In this example, you'll make the "home" page of your application display all of your users.
Open the `app/page.tsx` file and replace the existing code with the following:
```tsx title="app/page.tsx"
export default async function Home() {
return (
Superblog
Alice
Bob
);
}
```
This gives you a basic page with a title and a list of users. However, that list is static with hardcoded values. Let's update the page to fetch the users from your database and make it dynamic.
```tsx title="app/page.tsx"
import prisma from "@/lib/prisma";
export default async function Home() {
const users = await prisma.user.findMany();
return (
Superblog
{users.map((user) => (
{user.name}
))}
);
}
```
You are now importing your client, querying the `User` model for all users, and then displaying them in a list.
Now your home page is dynamic and will display the users from your database.
3.1 Update your data (optional) [#31-update-your-data-optional]
If you want to see what happens when data is updated, you could:
* update your `User` table via a SQL browser of your choice
* change your `seed.ts` file to add more users
* change the call to `prisma.user.findMany` to re-order the users, filter the users, or similar.
Just reload the page and you'll see the changes.
4. Add a new Posts list page [#4-add-a-new-posts-list-page]
You have your home page working, but you should add a new page that displays all of your posts.
First create a new `posts` directory in the `app` directory and create a new `page.tsx` file inside of it.
```bash
mkdir -p app/posts && touch app/posts/page.tsx
```
Second, add the following code to the `app/posts/page.tsx` file:
```tsx title="app/posts/page.tsx"
import prisma from "@/lib/prisma";
export default async function Posts() {
return (
Posts
My first post
);
}
```
Now `localhost:3000/posts` will load, but the content is hardcoded again. Let's update it to be dynamic, similarly to the home page:
```tsx title="app/posts/page.tsx"
import prisma from "@/lib/prisma";
export default async function Posts() {
const posts = await prisma.post.findMany({
include: {
author: true,
},
});
return (
Posts
{posts.map((post) => (
{post.title}by {post.author.name}
))}
);
}
```
This works similarly to the home page, but instead of displaying users, it displays posts. You can also see that you've used `include` in your Prisma Client query to fetch the author of each post so you can display the author's name.
This "list view" is one of the most common patterns in web applications. You're going to add two more pages to your application which you'll also commonly need: a "detail view" and a "create view".
5. Add a new Posts detail page [#5-add-a-new-posts-detail-page]
To complement the Posts list page, you'll add a Posts detail page.
In the `posts` directory, create a new `[id]` directory and a new `page.tsx` file inside of that.
```bash
mkdir -p "app/posts/[id]" && touch "app/posts/[id]/page.tsx"
```
This page will display a single post's title, content, and author. Just like your other pages, add the following code to the `app/posts/new/page.tsx` file:
```tsx title="app/posts/[id]/page.tsx"
import prisma from "@/lib/prisma";
export default async function Post({ params }: { params: Promise<{ id: string }> }) {
return (
My first post
by Anonymous
No content available.
);
}
```
As before, this page is static with hardcoded content. Let's update it to be dynamic based on the `params` passed to the page:
```tsx title="app/posts/[id]/page.tsx"
import prisma from "@/lib/prisma";
import { notFound } from "next/navigation";
export default async function Post({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
const post = await prisma.post.findUnique({
where: { id: parseInt(id) },
include: {
author: true,
},
});
if (!post) {
notFound();
}
return (
{post.title}
by {post.author.name}
{post.content || "No content available."}
);
}
```
There's a lot of changes here, so let's break it down:
* You're using Prisma Client to fetch the post by its `id`, which you get from the `params` object.
* In case the post doesn't exist (maybe it was deleted or maybe you typed a wrong ID), you call `notFound()` to display a 404 page.
* You then display the post's title, content, and author. If the post doesn't have content, you display a placeholder message.
It's not the prettiest page, but it's a good start. Try it out by navigating to `localhost:3000/posts/1` and `localhost:3000/posts/2`. You can also test the 404 page by navigating to `localhost:3000/posts/999`.
6. Add a new Posts create page [#6-add-a-new-posts-create-page]
To round out your application, you'll add a "create" page for posts. This will let you write your own posts and save them to the database.
As with the other pages, you'll start with a static page and then update it to be dynamic.
```bash
mkdir -p app/posts/new && touch app/posts/new/page.tsx
```
Now, add the following code to the `app/posts/new/page.tsx` file:
```tsx title="app/posts/new/page.tsx"
import Form from "next/form";
export default function NewPost() {
async function createPost(formData: FormData) {
"use server";
const title = formData.get("title") as string;
const content = formData.get("content") as string;
}
return (
Create New Post
);
}
```
This form looks good, but it doesn't do anything yet. Let's update the `createPost` function to save the post to the database:
```tsx title="app/posts/new/page.tsx"
import Form from "next/form";
import prisma from "@/lib/prisma";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
export default function NewPost() {
async function createPost(formData: FormData) {
"use server";
const title = formData.get("title") as string;
const content = formData.get("content") as string;
await prisma.post.create({
data: {
title,
content,
authorId: 1,
},
});
revalidatePath("/posts");
redirect("/posts");
}
return (
Create New Post
);
}
```
This page now has a functional form! When you submit the form, it will create a new post in the database and redirect you to the posts list page.
You also added a `revalidatePath` call to revalidate the posts list page so that it will be updated with the new post. That way everyone can read the new post immediately.
Try it out by navigating to `localhost:3000/posts/new` and submitting the form.
7. Deploy your application to Vercel (Optional) [#7-deploy-your-application-to-vercel-optional]
The quickest way to deploy your application to Vercel is to use the [Vercel CLI](https://vercel.com/docs/cli).
First, install the Vercel CLI:
npm
pnpm
yarn
bun
```bash
npm install -g vercel
```
```bash
pnpm add -g vercel
```
```bash
yarn global add vercel
```
```bash
bun add --global vercel
```
Then, run `vercel login` to log in to your Vercel account.
```bash
vercel login
```
Before you deploy, you also need to tell Vercel to make sure that the Prisma Client is generated. You can do this by adding a `postinstall` script to your `package.json` file.
```json title="package.json"
{
"name": "nextjs-prisma",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"postinstall": "prisma generate",
"start": "next start",
"lint": "next lint"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
},
"dependencies": {
"@prisma/adapter-pg": "^6.2.1",
"@prisma/client": "^6.2.1",
"next": "15.1.4",
"pg": "^8.13.1",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "15.1.4",
"postcss": "^8",
"prisma": "^6.2.1",
"tailwindcss": "^3.4.1",
"tsx": "^4.19.2",
"typescript": "^5"
}
}
```
After this change, you can deploy your application to Vercel by running `vercel`.
```bash
vercel
```
After the deployment is complete, you can visit your application at the URL that Vercel provides. Congratulations, you've just deployed a Next.js application with Prisma ORM!
8. Next steps [#8-next-steps]
Now that you have a working Next.js application with Prisma ORM, here are some ways you can expand and improve your application:
* Add authentication to protect your routes
* Add the ability to edit and delete posts
* Add comments to posts
* Use [Prisma Studio](/studio) for visual database management
For more information:
* [Prisma ORM documentation](/orm)
* [Prisma Client API reference](/orm/prisma-client/setup-and-configuration/introduction)
* [Next.js documentation](https://nextjs.org/docs)
# Nuxt (/docs/guides/frameworks/nuxt)
This guide shows you how to set up Prisma ORM in a Nuxt application with [Prisma Postgres](https://prisma.io/postgres).
Prerequisites [#prerequisites]
* Node.js 18+
* A [Prisma Postgres](https://console.prisma.io/) database (or any PostgreSQL database)
1. Create a Nuxt project [#1-create-a-nuxt-project]
Create a new Nuxt project:
npm
pnpm
yarn
bun
```bash
npx nuxi@latest init hello-prisma
```
```bash
pnpm dlx nuxi@latest init hello-prisma
```
```bash
yarn dlx nuxi@latest init hello-prisma
```
```bash
bunx --bun nuxi@latest init hello-prisma
```
Navigate to the project and install dependencies:
```bash
cd hello-prisma
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg pg
```
```bash
bun add @prisma/client @prisma/adapter-pg pg
```
npm
pnpm
yarn
bun
```bash
npm install -D prisma @types/pg dotenv tsx
```
```bash
pnpm add -D prisma @types/pg dotenv tsx
```
```bash
yarn add --dev prisma @types/pg dotenv tsx
```
```bash
bun add --dev prisma @types/pg dotenv tsx
```
2. Initialize Prisma [#2-initialize-prisma]
Initialize Prisma in your project:
npm
pnpm
yarn
bun
```bash
npx prisma init
```
```bash
pnpm dlx prisma init
```
```bash
yarn dlx prisma init
```
```bash
bunx --bun prisma init
```
Update your `prisma/schema.prisma`:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "postgresql"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
```
Create a `prisma.config.ts` file in the root of your project:
```ts title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";
import "dotenv/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx ./prisma/seed.ts",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Update your `.env` file with your database connection string:
```text title=".env"
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
```
Run the migration to create your database tables:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
3. Set up Prisma Client [#3-set-up-prisma-client]
Create `server/utils/db.ts`. Nuxt auto-imports exports from `server/utils`, making `prisma` available in all API routes:
```ts title="server/utils/db.ts"
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "../../prisma/generated/client";
const prismaClientSingleton = () => {
const pool = new PrismaPg({ connectionString: process.env.DATABASE_URL! });
return new PrismaClient({ adapter: pool });
};
type PrismaClientSingleton = ReturnType;
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClientSingleton | undefined;
};
export const prisma = globalForPrisma.prisma ?? prismaClientSingleton();
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
```
4. Create API routes [#4-create-api-routes]
Create an API route to fetch users. The `prisma` instance is auto-imported:
```ts title="server/api/users.get.ts"
export default defineEventHandler(async () => {
const users = await prisma.user.findMany({
include: { posts: true },
});
return users;
});
```
Create an API route to create a user:
```ts title="server/api/users.post.ts"
export default defineEventHandler(async (event) => {
const body = await readBody<{ name: string; email: string }>(event);
const user = await prisma.user.create({
data: {
name: body.name,
email: body.email,
},
});
return user;
});
```
5. Create a page [#5-create-a-page]
Update `app.vue` to display users:
```html title="app.vue"
Users
{{ user.name }} ({{ user.email }})
No users yet.
```
6. Run the app [#6-run-the-app]
Start the development server:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
Open `http://localhost:3000` to see your app.
7. Seed your database (optional) [#7-seed-your-database-optional]
Create a seed file to populate your database with sample data:
```ts title="prisma/seed.ts"
import "dotenv/config";
import { PrismaClient } from "./generated/client";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL! });
const prisma = new PrismaClient({ adapter });
async function main() {
const alice = await prisma.user.create({
data: {
name: "Alice",
email: "alice@prisma.io",
posts: {
create: { title: "Hello World", published: true },
},
},
});
console.log(`Created user: ${alice.name}`);
}
main()
.then(() => prisma.$disconnect())
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
```
Run the seed:
npm
pnpm
yarn
bun
```bash
npx prisma db seed
```
```bash
pnpm dlx prisma db seed
```
```bash
yarn dlx prisma db seed
```
```bash
bunx --bun prisma db seed
```
8. Deploy to Vercel [#8-deploy-to-vercel]
You can deploy your Nuxt application to Vercel using one of two methods:
Option A: Deploy using Vercel CLI [#option-a-deploy-using-vercel-cli]
1. Install the Vercel CLI (if not already installed):
npm
pnpm
yarn
bun
```bash
npm install -g vercel
```
```bash
pnpm add -g vercel
```
```bash
yarn global add vercel
```
```bash
bun add --global vercel
```
2. Deploy your project:
npm
pnpm
yarn
bun
```bash
npx vercel
```
```bash
pnpm dlx vercel
```
```bash
yarn dlx vercel
```
```bash
bunx --bun vercel
```
3. Set the `DATABASE_URL` environment variable:
* Go to your [Vercel Dashboard](https://vercel.com/dashboard)
* Select your project
* Navigate to **Settings** → **Environment Variables**
* Add `DATABASE_URL` with your database connection string
4. Redeploy your application to apply the environment variable:
npm
pnpm
yarn
bun
```bash
npx vercel --prod
```
```bash
pnpm dlx vercel --prod
```
```bash
yarn dlx vercel --prod
```
```bash
bunx --bun vercel --prod
```
Option B: Deploy using Git integration [#option-b-deploy-using-git-integration]
1. Push your code to a Git repository (GitHub, GitLab, or Bitbucket).
2. Add `prisma generate` to your `postinstall` script in `package.json` to ensure Prisma Client is generated during deployment:
```json title="package.json"
{
"scripts": {
"postinstall": "prisma generate",
"build": "nuxt build",
"dev": "nuxt dev"
}
}
```
3. Import your project in Vercel:
* Go to [Vercel Dashboard](https://vercel.com/dashboard)
* Click **Add New** → **Project**
* Import your Git repository
* Vercel will automatically detect it as a Nuxt project
4. Configure environment variables:
* Before deploying, go to **Environment Variables**
* Add `DATABASE_URL` with your database connection string
* Click **Deploy**
Vercel will automatically build and deploy your Nuxt application. The deployment process is the same as any other Node.js application, and Prisma Client will be generated during the build process thanks to the `postinstall` script.
Next steps [#next-steps]
* Explore the [full Nuxt + Prisma example](https://github.com/prisma/prisma-examples/tree/latest/orm/nuxt) for a complete blog application
* Learn about [Prisma Client API](/orm/prisma-client/setup-and-configuration/introduction)
* Set up [Prisma Postgres](/postgres) for a managed database
# React Router 7 (/docs/guides/frameworks/react-router-7)
Introduction [#introduction]
This guide shows you how to use Prisma ORM with [React Router 7](https://reactrouter.com/), a multi-strategy router that can be as minimal as declarative routing or as full-featured as a fullstack framework.
You'll learn how to set up Prisma ORM and Prisma Postgres with React Router 7 and handle migrations. You can find a [deployment-ready example on GitHub](https://github.com/prisma/prisma-examples/blob/latest/orm/react-router-7).
Prerequisites [#prerequisites]
* [Node.js 20+](https://nodejs.org)
1. Set up your project [#1-set-up-your-project]
From the directory where you want to create your project, run `create-react-router` to create a new React Router app that you will be using for this guide.
npm
pnpm
yarn
bun
```bash
npx create-react-router@latest react-router-7-prisma
```
```bash
pnpm dlx create-react-router@latest react-router-7-prisma
```
```bash
yarn dlx create-react-router@latest react-router-7-prisma
```
```bash
bunx --bun create-react-router@latest react-router-7-prisma
```
You'll be prompted to select the following, select `Yes` for both:
* *Initialize a new git repository?* `Yes`
* *Install dependencies with npm?* `Yes`
Now, navigate to the project directory:
```bash
cd react-router-7-prisma
```
2. Install and Configure Prisma [#2-install-and-configure-prisma]
2.1. Install dependencies [#21-install-dependencies]
To get started with Prisma, you'll need to install a few dependencies:
npm
pnpm
yarn
bun
```bash
npm install prisma tsx @types/pg --save-dev
```
```bash
pnpm add prisma tsx @types/pg --save-dev
```
```bash
yarn add prisma tsx @types/pg --dev
```
```bash
bun add prisma tsx @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
bun add @prisma/client @prisma/adapter-pg dotenv pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Once installed, initialize Prisma in your project:
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output ../app/generated/prisma
```
```bash
pnpm dlx prisma init --db --output ../app/generated/prisma
```
```bash
yarn dlx prisma init --db --output ../app/generated/prisma
```
```bash
bunx --bun prisma init --db --output ../app/generated/prisma
```
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My React Router 7 Project"
This will create:
* A `prisma` directory with a `schema.prisma` file.
* A `prisma.config.ts` file for configuring Prisma
* A Prisma Postgres database.
* A `.env` file containing the `DATABASE_URL` at the project root.
* An `output` directory for the generated Prisma Client as `app/generated/prisma`.
2.2. Define your Prisma Schema [#22-define-your-prisma-schema]
In the `prisma/schema.prisma` file, add the following models and change the generator to use the `prisma-client` provider:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
posts Post[] // [!code ++]
} // [!code ++]
// [!code ++]
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
published Boolean @default(false) // [!code ++]
authorId Int // [!code ++]
author User @relation(fields: [authorId], references: [id]) // [!code ++]
} // [!code ++]
```
This creates two models: `User` and `Post`, with a one-to-many relationship between them.
2.3 Add dotenv to prisma.config.ts [#23-add-dotenv-to-prismaconfigts]
To get access to the variables in the `.env` file, they can either be loaded by your runtime, or by using `dotenv`.
Include an import for `dotenv` at the top of the `prisma.config.ts`
```ts
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
2.4. Configure the Prisma Client generator [#24-configure-the-prisma-client-generator]
Now, run the following command to create the database tables and generate the Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
2.5. Seed the database [#25-seed-the-database]
Add some seed data to populate the database with sample users and posts.
Create a new file called `seed.ts` in the `prisma/` directory:
```typescript title="prisma/seed.ts"
import { PrismaClient, Prisma } from "../app/generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
const userData: Prisma.UserCreateInput[] = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://www.twitter.com/prisma",
published: true,
},
],
},
},
];
export async function main() {
for (const u of userData) {
await prisma.user.create({ data: u });
}
}
main();
```
Now, tell Prisma how to run this script by updating your `prisma.config.ts`:
```ts title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: `tsx prisma/seed.ts`, // [!code ++]
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Run the seed script:
npm
pnpm
yarn
bun
```bash
npx prisma db seed
```
```bash
pnpm dlx prisma db seed
```
```bash
yarn dlx prisma db seed
```
```bash
bunx --bun prisma db seed
```
And open Prisma Studio to inspect your data:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
3. Integrate Prisma into React Router 7 [#3-integrate-prisma-into-react-router-7]
3.1. Create a Prisma Client [#31-create-a-prisma-client]
Inside of your `app` directory, create a new `lib` directory and add a `prisma.ts` file to it. This file will be used to create and export your Prisma Client instance.
Set up the Prisma client like this:
```typescript title="app/lib/prisma.ts"
import { PrismaClient } from "../generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const globalForPrisma = global as unknown as {
prisma: PrismaClient;
};
const prisma =
globalForPrisma.prisma ||
new PrismaClient({
adapter,
});
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
export default prisma;
```
We recommend using a connection pooler (like [Prisma Accelerate](https://www.prisma.io/accelerate)) to manage database connections efficiently.
If you choose not to use one, **avoid** instantiating `PrismaClient` globally in long-lived environments. Instead, create and dispose of the client per request to prevent exhausting your database connections.
You'll use this client in the next section to run your first queries.
3.2. Query your database with Prisma [#32-query-your-database-with-prisma]
Now that you have an initialized Prisma Client, a connection to your database, and some initial data, you can start querying your data with Prisma ORM.
In this example, you'll be making the "home" page of your application display all of your users.
Open the `app/routes/home.tsx` file and replace the existing code with the following:
```tsx title="app/routes/home.tsx"
import type { Route } from "./+types/home";
export function meta({}: Route.MetaArgs) {
return [
{ title: "New React Router App" },
{ name: "description", content: "Welcome to React Router!" },
];
}
export default function Home({ loaderData }: Route.ComponentProps) {
return (
Superblog
Alice
Bob
);
}
```
If you see an error on the first line, `import type { Route } from "./+types/home";`, make sure you run `npm run dev` so React Router generates needed types.
This gives you a basic page with a title and a list of users. However, the list of users is static. Update the page to fetch the users from your database and make it dynamic.
```tsx title="app/routes/home.tsx"
import type { Route } from "./+types/home";
import prisma from "~/lib/prisma"; // [!code ++]
export function meta({}: Route.MetaArgs) {
return [
{ title: "New React Router App" },
{ name: "description", content: "Welcome to React Router!" },
];
}
export async function loader() {
// [!code ++]
const users = await prisma.user.findMany(); // [!code ++]
return { users }; // [!code ++]
} // [!code ++]
export default function Home({ loaderData }: Route.ComponentProps) {
const { users } = loaderData; // [!code ++]
return (
Superblog
{users.map(
(
user, // [!code ++]
) => (
{" "}
// [!code ++]
{user.name} // [!code ++]
// [!code ++]
),
)}{" "}
// [!code ++]
);
}
```
You are now importing your client, using [a React Router loader](https://reactrouter.com/start/framework/data-loading#server-data-loading) to query the `User` model for all users, and then displaying them in a list.
Now your home page is dynamic and will display the users from your database.
3.4 Update your data (optional) [#34-update-your-data-optional]
If you want to see what happens when data is updated, you could:
* update your `User` table via an SQL browser of your choice
* change your `seed.ts` file to add more users
* change the call to `prisma.user.findMany` to re-order the users, filter the users, or similar.
Just reload the page and you'll see the changes.
4. Add a new Posts list page [#4-add-a-new-posts-list-page]
You have your home page working, but you should add a new page that displays all of your posts.
First, create a new `posts` directory under the `app/routes` directory and add a `home.tsx` file:
```bash
mkdir -p app/routes/posts && touch app/routes/posts/home.tsx
```
Second, add the following code to the `app/routes/posts/home.tsx` file:
```tsx title="app/routes/posts/home.tsx"
import type { Route } from "./+types/home";
import prisma from "~/lib/prisma";
export default function Home() {
return (
Posts
My first post
);
}
```
Second, update the `app/routes.ts` file so when you visit the `/posts` route, the `posts/home.tsx` page is shown:
```tsx title="app/routes.ts"
import { type RouteConfig, index, route } from "@react-router/dev/routes"; // [!code highlight]
export default [
index("routes/home.tsx"),
route("posts", "routes/posts/home.tsx"), // [!code ++]
] satisfies RouteConfig;
```
Now `localhost:5173/posts` will load, but the content is static. Update it to be dynamic, similarly to the home page:
```tsx title="app/routes/posts/home.tsx"
import type { Route } from "./+types/home";
import prisma from "~/lib/prisma";
export async function loader() {
// [!code ++]
const posts = await prisma.post.findMany({
// [!code ++]
include: {
// [!code ++]
author: true, // [!code ++]
}, // [!code ++]
}); // [!code ++]
return { posts }; // [!code ++]
} // [!code ++]
export default function Posts({ loaderData }: Route.ComponentProps) {
const { posts } = loaderData; // [!code ++]
return (
);
}
```
This works similarly to the home page, but instead of displaying users, it displays posts. You can also see that you've used `include` in your Prisma Client query to fetch the author of each post so you can display the author's name.
This "list view" is one of the most common patterns in web applications. You're going to add two more pages to your application which you'll also commonly need: a "detail view" and a "create view".
5. Add a new Posts detail page [#5-add-a-new-posts-detail-page]
To complement the Posts list page, you'll add a Posts detail page.
In the `routes/posts` directory, create a new `post.tsx` file.
```bash
touch app/routes/posts/post.tsx
```
This page will display a single post's title, content, and author. Just like your other pages, add the following code to the `app/routes/posts/post.tsx` file:
```tsx title="app/routes/posts/post.tsx"
import type { Route } from "./+types/post";
import prisma from "~/lib/prisma";
export default function Post({ loaderData }: Route.ComponentProps) {
return (
My first post
by Anonymous
No content available.
);
}
```
And then add a new route for this page:
```tsx title="app/routes.ts"
export default [
index("routes/home.tsx"),
route("posts", "routes/posts/home.tsx"),
route("posts/:postId", "routes/posts/post.tsx"), // [!code ++]
] satisfies RouteConfig;
```
As before, this page is static. Update it to be dynamic based on the `params` passed to the page:
```tsx title="app/routes/posts/post.tsx"
import { data } from "react-router"; // [!code ++]
import type { Route } from "./+types/post";
import prisma from "~/lib/prisma";
export async function loader({ params }: Route.LoaderArgs) {
// [!code ++]
const { postId } = params; // [!code ++]
const post = await prisma.post.findUnique({
// [!code ++]
where: { id: parseInt(postId) }, // [!code ++]
include: {
// [!code ++]
author: true, // [!code ++]
}, // [!code ++]
}); // [!code ++]
// [!code ++]
if (!post) {
// [!code ++]
throw data("Post Not Found", { status: 404 }); // [!code ++]
} // [!code ++]
return { post }; // [!code ++]
} // [!code ++]
export default function Post({ loaderData }: Route.ComponentProps) {
const { post } = loaderData; // [!code ++]
return (
);
}
```
There's a lot of changes here, so break it down:
* You're using Prisma Client to fetch the post by its `id`, which you get from the `params` object.
* In case the post doesn't exist (maybe it was deleted or maybe you typed a wrong ID), you throw an error to display a 404 page.
* You then display the post's title, content, and author. If the post doesn't have content, you display a placeholder message.
It's not the prettiest page, but it's a good start. Try it out by navigating to `localhost:5173/posts/1` and `localhost:5173/posts/2`. You can also test the 404 page by navigating to `localhost:5173/posts/999`.
6. Add a new Posts create page [#6-add-a-new-posts-create-page]
To round out your application, you'll add a "create" page for posts. This will allow you to write your own posts and save them to the database.
As with the other pages, you'll start with a static page and then update it to be dynamic.
```bash
touch app/routes/posts/new.tsx
```
Now, add the following code to the `app/routes/posts/new.tsx` file:
```tsx title="app/routes/posts/new.tsx"
import type { Route } from "./+types/new";
import { Form } from "react-router";
export async function action({ request }: Route.ActionArgs) {
const formData = await request.formData();
const title = formData.get("title") as string;
const content = formData.get("content") as string;
}
export default function NewPost() {
return (
Create New Post
);
}
```
You can't open the `posts/new` page in your app yet. To do that, you need to add it to `routes.tsx` again:
```tsx title="app/routes.ts"
export default [
index("routes/home.tsx"),
route("posts", "routes/posts/home.tsx"),
route("posts/:postId", "routes/posts/post.tsx"),
route("posts/new", "routes/posts/new.tsx"), // [!code ++]
] satisfies RouteConfig;
```
Now you can view the form at the new URL. It looks good, but it doesn't do anything yet. Update the `action` to save the post to the database:
```tsx title="app/routes/posts/new.tsx"
import type { Route } from "./+types/new";
import { Form, redirect } from "react-router"; // [!code ++]
import prisma from "~/lib/prisma"; // [!code ++]
export async function action({ request }: Route.ActionArgs) {
const formData = await request.formData();
const title = formData.get("title") as string;
const content = formData.get("content") as string;
try {
// [!code ++]
await prisma.post.create({
// [!code ++]
data: {
// [!code ++]
title, // [!code ++]
content, // [!code ++]
authorId: 1, // [!code ++]
}, // [!code ++]
}); // [!code ++]
} catch (error) {
// [!code ++]
console.error(error); // [!code ++]
return Response.json({ error: "Failed to create post" }, { status: 500 }); // [!code ++]
} // [!code ++]
// [!code ++]
return redirect("/posts"); // [!code ++]
}
export default function NewPost() {
return (
Create New Post
);
}
```
This page now has a functional form! When you submit the form, it will create a new post in the database and redirect you to the posts list page.
Try it out by navigating to `localhost:5173/posts/new` and submitting the form.
7. Next steps [#7-next-steps]
Now that you have a working React Router application with Prisma ORM, here are some ways you can expand and improve your application:
* Add authentication to protect your routes
* Add the ability to edit and delete posts
* Add comments to posts
* Use [Prisma Studio](/studio) for visual database management
For more information and updates:
* [Prisma ORM documentation](/orm)
* [Prisma Client API reference](/orm/prisma-client/setup-and-configuration/introduction)
* [React Router documentation](https://reactrouter.com/home)
* Join our [Discord community](https://pris.ly/discord)
* Follow us on [Twitter](https://twitter.com/prisma) and [YouTube](https://youtube.com/prismadata)
# SolidStart (/docs/guides/frameworks/solid-start)
Introduction [#introduction]
Prisma ORM streamlines database access with type-safe queries and a smooth developer experience. SolidStart, a modern framework for building reactive web apps with SolidJS, pairs well with Prisma and Postgres to create a clean and scalable full-stack architecture.
In this guide, you'll learn how to integrate Prisma ORM with a Prisma Postgres database in a SolidStart project from scratch. You can find a complete example of this guide on [GitHub](https://github.com/prisma/prisma-examples/tree/latest/orm/solid-start).
Prerequisites [#prerequisites]
* [Node.js 20+](https://nodejs.org)
1. Set up your project [#1-set-up-your-project]
Begin by creating a new SolidStart app. In your terminal, run:
npm
pnpm
yarn
bun
```bash
npm init solid@latest
```
```bash
pnpm create solid
```
```bash
yarn create solid
```
```bash
bunx create-solid
```
Use the following options when prompted:
* *Project name:* `my-solid-prisma-app`
* *Is this a SolidStart project:* `Yes`
* *Template:* `bare`
* *Use TypeScript:* `Yes`
Next, navigate into your new project, install dependencies, and start the development server:
npm
pnpm
yarn
bun
```bash
cd my-solid-prisma-app
npm install
npm run dev
```
```bash
cd my-solid-prisma-app
pnpm install
pnpm run dev
```
```bash
cd my-solid-prisma-app
yarn install
yarn dev
```
```bash
cd my-solid-prisma-app
bun install
bun run dev
```
Once the dev server is running, open `http://localhost:3000` in your browser. You should see the SolidStart welcome screen.
Clean up the default UI by editing the `app.tsx` file and replacing its content with the following code:
```typescript title="src/app.tsx"
import "./app.css";
export default function App() {
return (
SolidStart + Prisma
);
}
```
2. Install and Configure Prisma [#2-install-and-configure-prisma]
2.1. Install dependencies [#21-install-dependencies]
To get started with Prisma, you'll need to install a few dependencies:
npm
pnpm
yarn
bun
```bash
npm install prisma tsx @types/pg --save-dev
```
```bash
pnpm add prisma tsx @types/pg --save-dev
```
```bash
yarn add prisma tsx @types/pg --dev
```
```bash
bun add prisma tsx @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
bun add @prisma/client @prisma/adapter-pg dotenv pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Once installed, initialize Prisma in your project:
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output ../src/generated/prisma
```
```bash
pnpm dlx prisma init --db --output ../src/generated/prisma
```
```bash
yarn dlx prisma init --db --output ../src/generated/prisma
```
```bash
bunx --bun prisma init --db --output ../src/generated/prisma
```
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My SolidStart Project"
This will create:
* A `prisma` directory with a `schema.prisma` file.
* A `prisma.config.ts` file for configuring Prisma
* A Prisma Postgres database.
* A `.env` file containing the `DATABASE_URL` at the project root.
* An `output` directory for the generated Prisma Client as `src/generated/prisma`.
2.2. Define your Prisma Schema [#22-define-your-prisma-schema]
In the `prisma/schema.prisma` file, add the following models and change the generator to use the `prisma-client` provider:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
posts Post[] // [!code ++]
} // [!code ++]
// [!code ++]
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
published Boolean @default(false) // [!code ++]
authorId Int // [!code ++]
author User @relation(fields: [authorId], references: [id]) // [!code ++]
} // [!code ++]
```
This creates two models: `User` and `Post`, with a one-to-many relationship between them.
2.3 Add dotenv to prisma.config.ts [#23-add-dotenv-to-prismaconfigts]
To get access to the variables in the `.env` file, they can either be loaded by your runtime, or by using `dotenv`.
Include an import for `dotenv` at the top of the `prisma.config.ts`
```ts
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
2.4. Configure the Prisma Client generator [#24-configure-the-prisma-client-generator]
Now, run the following command to create the database tables and generate the Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
2.5. Seed the database [#25-seed-the-database]
Let's add some seed data to populate the database with sample users and posts.
Create a new file called `seed.ts` in the `prisma/` directory:
```typescript title="prisma/seed.ts"
import { PrismaClient, Prisma } from "../src/generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
const userData: Prisma.UserCreateInput[] = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://www.twitter.com/prisma",
published: true,
},
],
},
},
];
export async function main() {
for (const u of userData) {
await prisma.user.create({ data: u });
}
}
main();
```
Now, tell Prisma how to run this script by updating your `prisma.config.ts`:
```ts title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: `tsx prisma/seed.ts`, // [!code ++]
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Run the seed script:
npm
pnpm
yarn
bun
```bash
npx prisma db seed
```
```bash
pnpm dlx prisma db seed
```
```bash
yarn dlx prisma db seed
```
```bash
bunx --bun prisma db seed
```
And open Prisma Studio to inspect your data:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
3. Integrate Prisma into SolidStart [#3-integrate-prisma-into-solidstart]
3.1. Create a Prisma Client [#31-create-a-prisma-client]
At the root of your project, create a new `lib` folder and a `prisma.ts` file inside it:
```bash
mkdir -p lib && touch lib/prisma.ts
```
Add the following code to create a Prisma Client instance:
```typescript title="lib/prisma.ts"
import { PrismaClient } from "../src/generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
export default prisma;
```
We recommend using a connection pooler (like [Prisma Accelerate](https://www.prisma.io/accelerate)) to manage database connections efficiently.
If you choose not to use one, **avoid** instantiating `PrismaClient` globally in long-lived environments. Instead, create and dispose of the client per request to prevent exhausting your database connections.
3.2. Create an API Route [#32-create-an-api-route]
Now, let's fetch data from the database using an API route.
Create a new file at `src/routes/api/users.ts`:
```typescript title="src/routes/api/users.ts"
import prisma from "../../../lib/prisma";
export async function GET() {
const users = await prisma.user.findMany({
include: {
posts: true,
},
});
return new Response(JSON.stringify(users), {
headers: { "Content-Type": "application/json" },
});
}
```
3.3. Fetch Data in Your Component [#33-fetch-data-in-your-component]
In your `app.tsx` file, use `createResource` to fetch data from your new API route:
```typescript title="src/app.tsx"
import "./app.css";
import { createResource } from "solid-js"; // [!code ++]
import { User, Post } from "./generated/prisma/client"; // [!code ++]
// [!code ++]
type UserWithPosts = User & { // [!code ++]
posts: Post[]; // [!code ++]
}; // [!code ++]
// [!code ++]
const fetchUsers = async () => { // [!code ++]
const res = await fetch("http://localhost:3000/api/users"); // [!code ++]
return res.json(); // [!code ++]
}; // [!code ++]
export default function App() {
const [users, { mutate, refetch }] = createResource(fetchUsers); // [!code ++]
return (
SolidStart + Prisma
);
}
```
`createResource` is a SolidJS hook for managing async data. It tracks loading and error states automatically. [Learn more](https://docs.solidjs.com/reference/basic-reactivity/create-resource#createresource).
3.4. Display the Data [#34-display-the-data]
To show the users and their posts, use SolidJS's `` component:
```typescript title="src/app.tsx"
import "./app.css";
import { createResource, For } from "solid-js"; // [!code highlight]
import { User, Post } from "./generated/prisma/client";
type UserWithPosts = User & {
posts: Post[];
};
const fetchUsers = async () => {
const res = await fetch("http://localhost:3000/api/users");
return res.json();
};
export default function App() {
const [users, { mutate, refetch }] =
createResource(fetchUsers);
return (
SolidJS + Prisma
// [!code ++]
{(user) => ( // [!code ++]
// [!code ++]
{user.name}
// [!code ++]
{(post) =>
{post.title}
} // [!code ++]
// [!code ++]
)} // [!code ++]
// [!code ++]
);
}
```
`` loops through an array reactively. Think of it like `.map()` in React. [Learn more](https://docs.solidjs.com/reference/components/for)
3.5. Add Loading and Error States [#35-add-loading-and-error-states]
Use SolidJS's `` component to handle loading and error conditions:
```typescript title="src/app.tsx"
import "./app.css";
import { createResource, For, Show } from "solid-js"; // [!code highlight]
import { User, Post } from "./generated/prisma/client";
type UserWithPosts = User & {
posts: Post[];
};
const fetchUsers = async () => {
const res = await fetch("http://localhost:3000/api/users");
return res.json();
};
export default function App() {
const [users, { mutate, refetch }] =
createResource(fetchUsers);
return (
)}
// [!code ++]
// [!code ++]
);
}
```
`` conditionally renders content. It's similar to an `if` statement. [Learn more](https://docs.solidjs.com/reference/components/show)
You're done! You've just created a SolidStart app connected to a Prisma Postgres database.
Next Steps [#next-steps]
Now that you have a working SolidStart app connected to a Prisma Postgres database, you can:
* Extend your Prisma schema with more models and relationships
* Add create/update/delete routes and forms
* Explore authentication, validation, and optimistic updates
More Info [#more-info]
* [Prisma ORM Docs](/orm)
* [SolidStart Documentation](https://start.solidjs.com/)
# SvelteKit (/docs/guides/frameworks/sveltekit)
Introduction [#introduction]
Prisma ORM simplifies database access with type-safe queries, and when paired with [SvelteKit](https://svelte.dev/docs/kit), it creates a robust and scalable full-stack architecture.
In this guide, you'll learn to integrate Prisma ORM with a Prisma Postgres database in a SvelteKit project from scratch. You can find a complete example of this guide on [GitHub](https://github.com/prisma/prisma-examples/tree/latest/orm/sveltekit).
Prerequisites [#prerequisites]
* [Node.js 20+](https://nodejs.org)
* [Svelte VSCode extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) (Recommended by Svelte)
1. Set up your project [#1-set-up-your-project]
You'll be using [Svelte CLI](https://github.com/sveltejs/cli) instead of `npx create svelte@latest`. This CLI provides a more interactive setup and built-in support for popular tooling like ESLint and Prettier
Create a new Svelte project:
npm
pnpm
yarn
bun
```bash
npx sv create sveltekit-prisma
```
```bash
pnpm dlx sv create sveltekit-prisma
```
```bash
yarn dlx sv create sveltekit-prisma
```
```bash
bunx --bun sv create sveltekit-prisma
```
It will prompt you to customize your setup. Here are the options you'll choose:
* *Which template would you like?* `SvelteKit minimal`
* *Add type checking with TypeScript?* `Yes, using TypeScript syntax`
* *What would you like to add to your project?*
* `prettier`
* `eslint`
* *Which package manager do you want to install dependencies with?* `npm`
Once the setup completes, navigate into your project and start the development server:
npm
pnpm
yarn
bun
```bash
cd sveltekit-prisma
npm run dev
```
```bash
cd sveltekit-prisma
pnpm run dev
```
```bash
cd sveltekit-prisma
yarn dev
```
```bash
cd sveltekit-prisma
bun run dev
```
That's it! Svelte makes it a very simple process to get up and running. At this point, your project is ready to integrate Prisma and connect to a Prisma Postgres database.
2. Install and Configure Prisma [#2-install-and-configure-prisma]
2.1. Install dependencies [#21-install-dependencies]
To get started with Prisma, you'll need to install a few dependencies:
npm
pnpm
yarn
bun
```bash
npm install prisma tsx @types/pg --save-dev
```
```bash
pnpm add prisma tsx @types/pg --save-dev
```
```bash
yarn add prisma tsx @types/pg --dev
```
```bash
bun add prisma tsx @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
bun add @prisma/client @prisma/adapter-pg dotenv pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Once installed, initialize Prisma in your project:
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output src/generated/prisma
```
```bash
pnpm dlx prisma init --db --output src/generated/prisma
```
```bash
yarn dlx prisma init --db --output src/generated/prisma
```
```bash
bunx --bun prisma init --db --output src/generated/prisma
```
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My SvelteKit Project"
This will create:
* A `prisma` directory with a `schema.prisma` file.
* A `prisma.config.ts` file for configuring Prisma
* A Prisma Postgres database.
* A `.env` file containing the `DATABASE_URL` at the project root.
* An `output` directory for the generated Prisma Client as `src/generated/prisma`.
2.2. Define your Prisma Schema [#22-define-your-prisma-schema]
In the `prisma/schema.prisma` file, add the following models and change the generator to use the `prisma-client` provider:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
posts Post[] // [!code ++]
} // [!code ++]
// [!code ++]
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
published Boolean @default(false) // [!code ++]
authorId Int // [!code ++]
author User @relation(fields: [authorId], references: [id]) // [!code ++]
} // [!code ++]
```
This creates two models: `User` and `Post`, with a one-to-many relationship between them.
2.3 Add dotenv to prisma.config.ts [#23-add-dotenv-to-prismaconfigts]
To get access to the variables in the `.env` file, they can either be loaded by your runtime, or by using `dotenv`.
Include an import for `dotenv` at the top of the `prisma.config.ts`
```ts
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
2.4. Configure the Prisma Client generator [#24-configure-the-prisma-client-generator]
Now, run the following command to create the database tables and generate the Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
2.5. Seed the database [#25-seed-the-database]
Add some seed data to populate the database with sample users and posts.
Create a new file called `seed.ts` in the `prisma/` directory:
```typescript title="prisma/seed.ts"
import { PrismaClient, Prisma } from "../src/generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
const userData: Prisma.UserCreateInput[] = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://www.twitter.com/prisma",
published: true,
},
],
},
},
];
export async function main() {
for (const u of userData) {
await prisma.user.create({ data: u });
}
}
main();
```
Now, tell Prisma how to run this script by updating your `prisma.config.ts`:
```ts title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: `tsx prisma/seed.ts`, // [!code ++]
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Run the seed script:
npm
pnpm
yarn
bun
```bash
npx prisma db seed
```
```bash
pnpm dlx prisma db seed
```
```bash
yarn dlx prisma db seed
```
```bash
bunx --bun prisma db seed
```
And open Prisma Studio to inspect your data:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
3. Integrate Prisma into SvelteKit [#3-integrate-prisma-into-sveltekit]
3.1. Create a Prisma Client [#31-create-a-prisma-client]
Inside your `/src/lib` directory, rename `index.ts` to `prisma.ts`. This file will be used to create and export your Prisma Client instance.
Files in `src/lib` can be accessed from anywhere using the `$lib` alias.
The `DATABASE_URL` is stored in the `.env` file. To access it, you'll need to import it from the [`$env/static/private`](https://svelte.dev/docs/kit/$env-static-private) namespace.
Set up the Prisma client like this:
```tsx title="src/lib/prisma.ts"
import { PrismaClient } from "../generated/prisma/client.js";
import { DATABASE_URL } from "$env/static/private";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: DATABASE_URL,
});
const prisma = new PrismaClient({
adapter,
});
export default prisma;
```
We recommend using a connection pooler (like [Prisma Accelerate](https://www.prisma.io/accelerate)) to manage database connections efficiently.
If you choose not to use one, **avoid** instantiating `PrismaClient` globally in long-lived environments. Instead, create and dispose of the client per request to prevent exhausting your database connections.
3.2. Create a server route [#32-create-a-server-route]
To fetch data from the database on the server side, create a `+page.server.ts` file in your `routes` directory. This file should export a `load` function, which runs on the server before your page renders.
Use the `findMany()` method within a basic `load` function to get a list of users.
Update your `+page.server.ts` file like this:
```typescript title="src/routes/+page.server.ts"
import prisma from "$lib/prisma";
export async function load() {
const users = await prisma.user.findMany({});
return {
users,
};
}
```
At this point, you're only getting data directly on the `User` model — no relations like posts are included yet.
To also fetch each user's posts, we can expand the query using the `include` option. This tells Prisma to join the related `Posts` table in the result.
Update your `findMany()` call like this:
```typescript title="src/routes/+page.server.ts"
import prisma from "$lib/prisma";
export async function load() {
const users = await prisma.user.findMany({
include: {
// [!code ++]
posts: true, // [!code ++]
}, // [!code ++]
});
return {
users,
};
}
```
Now, every user in the result will also include a `posts` array.
3.3. Populate the page [#33-populate-the-page]
In `src/routes/+page.svelte`, strip the file down to the basics and add a `
SvelteKit + Prisma
```
We need to grab the data exported from `+page.server.ts`:
```html title="src/routes/+page.svelte"
SvelteKit + Prisma
```
Now that we have the data, let's map through the users and their posts with Svelte's [`each`](https://svelte.dev/docs/svelte/each) block:
```html title="src/routes/+page.svelte"
SvelteKit + Prisma
{#each data.users as user} // [!code ++]
{user.name}
// [!code ++] {#each user.posts as post} // [!code ++]
// [!code ++] {/each} // [!code ++] {/each} // [!code ++]
```
You're done! You've just created a SvelteKit app with Prisma ORM. Below are some next steps to explore, as well as some more resources to help you get started expanding your project.
Next Steps [#next-steps]
Now that you have a working SvelteKit app connected to a Prisma Postgres database, you can:
* Extend your Prisma schema with more models and relationships
* Add create/update/delete routes and forms
* Explore authentication and validation
More Info [#more-info]
* [Prisma Documentation](/orm)
* [SvelteKit Documentation](https://svelte.dev/docs/kit)
# TanStack Start (/docs/guides/frameworks/tanstack-start)
Introduction [#introduction]
Prisma ORM simplifies database interactions, and [TanStack Start](https://tanstack.com/start/latest/docs/framework/react/guide/server-functions) offers a robust framework for building modern React applications. Together with [Prisma Postgres](https://www.prisma.io/postgres), they provide a seamless full-stack development experience with type-safe queries and efficient data management.
This guide will walk you through integrating Prisma ORM with a Prisma Postgres database in a TanStack Start project from scratch.
Prerequisites [#prerequisites]
* [Node.js 20+](https://nodejs.org)
1. Set up your project [#1-set-up-your-project]
To begin, create a new TanStack Start project.
npm
pnpm
yarn
bun
```bash
npm create @tanstack/start@latest
```
```bash
pnpm create @tanstack/start
```
```bash
yarn create @tanstack/start
```
```bash
bunx @tanstack/create-start@latest
```
* *What would you like to name your project?* tanstack-start-prisma
* *Would you like to use Tailwind CSS?* No
* *Select Toolchain* None
* *Select deployment adapter* Nitro
* *What add-ons would you like for your project?* Prisma
* *Would you like any examples?* No
* *Prisma: Database Provider* Prisma PostgresSQL
This will create a new folder called `tanstack-start-prisma` and provision a new Prisma Postgres database. At the end of the setup, the CLI will display the database connection string:
```
● Database Connection
│
│ Connection String:
│
│ postgresql://username:password@db.prisma.io:5432/postgres
●
```
The database is **temporary** and will be deleted after 24 hours. To keep it permanently, follow the claim link shown in the CLI output.
Navigate to your project directory:
```bash
cd tanstack-start-prisma
```
Then, add the connection string you copied to your `.env` file:
```bash title=".env"
DATABASE_URL="postgresql://username:password@db.prisma.io:5432/postgres"
```
2. Configure Prisma [#2-configure-prisma]
2.1. Define your Prisma Schema [#21-define-your-prisma-schema]
In `schema.prisma`, the model for our todos is defined below the generator and datasource blocks:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model Todo {
id Int @id @default(autoincrement())
title String
createdAt DateTime @default(now())
}
```
This creates a `Todo` model that will be pushed to the database
2.2. Configure the Prisma Client generator [#22-configure-the-prisma-client-generator]
Now, run the following command to create the database tables:
npm
pnpm
yarn
bun
```bash
npm run db:seed -- --name init
```
```bash
pnpm run db:seed --name init
```
```bash
yarn db:seed --name init
```
```bash
bun run db:seed --name init
```
2.3. Seed the database [#23-seed-the-database]
Generate the Prisma Client needed for the project;
npm
pnpm
yarn
bun
```bash
npm run db:generate
```
```bash
pnpm run db:generate
```
```bash
yarn db:generate
```
```bash
bun run db:generate
```
Then seed the project with the `seed.ts` file in the `prisma/` directory:
npm
pnpm
yarn
bun
```bash
npm run db:seed
```
```bash
pnpm run db:seed
```
```bash
yarn db:seed
```
```bash
bun run db:seed
```
And open Prisma Studio to inspect your data:
npm
pnpm
yarn
bun
```bash
npm run db:studio
```
```bash
pnpm run db:studio
```
```bash
yarn db:studio
```
```bash
bun run db:studio
```
3. Integrate Prisma into TanStack Start [#3-integrate-prisma-into-tanstack-start]
3.1 The Prisma Client [#31-the-prisma-client]
Instead of creating a new Prisma Client instance in each file, TanStack Start has a `db.ts` that
creates a single instance that can be shared globally
```tsx title="src/db.ts"
import { PrismaClient } from "./generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
declare global {
var __prisma: PrismaClient | undefined;
}
export const prisma = globalThis.__prisma || new PrismaClient({ adapter });
if (process.env.NODE_ENV !== "production") {
globalThis.__prisma = prisma;
}
```
3.2 Fetch data on load [#32-fetch-data-on-load]
First, import the necessary modules. Then, create a server function using the [`createServerFn`](https://tanstack.com/start/latest/docs/framework/react/guide/server-functions) function. This function will fetch the data from the database using the `.findMany()` method
```typescript title="src/routes/index.tsx"
import { createFileRoute } from "@tanstack/react-router";
import { createServerFn } from "@tanstack/react-start"; // [!code ++]
import { prisma } from '../db'; // [!code ++]
export const Route = createFileRoute("/")({
component: Home,
});
const getTodos = createServerFn({ method: "GET" }).handler(async () => { // [!code ++]
return prisma.todo.findMany(); // [!code ++]
}); // [!code ++]
function Home() {
return (
);
}
```
TanStack Start allows functions to run on load with loader functions in the [`createFileRoute`](https://tanstack.com/router/latest/docs/framework/react/api/router/createFileRouteFunction) function. Fetch the users and their posts on load with this code:
```typescript title="app/routes/index.tsx"
import { createFileRoute } from '@tanstack/react-router';
import { createServerFn } from '@tanstack/react-start';
import { prisma } from '../db';
export const Route = createFileRoute("/")({
component: Home,
loader: () => { // [!code ++]
return getTodos(); // [!code ++]
}, // [!code ++]
});
const getTodos = createServerFn({ method: "GET" }).handler(async () => {
return prisma.todo.findMany();
});
function Home() {
return (
Todos
);
}
```
Store the response from the loader in the main component using [`Route.useLoaderData()`](https://tanstack.com/router/latest/docs/framework/react/api/router/useLoaderDataHook):
```typescript title="app/routes/index.tsx"
import { createServerFn } from "@tanstack/react-start";
import { createFileRoute } from "@tanstack/react-router";
import { prisma } from '../db';
export const Route = createFileRoute("/")({
component: Home,
loader: () => {
return getTodos();
},
});
const getTodos = createServerFn({ method: "GET" }).handler(async () => {
return prisma.todo.findMany();
});
function Home() {
const todos = Route.useLoaderData(); // [!code ++]
return (
Todos
);
}
```
3.3 Display the todos [#33-display-the-todos]
Next, you'll update the home page to display the data retrieved from your database.
Map over the `todos` and display them in a list:
```typescript title="app/routes/index.tsx"
import { createFileRoute } from '@tanstack/react-router';
import { createServerFn } from '@tanstack/react-start';
import { prisma } from '../db';
export const Route = createFileRoute('/')({
component: App,
loader: () => getTodos(),
});
const getTodos = createServerFn({ method: 'GET' }).handler(async () => {
return prisma.todo.findMany();
});
function App() {
const todos = Route.useLoaderData();
return (
{todos.map(todo => (
{todo.title}
))}
);
}
```
This setup will display the todos on your page, fetched directly from your database.
Next steps [#next-steps]
You've successfully integrated Prisma ORM with TanStack Start, creating a seamless full-stack application. Here are a few suggestions for what you can do next:
* Expand your Prisma models to handle more complex data relationships.
* Implement additional CRUD operations to enhance your application's functionality.
* Explore more features of Prisma and TanStack Start to deepen your understanding.
* Check out [Prisma Postgres](https://www.prisma.io/postgres) to see how you can scale your application.
More info [#more-info]
* [Prisma ORM Documentation](/orm)
* [TanStack Start Documentation](https://tanstack.com/start/latest/docs/framework/react/overview)
# AI SDK (with Next.js) (/docs/guides/integrations/ai-sdk)
Introduction [#introduction]
Prisma ORM streamlines database access with type-safe queries, and when paired with [Next.js](https://nextjs.org/) and [AI SDK](https://sdk.vercel.ai/), it creates a powerful foundation for building AI-powered chat applications with persistent storage.
In this guide, you'll learn to build a chat application using AI SDK with Next.js and Prisma ORM to store chat sessions and messages in a Prisma Postgres database. You can find a complete example of this guide on [GitHub](https://github.com/prisma/prisma-examples/tree/latest/orm/ai-sdk-nextjs).
Prerequisites [#prerequisites]
* [Node.js 20+](https://nodejs.org)
* An [OpenAI API key](https://platform.openai.com/api-keys) or other AI provider API key
1. Set up your project [#1-set-up-your-project]
To get started, you'll need to create a new Next.js project.
npm
pnpm
yarn
bun
```bash
npx create-next-app@latest ai-sdk-prisma
```
```bash
pnpm dlx create-next-app@latest ai-sdk-prisma
```
```bash
yarn dlx create-next-app@latest ai-sdk-prisma
```
```bash
bunx --bun create-next-app@latest ai-sdk-prisma
```
It will prompt you to customize your setup. Choose the defaults:
* *Would you like to use TypeScript?* `Yes`
* *Would you like to use ESLint?* `Yes`
* *Would you like to use Tailwind CSS?* `Yes`
* *Would you like your code inside a `src/` directory?* `No`
* *Would you like to use App Router?* (recommended) `Yes`
* *Would you like to use Turbopack for `next dev`?* `Yes`
* \_Would you like to customize the import alias (`@/_`by default)?\*`No`
Navigate to the project directory:
```bash
cd ai-sdk-prisma
```
2. Install and Configure Prisma [#2-install-and-configure-prisma]
2.1. Install dependencies [#21-install-dependencies]
To get started with Prisma, you'll need to install a few dependencies:
npm
pnpm
yarn
bun
```bash
npm install prisma tsx @types/pg --save-dev
```
```bash
pnpm add prisma tsx @types/pg --save-dev
```
```bash
yarn add prisma tsx @types/pg --dev
```
```bash
bun add prisma tsx @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
bun add @prisma/client @prisma/adapter-pg dotenv pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Once installed, initialize Prisma in your project:
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output ../app/generated/prisma
```
```bash
pnpm dlx prisma init --db --output ../app/generated/prisma
```
```bash
yarn dlx prisma init --db --output ../app/generated/prisma
```
```bash
bunx --bun prisma init --db --output ../app/generated/prisma
```
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My Next.js AI SDK Project"
This will create:
* A `prisma` directory with a `schema.prisma` file.
* A `prisma.config.ts` file for configuring Prisma
* A Prisma Postgres database.
* A `.env` file containing the `DATABASE_URL` at the project root.
* The `output` field specifies where the generated Prisma Client will be stored.
2.2. Define your Prisma Schema [#22-define-your-prisma-schema]
In the `prisma/schema.prisma` file, add the following models:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model Session { // [!code ++]
id String @id // [!code ++]
createdAt DateTime @default(now()) // [!code ++]
updatedAt DateTime @updatedAt // [!code ++]
messages Message[] // [!code ++]
} // [!code ++]
// [!code ++]
model Message { // [!code ++]
id String @id @default(cuid()) // [!code ++]
role MessageRole // [!code ++]
content String // [!code ++]
createdAt DateTime @default(now()) // [!code ++]
sessionId String // [!code ++]
session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade) // [!code ++]
} // [!code ++]
// [!code ++]
enum MessageRole { // [!code ++]
USER // [!code ++]
ASSISTANT // [!code ++]
} // [!code ++]
```
This creates three models: `Session`, `Message`, and `MessageRole`.
2.3 Add dotenv to prisma.config.ts [#23-add-dotenv-to-prismaconfigts]
To get access to the variables in the `.env` file, they can either be loaded by your runtime, or by using `dotenv`.
Include an import for `dotenv` at the top of the `prisma.config.ts`
```ts
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
2.4. Configure the Prisma Client generator [#24-configure-the-prisma-client-generator]
Now, run the following command to create the database tables and generate the Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
3. Integrate Prisma into Next.js [#3-integrate-prisma-into-nextjs]
Create a `/lib` directory and a `prisma.ts` file inside it. This file will be used to create and export your Prisma Client instance.
```bash
mkdir lib
touch lib/prisma.ts
```
Set up the Prisma client like this:
```tsx title="lib/prisma.ts"
import { PrismaClient } from "../app/generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const globalForPrisma = global as unknown as {
prisma: PrismaClient;
};
const prisma =
globalForPrisma.prisma ||
new PrismaClient({
adapter,
});
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
export default prisma;
```
We recommend using a connection pooler (like [Prisma Accelerate](https://www.prisma.io/accelerate)) to manage database connections efficiently.
If you choose not to use one, **avoid** instantiating `PrismaClient` globally in long-lived environments. Instead, create and dispose of the client per request to prevent exhausting your database connections.
4. Set up AI SDK [#4-set-up-ai-sdk]
4.1. Install AI SDK and get an API key [#41-install-ai-sdk-and-get-an-api-key]
Install the AI SDK package:
npm
pnpm
yarn
bun
```bash
npm install ai @ai-sdk/react @ai-sdk/openai zod
```
```bash
pnpm add ai @ai-sdk/react @ai-sdk/openai zod
```
```bash
yarn add ai @ai-sdk/react @ai-sdk/openai zod
```
```bash
bun add ai @ai-sdk/react @ai-sdk/openai zod
```
To use AI SDK, you'll need to obtain an API key from [OpenAI](https://platform.openai.com/api-keys).
1. Navigate to [OpenAI API Keys](https://platform.openai.com/api-keys)
2. Click on `Create new secret key`
3. Fill in the form:
* Give your key a name like `Next.js AI SDK Project`
* Select `All` access
4. Click on `Create secret key`
5. Copy the API key
6. Add the API key to the `.env` file:
```text title=".env"
DATABASE_URL=
OPENAI_API_KEY=
```
4.2. Create a route handler [#42-create-a-route-handler]
You need to create a route handler to handle the AI SDK requests. This handler will process chat messages and stream AI responses back to the client.
```bash
mkdir -p app/api/chat
touch app/api/chat/route.ts
```
Set up the basic route handler:
```tsx title="app/api/chat/route.ts"
import { openai } from "@ai-sdk/openai";
import { streamText, UIMessage, convertToModelMessages } from "ai";
export const maxDuration = 300;
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
const result = streamText({
model: openai("gpt-4o"),
messages: convertToModelMessages(messages),
});
return result.toUIMessageStreamResponse();
}
```
This route handler:
1. Extracts the conversation history from the request body
2. Converts UI messages to the format expected by the AI model
3. Streams the AI response back to the client in real-time
To save chat sessions and messages to the database, we need to:
1. Add a session `id` parameter to the request
2. Include an `onFinish` callback in the response
3. Pass the `id` and `messages` parameters to the `saveChat` function (which we'll build next)
```tsx title="app/api/chat/route.ts"
import { openai } from "@ai-sdk/openai";
import { streamText, UIMessage, convertToModelMessages } from "ai";
import { saveChat } from "@/lib/save-chat"; // [!code ++]
export const maxDuration = 300;
export async function POST(req: Request) {
const { messages, id }: { messages: UIMessage[]; id: string } = await req.json(); // [!code highlight]
const result = streamText({
model: openai("gpt-4o"),
messages: convertToModelMessages(messages),
});
return result.toUIMessageStreamResponse({
originalMessages: messages, // [!code ++]
onFinish: async ({ messages }) => {
// [!code ++]
await saveChat(messages, id); // [!code ++]
}, // [!code ++]
});
}
```
4.3. Create a saveChat function [#43-create-a-savechat-function]
Create a new file at `lib/save-chat.ts` to save the chat sessions and messages to the database:
```bash
touch lib/save-chat.ts
```
To start, create a basic function called `saveChat` that will be used to save the chat sessions and messages to the database.
Pass into it the `messages` and `id` parameters typed as `UIMessage[]` and `string` respectively:
```tsx title="lib/save-chat.ts"
import { UIMessage } from "ai";
export async function saveChat(messages: UIMessage[], id: string) {}
```
Now, add the logic to create a session with the given `id`:
```tsx title="lib/save-chat.ts"
import prisma from "./prisma"; // [!code ++]
import { UIMessage } from "ai";
export async function saveChat(messages: UIMessage[], id: string) {
const session = await prisma.session.upsert({
// [!code ++]
where: { id }, // [!code ++]
update: {}, // [!code ++]
create: { id }, // [!code ++]
}); // [!code ++]
// [!code ++]
if (!session) throw new Error("Session not found"); // [!code ++]
}
```
Add the logic to save the messages to the database. You'll only be saving the last two messages *(Users and Assistants last messages)* to avoid any overlapping messages.
```tsx title="lib/save-chat.ts"
import prisma from "./prisma";
import { UIMessage } from "ai";
export async function saveChat(messages: UIMessage[], id: string) {
const session = await prisma.session.upsert({
where: { id },
update: {},
create: { id },
});
if (!session) throw new Error("Session not found");
const lastTwoMessages = messages.slice(-2); // [!code ++]
// [!code ++]
for (const msg of lastTwoMessages) {
// [!code ++]
let content = JSON.stringify(msg.parts); // [!code ++]
if (msg.role === "assistant") {
// [!code ++]
const textParts = msg.parts.filter((part) => part.type === "text"); // [!code ++]
content = JSON.stringify(textParts); // [!code ++]
} // [!code ++]
// [!code ++]
await prisma.message.create({
// [!code ++]
data: {
// [!code ++]
role: msg.role === "user" ? "USER" : "ASSISTANT", // [!code ++]
content: content, // [!code ++]
sessionId: session.id, // [!code ++]
}, // [!code ++]
}); // [!code ++]
} // [!code ++]
}
```
This function:
1. Upserts a session with the given `id` to create a session if it doesn't exist
2. Saves the messages to the database under the `sessionId`
5. Create a messages API route [#5-create-a-messages-api-route]
Create a new file at `app/api/messages/route.ts` to fetch the messages from the database:
```bash
mkdir -p app/api/messages
touch app/api/messages/route.ts
```
Create a basic API route to fetch the messages from the database.
```tsx title="app/api/messages/route.ts"
import { NextResponse } from "next/server";
import prisma from "@/lib/prisma";
export async function GET() {
try {
const messages = await prisma.message.findMany({
orderBy: { createdAt: "asc" },
});
const uiMessages = messages.map((msg) => ({
id: msg.id,
role: msg.role.toLowerCase(),
parts: JSON.parse(msg.content),
}));
return NextResponse.json({ messages: uiMessages });
} catch (error) {
console.error("Error fetching messages:", error);
return NextResponse.json({ messages: [] });
}
}
```
6. Create the UI [#6-create-the-ui]
Replace the content of the `app/page.tsx` file with the following:
```tsx title="app/page.tsx"
"use client";
export default function Page() {}
```
6.1. Set up the basic imports and state [#61-set-up-the-basic-imports-and-state]
Start by importing the required dependencies and setting up the state variables that will manage the chat interface:
```tsx title="app/page.tsx"
"use client";
import { useChat } from "@ai-sdk/react"; // [!code ++]
import { useState, useEffect } from "react"; // [!code ++]
export default function Chat() {
const [input, setInput] = useState(""); // [!code ++]
const [isLoading, setIsLoading] = useState(true); // [!code ++]
// [!code ++]
const { messages, sendMessage, setMessages } = useChat(); // [!code ++]
}
```
6.2. Load existing messages [#62-load-existing-messages]
Create a `useEffect` hook that will automatically fetch and display any previously saved messages when the chat component loads:
```tsx title="app/page.tsx"
"use client";
import { useChat } from "@ai-sdk/react";
import { useState, useEffect } from "react";
export default function Chat() {
const [input, setInput] = useState("");
const [isLoading, setIsLoading] = useState(true);
const { messages, sendMessage, setMessages } = useChat();
useEffect(() => {
// [!code ++]
fetch("/api/messages") // [!code ++]
.then((res) => res.json()) // [!code ++]
.then((data) => {
// [!code ++]
if (data.messages && data.messages.length > 0) {
// [!code ++]
setMessages(data.messages); // [!code ++]
} // [!code ++]
setIsLoading(false); // [!code ++]
}) // [!code ++]
.catch(() => setIsLoading(false)); // [!code ++]
}, [setMessages]); // [!code ++]
}
```
This loads any existing messages from your database when the component first mounts, so users can see their previous conversation history.
6.3. Add message display [#63-add-message-display]
Build the UI components that will show a loading indicator while fetching data and render the chat messages with proper styling:
```tsx title="app/page.tsx"
'use client';
import { useChat } from '@ai-sdk/react';
import { useState, useEffect } from 'react';
export default function Chat() {
const [input, setInput] = useState('');
const [isLoading, setIsLoading] = useState(true);
const { messages, sendMessage, setMessages } = useChat();
useEffect(() => {
fetch('/api/messages')
.then(res => res.json())
.then(data => {
if (data.messages && data.messages.length > 0) {
setMessages(data.messages);
}
setIsLoading(false);
})
.catch(() => setIsLoading(false));
}, [setMessages]);
if (isLoading) { // [!code ++]
return
// [!code ++]
))} // [!code ++]
```
The message rendering logic handles different message types and applies appropriate styling - user messages appear on the right with a dark background, while AI responses appear on the left with a light background.
6.4. Add the input form [#64-add-the-input-form]
Now we need to create the input interface that allows users to type and send messages to the AI:
```tsx title="app/page.tsx"
"use client";
import { useChat } from "@ai-sdk/react";
import { useState, useEffect } from "react";
export default function Chat() {
const [input, setInput] = useState("");
const [isLoading, setIsLoading] = useState(true);
const { messages, sendMessage, setMessages } = useChat();
useEffect(() => {
fetch("/api/messages")
.then((res) => res.json())
.then((data) => {
if (data.messages && data.messages.length > 0) {
setMessages(data.messages);
}
setIsLoading(false);
})
.catch(() => setIsLoading(false));
}, [setMessages]);
if (isLoading) {
return
Loading...
;
}
return (
{messages.map((message) => (
{message.role === "user" ? "YOU " : "AI "}
{message.parts.map((part, i) => {
switch (part.type) {
case "text":
return
{part.text}
;
}
})}
))}
{" "}
// [!code ++]
);
}
```
7. Test your application [#7-test-your-application]
To test your application, run the following command:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
Open your browser and navigate to [`http://localhost:3000`](http://localhost:3000) to see your application in action.
Test it by sending a message to the AI and see if it's saved to the database. Check Prisma Studio to see the messages in the database.
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
You're done! You've just created a AI SDK chat application with Next.js and Prisma. Below are some next steps to explore, as well as some more resources to help you get started expanding your project.
Next Steps [#next-steps]
Now that you have a working AI SDK chat application connected to a Prisma Postgres database, you can:
* Extend your Prisma schema with more models and relationships
* Add create/update/delete routes and forms
* Explore authentication and validation
More Info [#more-info]
* [Prisma Documentation](/orm)
* [AI SDK Documentation](https://ai-sdk.dev/)
# Datadog (/docs/guides/integrations/datadog)
Introduction [#introduction]
In this guide, you'll learn how to set up Datadog tracing for a new Prisma project. By combining the `@prisma/instrumentation` package with Prisma Client extensions, you can capture detailed spans for every database query. These spans are enriched with query metadata and sent to Datadog [using `dd-trace`](https://www.npmjs.com/package/dd-trace), Datadog's official APM library for Node.js, enabling you to monitor, analyze, and gain visibility into your application's database activity.
What are spans and tracing? [#what-are-spans-and-tracing]
* **Spans** are the individual operations or units of work within a distributed system or complex application. Each database query, service call, or external request is represented by a span.
* **Tracing** ties these spans together to form a complete, end-to-end picture of a request’s lifecycle. With tracing, you can visualize bottlenecks, identify problematic queries, and pinpoint where errors occur from your queries.
Why use Datadog with Prisma ORM? [#why-use-datadog-with-prisma-orm]
[Datadog](https://www.datadoghq.com/) provides application performance monitoring (APM), metrics, logs, and dashboards to help you observe and debug production systems.
While Prisma ORM abstracts away SQL and boosts developer productivity, it can obscure query performance without proper instrumentation. By integrating Datadog with Prisma using `@prisma/instrumentation` and [`dd-trace`](https://www.npmjs.com/package/dd-trace), you can automatically capture spans for every database query.
This enables you to:
* Measure latency per query.
* Inspect query arguments and raw SQL.
* Trace Prisma operations in the context of application-level requests.
* Identify bottlenecks related to database access.
This integration provides runtime visibility into Prisma queries with minimal effort, helping you catch slow queries and errors in real time.
Prerequisites [#prerequisites]
Before you begin, ensure you have the following:
* **Node.js** installed (v18+ recommended).
* A local or hosted **PostgreSQL** database.
* A **Datadog** account. If you do not have one, [sign up here](https://www.datadoghq.com/).
* The **Datadog Agent** installed and running on your machine or server where this application will run. You can follow the [Datadog Agent installation docs](https://docs.datadoghq.com/agent/) to set it up.
1. Create a new project [#1-create-a-new-project]
We will start by creating a new Node.js project to demonstrate tracing with Datadog and Prisma ORM. This will be a minimal, standalone setup focused on running and tracing Prisma queries, to understand the instrumentation flow in isolation.
If you're integrating tracing into an existing Prisma project, you can skip this step and directly follow from [the setup tracing section](#4-set-up-datadog-tracing). Just make sure you apply the changes in your project's equivalent folder structure.
npm
pnpm
yarn
bun
```bash
mkdir prisma-datadog-tracing
cd prisma-datadog-tracing
npm init -y
```
```bash
mkdir prisma-datadog-tracing
cd prisma-datadog-tracing
pnpm init -y
```
```bash
mkdir prisma-datadog-tracing
cd prisma-datadog-tracing
yarn init -y
```
```bash
mkdir prisma-datadog-tracing
cd prisma-datadog-tracing
bun init -y
```
In this setup, you'll:
* Define a Prisma schema with basic models.
* Connect to a Postgres database (Prisma Postgres or your own).
* Configure Datadog tracing for all queries using `@prisma/instrumentation` and `dd-trace`.
* Run a sample script that executes Prisma operations and sends spans to Datadog.
2. Set up Prisma ORM [#2-set-up-prisma-orm]
In this section, you will install Prisma, create your schema, and generate the Prisma Client. This prepares your application to run database queries—queries that you will trace with Datadog.
2.1. Install and initialize Prisma ORM [#21-install-and-initialize-prisma-orm]
Run the following commands to install Prisma and a minimal TypeScript runner:
npm
pnpm
yarn
bun
```bash
npm install -D prisma tsx
```
```bash
pnpm add -D prisma tsx
```
```bash
yarn add --dev prisma tsx
```
```bash
bun add --dev prisma tsx
```
Then initialize Prisma with the `--db` flag to create a [new Prisma Postgres](/postgres) instance:
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output ../src/generated/prisma
```
```bash
pnpm dlx prisma init --db --output ../src/generated/prisma
```
```bash
yarn dlx prisma init --db --output ../src/generated/prisma
```
```bash
bunx --bun prisma init --db --output ../src/generated/prisma
```
You will be prompted to name your database and select the closest region. For clarity, choose a memorable name (e.g., `My Datadog Project`).
This command does the following:
* Creates a `prisma` directory with a `schema.prisma` file.
* Generates the Prisma Client in the `/src/generated/prisma` directory (as specified in the `--output` flag).
* Creates a `.env` file at the project root with your database connection string (`DATABASE_URL`).
The `.env` file should contain a standard connection string:
```text title=".env"
# Placeholder url you have to replace
DATABASE_URL="postgresql://janedoe:mypassword@localhost:5432/mydb?schema=sample"
```
Install the driver adapter for PostgreSQL:
npm
pnpm
yarn
bun
```bash
npm i @prisma/adapter-pg pg
```
```bash
pnpm add @prisma/adapter-pg pg
```
```bash
yarn add @prisma/adapter-pg pg
```
```bash
bun add @prisma/adapter-pg pg
```
npm
pnpm
yarn
bun
```bash
npm i -D @types/pg
```
```bash
pnpm add -D @types/pg
```
```bash
yarn add --dev @types/pg
```
```bash
bun add --dev @types/pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
2.2. Define models [#22-define-models]
Now, open `prisma/schema.prisma` and update your generator block and models. Replace the `generator` block with the following, and add a `User` and a `Post` model:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
posts Post[] // [!code ++]
} // [!code ++]
// [!code ++]
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
published Boolean @default(false) // [!code ++]
authorId Int // [!code ++]
author User @relation(fields: [authorId], references: [id]) // [!code ++]
} // [!code ++]
```
Create a `prisma.config.ts` file to configure Prisma:
```typescript title="prisma.config.ts"
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config"; // [!code ++]
// [!code ++]
export default defineConfig({
// [!code ++]
schema: "prisma/schema.prisma", // [!code ++]
migrations: {
// [!code ++]
path: "prisma/migrations", // [!code ++]
}, // [!code ++]
datasource: {
// [!code ++]
url: env("DATABASE_URL"), // [!code ++]
}, // [!code ++]
}); // [!code ++]
```
You'll need to install the `dotenv` package if you haven't already:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
2.3. Generate the Prisma Client and run migrations [#23-generate-the-prisma-client-and-run-migrations]
Generate the Prisma Client and apply your schema to your database:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name "init"
```
```bash
pnpm dlx prisma migrate dev --name "init"
```
```bash
yarn dlx prisma migrate dev --name "init"
```
```bash
bunx --bun prisma migrate dev --name "init"
```
This creates the tables according to your schema in the Postgres database and generates a client for you to interact with the database.
3. Install required dependencies for tracing [#3-install-required-dependencies-for-tracing]
In addition to Prisma, you will need the following packages for Datadog tracing:
npm
pnpm
yarn
bun
```bash
npm install @prisma/instrumentation \
dd-trace
```
```bash
pnpm add @prisma/instrumentation \
dd-trace
```
```bash
yarn add @prisma/instrumentation \
dd-trace
```
```bash
bun add @prisma/instrumentation \
dd-trace
```
Also ensure you have development dependencies for TypeScript:
npm
pnpm
yarn
bun
```bash
npm install -D typescript
```
```bash
pnpm add -D typescript
```
```bash
yarn add --dev typescript
```
```bash
bun add --dev typescript
```
Here's a quick overview:
* **`@prisma/instrumentation`**: Instruments Prisma queries so they appear as spans in your tracer.
* **`dd-trace`**: Official Node.js tracing library from Datadog.
4. Set up Datadog tracing [#4-set-up-datadog-tracing]
Create a `tracer.ts` file in the `src` folder to instantiate your tracing logic:
```bash
touch src/tracer.ts
```
4.1. Configure the tracer [#41-configure-the-tracer]
Open `src/tracer.ts` and add the following code:
```ts title="src/tracer.ts"
import tracer from "dd-trace";
tracer.init({
profiling: true,
logInjection: true,
runtimeMetrics: true,
dbmPropagationMode: "full",
env: "dev",
sampleRate: 1,
service: "prisma-datadog-tracing",
version: "1.0.0",
});
export { tracer };
```
Explanation [#explanation]
* **`tracer.init`** configures `dd-trace` with a `service` name. This name appears in Datadog under your `APM` > `Services` list.
* **`@prisma/instrumentation`** automatically logs each Prisma query as a Datadog span.
5. Instantiate Prisma and run queries [#5-instantiate-prisma-and-run-queries]
5.1. Create the Prisma Client instance [#51-create-the-prisma-client-instance]
Create a `src/client.ts` to hold your Prisma Client instantiation:
```ts title="src/client.ts"
import { tracer } from "./tracer";
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,
log: [{ emit: "event", level: "query" }],
})
.$on("query", (e) => {
const span = tracer.startSpan(`prisma_raw_query`, {
childOf: tracer.scope().active() || undefined,
tags: {
"prisma.rawquery": e.query,
},
});
span.finish();
})
.$extends({
query: {
async $allOperations({ operation, model, args, query }) {
const span = tracer.startSpan(`prisma_query_${model?.toLowerCase()}_${operation}`, {
tags: {
"prisma.operation": operation,
"prisma.model": model,
"prisma.args": JSON.stringify(args),
"prisma.rawQuery": query,
},
childOf: tracer.scope().active() || undefined,
});
try {
const result = await query(args);
span.finish();
return result;
} catch (error) {
span.setTag("error", error);
span.finish();
throw error;
}
},
},
});
export { prisma };
```
The setup above gives you more control over how queries are traced:
* Tracing is initialized as early as possible by importing the `tracer` before creating the Prisma Client.
* The `$on("query")` hook captures raw SQL queries and sends them as standalone spans.
* The `$allOperations` extension wraps all Prisma operations in custom spans, allowing you to tag them with metadata like the model, operation type, and arguments.
Unlike the `@prisma/instrumentation` package, which offers automatic tracing out of the box, this manual setup gives you full control over how each span is structured and tagged. It's helpful when you need custom span names, additional metadata, a simpler setup, or when working around limitations or compatibility issues in the OpenTelemetry ecosystem. It also allows you to adapt tracing behavior based on query context, which can be especially useful in complex applications.
5.2. Add a script that performs queries [#52-add-a-script-that-performs-queries]
Create a `src/index.ts` file and add code to perform queries to your database and send traces to Datadog:
```typescript title="src/index.ts"
import { tracer } from "./tracer";
import { PrismaInstrumentation, registerInstrumentations } from "@prisma/instrumentation";
import { prisma } from "./client";
const provider = new tracer.TracerProvider();
registerInstrumentations({
instrumentations: [new PrismaInstrumentation()],
tracerProvider: provider,
});
provider.register();
async function main() {
const user1Email = `alice${Date.now()}@prisma.io`;
const user2Email = `bob${Date.now()}@prisma.io`;
let alice, bob;
// 1. Create users concurrently
try {
[alice, bob] = await Promise.all([
prisma.user.create({
data: {
email: user1Email,
name: "Alice",
posts: {
create: {
title: "Join the Prisma community on Discord",
content: "https://pris.ly/discord",
published: true,
},
},
},
include: { posts: true },
}),
prisma.user.create({
data: {
email: user2Email,
name: "Bob",
posts: {
create: [
{
title: "Check out Prisma on YouTube",
content: "https://pris.ly/youtube",
published: true,
},
{
title: "Follow Prisma on Twitter",
content: "https://twitter.com/prisma/",
published: false,
},
],
},
},
include: { posts: true },
}),
]);
console.log(
`✅ Created users: ${alice.name} (${alice.posts.length} post) and ${bob.name} (${bob.posts.length} posts)`,
);
} catch (err) {
console.error("❌ Error creating users:", err);
return;
}
// 2. Fetch all published posts
try {
const publishedPosts = await prisma.post.findMany({
where: { published: true },
});
console.log(`✅ Retrieved ${publishedPosts.length} published post(s).`);
} catch (err) {
console.error("❌ Error fetching published posts:", err);
}
// 3. Create & publish a post for Alice
let post;
try {
post = await prisma.post.create({
data: {
title: "Join the Prisma Discord community",
content: "https://pris.ly/discord",
published: false,
author: { connect: { email: user1Email } },
},
});
console.log(`✅ Created draft post for Alice (ID: ${post.id})`);
} catch (err) {
console.error("❌ Error creating draft post for Alice:", err);
return;
}
try {
post = await prisma.post.update({
where: { id: post.id },
data: { published: true },
});
console.log("✅ Published Alice’s post:", post);
} catch (err) {
console.error("❌ Error publishing Alice's post:", err);
}
// 4. Fetch all posts by Alice
try {
const alicePosts = await prisma.post.findMany({
where: { author: { email: user1Email } },
});
console.log(`✅ Retrieved ${alicePosts.length} post(s) by Alice.`, alicePosts);
} catch (err) {
console.error("❌ Error fetching Alice's posts:", err);
}
}
// Entrypoint
main()
.catch((err) => {
console.error("❌ Unexpected error:", err);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
console.log("🔌 Disconnected from database.");
});
```
If you encounter a linting error on the line `tracerProvider: provider` due to incompatible types, it's likely caused by a version mismatch in the `@opentelemetry/api` package.
To resolve this, add the following override to your package.json:
```json
"overrides": { // [!code ++]
"@opentelemetry/api": "1.8.0" // [!code ++]
} // [!code ++]
```
This is necessary because [`dd-trace` does not yet support version `1.9.0` or above of `@opentelemetry/api`](https://github.com/DataDog/dd-trace-js#datadog-with-opentelemetery).
After updating the `package.json`, reinstall your dependencies:
npm
pnpm
yarn
bun
```bash
npm i
```
```bash
pnpm i
```
```bash
yarn install
```
```bash
bun install
```
This should resolve the linting error.
6. Run your queries and see the traces [#6-run-your-queries-and-see-the-traces]
Run the queries:
npm
pnpm
yarn
bun
```bash
npx tsx src/index.ts
```
```bash
pnpm dlx tsx src/index.ts
```
```bash
yarn dlx tsx src/index.ts
```
```bash
bunx --bun tsx src/index.ts
```
This executes your script, which:
* Registers the Datadog tracer.
* Performs multiple Prisma queries.
* Logs the result of each operation.
Then, confirm the traces in Datadog:
* Open your [Datadog APM page](https://docs.datadoghq.com/tracing/).
* Navigate to **APM > Traces > Explorer** in the side panel.
* Explore the list of traces and spans, each representing a Prisma query (e.g. `prisma:query`).
Depending on your Datadog setup, it may take a minute or two for new data to appear. Refresh or wait briefly if you do not see traces right away.
Next steps [#next-steps]
You have successfully:
* Created a Prisma ORM project with [Prisma Postgres](/postgres).
* Set up Datadog tracing using `@prisma/instrumentation` and `dd-trace`.
* Verified that database operations show up as spans in Datadog.
To improve your observability further:
* Add more instrumentation for your HTTP server or other services (e.g., Express, Fastify).
* [Create Dashboards to view](https://docs.datadoghq.com/dashboards/) key metrics from your data.
For additional guidance, check out:
* [Datadog APM documentation](https://docs.datadoghq.com/tracing/).
* [Prisma tracing docs](/orm/prisma-client/observability-and-logging/opentelemetry-tracing).
# Prisma Postgres on Deno (/docs/guides/integrations/deno)
[Deno Deploy](https://deno.com/deploy) includes a feature that allows you to provision a Prisma Postgres database directly within the platform. This guide demonstrates how to integrate Prisma Postgres in a Deno Deploy project using a minimal Deno application that logs HTTP requests to the database.
By the end of this guide, you will have a deployed Deno app that writes to and reads from a Prisma Postgres database provisioned in Deno Deploy, using Prisma Client with `runtime = "deno"`.
Prerequisites [#prerequisites]
* A [Deno Deploy](https://deno.com/deploy) account
* Deno runtime installed ([installation guide](https://docs.deno.com/runtime/#install-deno))
* [Deno extension for VS Code](https://docs.deno.com/runtime/reference/vscode/)
1. Create and set up a new Deno project [#1-create-and-set-up-a-new-deno-project]
Create a new Deno project using the `deno init` command, which generates a basic project structure with a main entry file and configuration.
```bash
deno init prisma-postgres-deno-deploy
cd prisma-postgres-deno-deploy
```
1.1 Configure VS Code for Deno [#11-configure-vs-code-for-deno]
To ensure VS Code recognizes this as a Deno project and provides proper TypeScript validation, you need to initialize the workspace. Without this, VS Code will show errors when using Deno-specific APIs like `Deno.serve`.
Install the [Deno extension for VS Code](https://docs.deno.com/runtime/reference/vscode/), then:
1. Select **View** > **Command Palette** *(or press `Cmd+Shift+P` on macOS or `Ctrl+Shift+P` on Windows)*
2. Run the command **Deno: Initialize Workspace Configuration**
1.2 Create a basic HTTP server [#12-create-a-basic-http-server]
Update the `main.ts` file to create a simple HTTP server that responds with "Hello, World!", establishing the foundation for your application before adding database functionality.
```tsx title="main.ts"
function handler(_req: Request): Response {
return new Response("Hello, World!");
}
Deno.serve(handler);
```
You can test the server locally by running:
```bash
deno run dev
```
Visit `localhost:8000` in your browser to see the application running.
1.3 Push initial project to GitHub [#13-push-initial-project-to-github]
To connect your project to Deno Deploy and get a database connection string, you need to have a successful deployment. Set up a GitHub repository and push your project to it.
2. Deploy the project to Deno Deploy [#2-deploy-the-project-to-deno-deploy]
Deploy your repository to Deno Deploy. Any subsequent commits will trigger automatic redeployments. You need to deploy now, as the database string requires a successful deployment to generate.
1. Navigate to the [Deno Deploy dashboard](https://dash.deno.com/) and select **New App**
2. Configure GitHub app permissions by following GitHub's prompts
3. Choose your GitHub repository in the Deno Deploy interface
4. Click **Create App** to complete the deployment
The application will deploy automatically.
3. Provision a Prisma Postgres database [#3-provision-a-prisma-postgres-database]
Provision a Prisma Postgres database in Deno Deploy, and link it to your application:
1. Go to the **Databases** section in the Deno Deploy dashboard
2. Select **Provision Database** and choose **Prisma Postgres**
3. Complete the database configuration and confirm provisioning
4. Click **Assign** and select your application
5. Copy the **Production connection string**
6. Add the connection string to your `.env` file:
```text
DATABASE_URL="postgresql://:@db.prisma.io:5432/-production"
```
4. Configure Prisma ORM [#4-configure-prisma-orm]
4.1 Enable environment variables [#41-enable-environment-variables]
To access the database connection string during local development, configure Deno to load environment variables from your `.env` file using the `--env-file` flag.
Update the `dev` task in `deno.json`:
```json title="deno.json"
{
"tasks": {
"dev": "deno run --watch --env-file main.ts" // [!code highlight]
}
}
```
4.2 Initialize Prisma and create schema [#42-initialize-prisma-and-create-schema]
Install the Prisma Client, PostgreSQL adapter, and development dependencies:
npm
pnpm
yarn
bun
```bash
deno install npm:@prisma/client npm:@prisma/adapter-pg npm:pg npm:prisma npm:@types/pg
```
```bash
deno install npm undefined
# couldn't auto-convert command:@prisma/client npm undefined
# couldn't auto-convert command:@prisma/adapter-pg npm undefined
# couldn't auto-convert command:pg npm undefined
# couldn't auto-convert command:prisma npm undefined
# couldn't auto-convert command:@types/pg
```
```bash
deno install npm undefined
# couldn't auto-convert command:@prisma/client npm undefined
# couldn't auto-convert command:@prisma/adapter-pg npm undefined
# couldn't auto-convert command:pg npm undefined
# couldn't auto-convert command:prisma npm undefined
# couldn't auto-convert command:@types/pg
```
```bash
deno install npm
# couldn't auto-convert command:@prisma/client npm
# couldn't auto-convert command:@prisma/adapter-pg npm
# couldn't auto-convert command:pg npm
# couldn't auto-convert command:prisma npm
# couldn't auto-convert command:@types/pg
```
Initialize Prisma in your project, which creates the necessary configuration files and folder structure for defining your database models.
npm
pnpm
yarn
bun
```bash
npx prisma init
```
```bash
pnpm dlx prisma init
```
```bash
yarn dlx prisma init
```
```bash
bunx --bun prisma init
```
Update the Prisma schema with these changes:
1. Change the client output from `prisma-client-js` to `prisma-client`.
2. Add the Deno runtime configuration. *(This is required for Deno to run properly)*
3. Add the Log model for storing request information.
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client" // [!code highlight]
output = "../generated/prisma"
runtime = "deno" // [!code ++]
}
datasource db {
provider = "postgresql"
}
model Log { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
level Level // [!code ++]
message String // [!code ++]
meta Json // [!code ++]
} // [!code ++]
// [!code ++]
enum Level { // [!code ++]
Info // [!code ++]
Warn // [!code ++]
Error // [!code ++]
} // [!code ++]
```
4.3 Generate and apply migrations [#43-generate-and-apply-migrations]
Migrations create the actual database tables based on your Prisma schema. This command generates SQL migration files and executes them against your database, creating the `Log` table with the specified fields.
npm
pnpm
yarn
bun
```bash
deno run -A npm:prisma migrate dev --name init
deno run -A npm:prisma generate
```
```bash
deno run -A npm undefined
# couldn't auto-convert command:prisma migrate dev --name init
deno run -A npm undefined
# couldn't auto-convert command:prisma generate
```
```bash
deno run -A npm undefined
# couldn't auto-convert command:prisma migrate dev --name init
deno run -A npm undefined
# couldn't auto-convert command:prisma generate
```
```bash
deno run -A npm
# couldn't auto-convert command:prisma migrate dev --name init
deno run -A npm
# couldn't auto-convert command:prisma generate
```
5. Update the application to use Prisma [#5-update-the-application-to-use-prisma]
Now that the database is configured, update your application to interact with it. This implementation creates a logging system that captures every HTTP request, stores it in the database, and returns the logged entry as JSON.
```tsx title="main.ts"
import { PrismaClient } from "./generated/prisma/client.ts";
import { PrismaPg } from "npm:@prisma/adapter-pg";
import process from "node:process";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
const prisma = new PrismaClient({
adapter,
});
async function handler(request: Request) {
const url = new URL(request.url);
if (url.pathname === "/favicon.ico") {
return new Response(null, { status: 204 });
}
const log = await prisma.log.create({
data: {
level: "Info",
message: `${request.method} ${request.url}`,
meta: {
headers: JSON.stringify(request.headers),
},
},
});
const body = JSON.stringify(log, null, 2);
return new Response(body, {
headers: { "content-type": "application/json; charset=utf-8" },
});
}
Deno.serve(handler);
```
Test the application locally by running:
```bash
deno run dev
```
It may ask you for access to your environment variables. Select **Allow** to grant access.
Visit `localhost:8000` in your browser to see the application running. You should see a JSON response containing the log entry:
```json
{
"id": 1,
"level": "Info",
"message": "GET http://localhost:8000/",
"meta": {
"headers": "..."
}
}
```
6. Deploy the application [#6-deploy-the-application]
The build command must generate the Prisma Client code to ensure it is available in production.
6.1 Update build command in Deno Deploy [#61-update-build-command-in-deno-deploy]
1. Go to the application in Deno Deploy and click **Settings**
2. Under **Build configuration**, hit **Edit** and add `deno run -A npm:prisma generate` to the build command
3. Click **Save**
6.2 Push changes to GitHub [#62-push-changes-to-github]
Commit and push your changes to trigger an automatic deployment:
```bash
git add .
git commit -m "added prisma"
git push
```
Navigate back to Deno Deploy and you should see a successful build. Once deployed, click the deployment URL at the top right of the dashboard.
6.3 Verify the deployment [#63-verify-the-deployment]
When you visit your deployed application, you should see a response that looks like this:
```json
{
"id": 1,
"level": "Info",
"message": "GET https://prisma-postgres-deno-deploy..deno.net/",
"meta": {
"headers": "{}"
}
}
```
You're done! Each time you refresh the page, a new log entry is created in your database.
Next Steps [#next-steps]
Now that you have a working Deno app connected to a Prisma Postgres database, you can:
* **Enhance your data model** - Add relationships, validations, and indexes to your Prisma schema
* **Secure your API** - Implement authentication, rate limiting, and proper error handling
* **Improve deployment** - Set up CI/CD, monitoring, and database backups for production
More info [#more-info]
* [Prisma ORM Documentation](/orm)
* [Deno Deploy Documentation](https://docs.deno.com/deploy)
# Embedded Prisma Studio (with Next.js) (/docs/guides/integrations/embed-studio)
Prisma Studio can be embedded directly into your Next.js application using the [`@prisma/studio-core`](https://www.npmjs.com/package/@prisma/studio-core) package. This guide walks you through the setup so you can manage your database from within your app instead of running Prisma Studio separately.
After completing the guide, you'll have a Next.js app with Prisma Studio embedded, allowing you to browse and edit your database directly from your application interface:
Embedding Prisma Studio can be useful in scenarios such as:
* Building a quick admin dashboard for editing data
* Supporting multi-tenant applications where each user has their own database
* Giving users an easy way to view and edit their data
[**Embeddable Prisma Studio**](/studio/integrations/embedding) is *free* and licensed under Apache 2.0.
✔️ Free to use in production
⚠️ Prisma branding must remain visible and unchanged
🔐 To remove branding or learn about upcoming partner-only features, reach out at [partnerships@prisma.io](mailto\:partnerships@prisma.io)
Currently, Embedded Prisma Studio supports **PostgreSQL, SQLite, and MySQL** databases.
Prerequisites [#prerequisites]
* [Node.js 20+](https://nodejs.org)
* Basic knowledge of React and Next.js
* A database (PostgreSQL, SQLite, or MySQL)
1. Setting up Next.js [#1-setting-up-nextjs]
First, create a new Next.js project from the directory where you want to build your app:
npm
pnpm
yarn
bun
```bash
npx create-next-app@latest nextjs-studio-embed
```
```bash
pnpm dlx create-next-app@latest nextjs-studio-embed
```
```bash
yarn dlx create-next-app@latest nextjs-studio-embed
```
```bash
bunx --bun create-next-app@latest nextjs-studio-embed
```
You will be prompted to answer a few questions about your project. Select all of the defaults.
For reference, those are:
* TypeScript
* ESLint
* Tailwind CSS
* No `src` directory
* App Router
* Turbopack
* Select default import alias
Then, navigate to the project directory:
```bash
cd nextjs-studio-embed
```
2. Setting up Prisma ORM and Prisma Postgres [#2-setting-up-prisma-orm-and-prisma-postgres]
2.1. Install Prisma dependencies [#21-install-prisma-dependencies]
Install the required Prisma packages:
Prisma Postgres (PostgreSQL) [#prisma-postgres-postgresql]
npm
pnpm
yarn
bun
```bash
npm install prisma tsx @types/pg --save-dev
npm install @prisma/extension-accelerate @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
pnpm add prisma tsx @types/pg --save-dev
pnpm add @prisma/extension-accelerate @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
yarn add prisma tsx @types/pg --dev
yarn add @prisma/extension-accelerate @prisma/client @prisma/adapter-pg dotenv pg
```
```bash
bun add prisma tsx @types/pg --dev
bun add @prisma/extension-accelerate @prisma/client @prisma/adapter-pg dotenv pg
```
SQLite [#sqlite]
npm
pnpm
yarn
bun
```bash
npm install prisma tsx --save-dev
npm install @prisma/client @prisma/adapter-sqlite dotenv better-sqlite3
```
```bash
pnpm add prisma tsx --save-dev
pnpm add @prisma/client @prisma/adapter-sqlite dotenv better-sqlite3
```
```bash
yarn add prisma tsx --dev
yarn add @prisma/client @prisma/adapter-sqlite dotenv better-sqlite3
```
```bash
bun add prisma tsx --dev
bun add @prisma/client @prisma/adapter-sqlite dotenv better-sqlite3
```
MySQL [#mysql]
npm
pnpm
yarn
bun
```bash
npm install prisma tsx @types/mysql2 --save-dev
npm install @prisma/client @prisma/adapter-mysql dotenv mysql2
```
```bash
pnpm add prisma tsx @types/mysql2 --save-dev
pnpm add @prisma/client @prisma/adapter-mysql dotenv mysql2
```
```bash
yarn add prisma tsx @types/mysql2 --dev
yarn add @prisma/client @prisma/adapter-mysql dotenv mysql2
```
```bash
bun add prisma tsx @types/mysql2 --dev
bun add @prisma/client @prisma/adapter-mysql dotenv mysql2
```
For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
2.2. Initialize Prisma with Prisma Postgres [#22-initialize-prisma-with-prisma-postgres]
Initialize Prisma in your project and create a Prisma Postgres database:
Prisma Postgres (PostgreSQL) [#prisma-postgres-postgresql-1]
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output ../app/generated/prisma
```
```bash
pnpm dlx prisma init --db --output ../app/generated/prisma
```
```bash
yarn dlx prisma init --db --output ../app/generated/prisma
```
```bash
bunx --bun prisma init --db --output ../app/generated/prisma
```
SQLite [#sqlite-1]
npm
pnpm
yarn
bun
```bash
npx prisma init --datasource-provider sqlite --output ../app/generated/prisma
```
```bash
pnpm dlx prisma init --datasource-provider sqlite --output ../app/generated/prisma
```
```bash
yarn dlx prisma init --datasource-provider sqlite --output ../app/generated/prisma
```
```bash
bunx --bun prisma init --datasource-provider sqlite --output ../app/generated/prisma
```
MySQL [#mysql-1]
npm
pnpm
yarn
bun
```bash
npx prisma init --datasource-provider mysql --output ../app/generated/prisma
```
```bash
pnpm dlx prisma init --datasource-provider mysql --output ../app/generated/prisma
```
```bash
yarn dlx prisma init --datasource-provider mysql --output ../app/generated/prisma
```
```bash
bunx --bun prisma init --datasource-provider mysql --output ../app/generated/prisma
```
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My \***\*\_\_\*\*** Project"
The `prisma init` command creates:
* A `prisma/` directory with your `schema.prisma` file
* A `prisma.config.ts` file for configuring Prisma
* A new Prisma Postgres database or local SQLite database file
* A `.env` file with your `DATABASE_URL`
* An output directory at `app/generated/prisma` for the Prisma Client
2.3. Define your database schema [#23-define-your-database-schema]
Open `prisma/schema.prisma` and replace the content with:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql" // this will change depending on the --datasource-provider flag used in the init command
}
// [!code ++]
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
name String // [!code ++]
email String @unique // [!code ++]
posts Post[] // [!code ++]
} // [!code ++]
// [!code ++]
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
content String? // [!code ++]
published Boolean @default(false) // [!code ++]
authorId Int // [!code ++]
author User @relation(fields: [authorId], references: [id]) // [!code ++]
createdAt DateTime @default(now()) // [!code ++]
} // [!code ++]
// [!code ++]
```
2.4 Add dotenv to prisma.config.ts [#24-add-dotenv-to-prismaconfigts]
To get access to the variables in the `.env` file, they can either be loaded by your runtime, or by using `dotenv`.
Include an import for `dotenv` at the top of the `prisma.config.ts`
```ts
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
2.5. Apply the schema to your database [#25-apply-the-schema-to-your-database]
Generate the Prisma Client and apply the schema:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
This creates the tables in your Prisma Postgres database and generates the Prisma Client.
If you are using SQLite or MySQL, this creates the tables in your database and generates the Prisma Client.
2.6. Seed your database (optional) [#26-seed-your-database-optional]
Create a seed file to add some sample data. Create a `seed.ts` file in the `prisma` folder and add the following code:
Prisma Postgres (PostgreSQL)
SQLite
MySQL
```typescript title="prisma/seed.ts"
import { PrismaClient } from "../app/generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
async function main() {
// Create users
const user1 = await prisma.user.create({
data: {
name: "Alice Johnson",
email: "alice@example.com",
},
});
const user2 = await prisma.user.create({
data: {
name: "Bob Smith",
email: "bob@example.com",
},
});
// Create posts
await prisma.post.create({
data: {
title: "Getting Started with Next.js",
content: "Next.js is a powerful React framework...",
published: true,
authorId: user1.id,
},
});
await prisma.post.create({
data: {
title: "Database Management with Prisma",
content: "Prisma makes database management easy...",
published: false,
authorId: user2.id,
},
});
console.log("Database seeded successfully!");
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
```typescript title="prisma/seed.ts"
import { PrismaClient } from "../app/generated/prisma/client";
import { PrismaSQLite } from "@prisma/adapter-sqlite";
const adapter = new PrismaSQLite({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
async function main() {
// Create users
const user1 = await prisma.user.create({
data: {
name: "Alice Johnson",
email: "alice@example.com",
},
});
const user2 = await prisma.user.create({
data: {
name: "Bob Smith",
email: "bob@example.com",
},
});
// Create posts
await prisma.post.create({
data: {
title: "Getting Started with Next.js",
content: "Next.js is a powerful React framework...",
published: true,
authorId: user1.id,
},
});
await prisma.post.create({
data: {
title: "Database Management with Prisma",
content: "Prisma makes database management easy...",
published: false,
authorId: user2.id,
},
});
console.log("Database seeded successfully!");
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
```typescript title="prisma/seed.ts"
import { PrismaClient } from "../app/generated/prisma/client";
import { PrismaMySQL } from "@prisma/adapter-mysql";
const adapter = new PrismaMySQL({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
async function main() {
// Create users
const user1 = await prisma.user.create({
data: {
name: "Alice Johnson",
email: "alice@example.com",
},
});
const user2 = await prisma.user.create({
data: {
name: "Bob Smith",
email: "bob@example.com",
},
});
// Create posts
await prisma.post.create({
data: {
title: "Getting Started with Next.js",
content: "Next.js is a powerful React framework...",
published: true,
authorId: user1.id,
},
});
await prisma.post.create({
data: {
title: "Database Management with Prisma",
content: "Prisma makes database management easy...",
published: false,
authorId: user2.id,
},
});
console.log("Database seeded successfully!");
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
Add a seed script to your `prisma.config.ts`:
Prisma Postgres (PostgreSQL)
SQLite
MySQL
```ts title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: `tsx prisma/seed.ts`,
},
datasource: {
url: env("DIRECT_URL"),
},
});
```
```ts title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: `tsx prisma/seed.ts`,
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
```ts title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: `tsx prisma/seed.ts`,
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Run the seed script:
npm
pnpm
yarn
bun
```bash
npx prisma db seed
```
```bash
pnpm dlx prisma db seed
```
```bash
yarn dlx prisma db seed
```
```bash
bunx --bun prisma db seed
```
3. Setting up the embedded Prisma Studio in your app [#3-setting-up-the-embedded-prisma-studio-in-your-app]
Now that you have Prisma ORM and Prisma Postgres set up, you can embed Prisma Studio in your Next.js app.
3.1. Install the Prisma Studio Core package [#31-install-the-prisma-studio-core-package]
Install the [`@prisma/studio-core` package](https://www.npmjs.com/package/@prisma/studio-core) that provides the embeddable components:
npm
pnpm
yarn
bun
```bash
npm install @prisma/studio-core
```
```bash
pnpm add @prisma/studio-core
```
```bash
yarn add @prisma/studio-core
```
```bash
bun add @prisma/studio-core
```
If you encounter a dependency resolution error while installing `@prisma/studio-core`, you can force the install with:
npm
pnpm
yarn
bun
```bash
npm install @prisma/studio-core --force
```
```bash
pnpm add @prisma/studio-core --force
```
```bash
yarn add @prisma/studio-core --force
```
```bash
bun add @prisma/studio-core --force
```
If you are using yarn, pnpm, or another package manager, use the equivalent flag for your tool.
The `@prisma/studio-core` provides `Studio`, a React component which renders Prisma Studio for your database. The `Studio` component accepts an *executor* which accesses a custom endpoint in your backend. The backend uses your API key to identify the correct Prisma Postgres instance and sends the SQL query to it.
3.2. Create a Studio wrapper component [#32-create-a-studio-wrapper-component]
Create a `components` folder and add a new file called `StudioWrapper.tsx`. This file will wrap the Studio component and provide a consistent layout:
```tsx title="components/StudioWrapper.tsx"
"use client";
import "@prisma/studio-core/ui/index.css";
import { ReactNode } from "react";
interface StudioWrapperProps {
children: ReactNode;
}
export default function StudioWrapper({ children }: StudioWrapperProps) {
return (
Database Studio
Powered by Prisma Studio
{children}
);
}
```
3.3. Create an API endpoint to send the SQL queries to Prisma Studio [#33-create-an-api-endpoint-to-send-the-sql-queries-to-prisma-studio]
Next, set up a backend endpoint that Prisma Studio can communicate with. This endpoint receives SQL queries from the embedded Studio UI, forwards them to your Prisma Postgres database, and then returns the results (or errors) back to the frontend.
If you are using SQLite or MySQL, you can still embed Studio, but your `/api/studio` implementation needs to use the correct executor for your database.
To do this, create a new folder called `api` inside the `app` directory. Inside it, add a `studio` folder with a `route.ts` file. This file will handle all requests sent to `/api/studio` and act as the bridge between the Studio component in your frontend and the database in your backend:
PostgreSQL
SQLite
MySQL
```typescript title="app/api/studio/route.ts"
import "dotenv/config";
import { createPrismaPostgresHttpClient } from "@prisma/studio-core/data/ppg";
import { serializeError } from "@prisma/studio-core/data/bff";
const CORS_HEADERS = {
"Access-Control-Allow-Origin": "*", // Change to your domain in production
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
};
// Use dynamic rendering for database operations
export const dynamic = "force-dynamic";
export async function GET() {
return Response.json({ message: "Studio API endpoint is running" }, { headers: CORS_HEADERS });
}
export async function POST(request: Request) {
try {
const body = await request.json();
const query = body.query;
if (!query) {
return Response.json([serializeError(new Error("Query is required"))], {
status: 400,
headers: CORS_HEADERS,
});
}
const url = process.env.DATABASE_URL;
if (!url) {
const message = "❌ Environment variable DATABASE_URL is missing.";
return Response.json([serializeError(new Error(message))], {
status: 500,
headers: CORS_HEADERS,
});
}
const [error, results] = await createPrismaPostgresHttpClient({
url,
}).execute(query);
if (error) {
return Response.json([serializeError(error)], {
headers: CORS_HEADERS,
});
}
return Response.json([null, results], { headers: CORS_HEADERS });
} catch (err) {
return Response.json([serializeError(err)], {
status: 400,
headers: CORS_HEADERS,
});
}
}
// Handle preflight requests for CORS
export async function OPTIONS() {
return new Response(null, { status: 204, headers: CORS_HEADERS });
}
```
```typescript title="app/api/studio/route.ts"
import "dotenv/config";
import { createNodeSQLiteExecutor } from "@prisma/studio-core/data/node-sqlite";
import { serializeError } from "@prisma/studio-core/data/bff";
import DatabaseSync from "better-sqlite3";
const CORS_HEADERS = {
"Access-Control-Allow-Origin": "*", // Change to your domain in production
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
};
// Use dynamic rendering for database operations
export const dynamic = "force-dynamic";
export async function GET() {
return Response.json({ message: "Studio API endpoint is running" }, { headers: CORS_HEADERS });
}
export async function POST(request: Request) {
try {
const body = await request.json();
const query = body.query;
if (!query) {
return Response.json([serializeError(new Error("Query is required"))], {
status: 400,
headers: CORS_HEADERS,
});
}
const url = process.env.DATABASE_URL;
if (!url) {
const message = "❌ Environment variable DATABASE_URL is missing.";
return Response.json([serializeError(new Error(message))], {
status: 500,
headers: CORS_HEADERS,
});
}
const dbPath = url.replace("file:", "");
const database = new DatabaseSync(dbPath);
const [error, results] = await createNodeSQLiteExecutor(database).execute(query);
if (error) {
return Response.json([serializeError(error)], {
headers: CORS_HEADERS,
});
}
return Response.json([null, results], { headers: CORS_HEADERS });
} catch (err) {
return Response.json([serializeError(err)], {
status: 400,
headers: CORS_HEADERS,
});
}
}
// Handle preflight requests for CORS
export async function OPTIONS() {
return new Response(null, { status: 204, headers: CORS_HEADERS });
}
```
```typescript title="app/api/studio/route.ts"
import "dotenv/config";
import { createMySQL2Executor } from "@prisma/studio-core/data/mysql2";
import { serializeError } from "@prisma/studio-core/data/bff";
import mysql from "mysql2/promise";
const CORS_HEADERS = {
"Access-Control-Allow-Origin": "*", // Change to your domain in production
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
};
// Use dynamic rendering for database operations
export const dynamic = "force-dynamic";
export async function GET() {
return Response.json({ message: "Studio API endpoint is running" }, { headers: CORS_HEADERS });
}
export async function POST(request: Request) {
try {
const body = await request.json();
const query = body.query;
if (!query) {
return Response.json([serializeError(new Error("Query is required"))], {
status: 400,
headers: CORS_HEADERS,
});
}
const url = process.env.DATABASE_URL;
if (!url) {
const message = "❌ Environment variable DATABASE_URL is missing.";
return Response.json([serializeError(new Error(message))], {
status: 500,
headers: CORS_HEADERS,
});
}
const pool = mysql.createPool(url);
const [error, results] = await createMySQL2Executor(pool).execute(query);
if (error) {
return Response.json([serializeError(error)], {
headers: CORS_HEADERS,
});
}
return Response.json([null, results], { headers: CORS_HEADERS });
} catch (err) {
return Response.json([serializeError(err)], {
status: 400,
headers: CORS_HEADERS,
});
}
}
// Handle preflight requests for CORS
export async function OPTIONS() {
return new Response(null, { status: 204, headers: CORS_HEADERS });
}
```
3.4. Create the main Studio page [#34-create-the-main-studio-page]
Open the `app/page.tsx` file and replace the existing code to render the embedded Studio with the following:
PostgreSQL
SQLite
MySQL
```tsx title="app/page.tsx"
"use client";
import dynamic from "next/dynamic";
import { createPostgresAdapter } from "@prisma/studio-core/data/postgres-core";
import { createStudioBFFClient } from "@prisma/studio-core/data/bff";
import { useMemo, Suspense } from "react";
import StudioWrapper from "@/components/StudioWrapper";
// Dynamically import Studio with no SSR to avoid hydration issues
const Studio = dynamic(() => import("@prisma/studio-core/ui").then((mod) => mod.Studio), {
ssr: false,
});
// Loading component
const StudioLoading = () => (
Loading Studio...
);
// Client-only Studio component
const ClientOnlyStudio = () => {
const adapter = useMemo(() => {
// Create the HTTP client that communicates with our API endpoint
const executor = createStudioBFFClient({
url: "/api/studio",
});
// Create the Postgres adapter using the executor
return createPostgresAdapter({ executor });
}, []);
return ;
};
export default function App() {
return (
}>
);
}
```
```tsx title="app/page.tsx"
"use client";
import dynamic from "next/dynamic";
import { createSQLiteAdapter } from "@prisma/studio-core/data/sqlite-core";
import { createStudioBFFClient } from "@prisma/studio-core/data/bff";
import { useMemo, Suspense } from "react";
import StudioWrapper from "@/components/StudioWrapper";
// Dynamically import Studio with no SSR to avoid hydration issues
const Studio = dynamic(() => import("@prisma/studio-core/ui").then((mod) => mod.Studio), {
ssr: false,
});
// Loading component
const StudioLoading = () => (
Loading Studio...
);
// Client-only Studio component
const ClientOnlyStudio = () => {
const adapter = useMemo(() => {
// Create the HTTP client that communicates with our API endpoint
const executor = createStudioBFFClient({
url: "/api/studio",
});
// Create the SQLite adapter using the executor
return createSQLiteAdapter({ executor });
}, []);
return ;
};
export default function App() {
return (
}>
);
}
```
```tsx title="app/page.tsx"
"use client";
import dynamic from "next/dynamic";
import { createMySQLAdapter } from "@prisma/studio-core/data/mysql-core";
import { createStudioBFFClient } from "@prisma/studio-core/data/bff";
import { useMemo, Suspense } from "react";
import StudioWrapper from "@/components/StudioWrapper";
// Dynamically import Studio with no SSR to avoid hydration issues
const Studio = dynamic(() => import("@prisma/studio-core/ui").then((mod) => mod.Studio), {
ssr: false,
});
// Loading component
const StudioLoading = () => (
Loading Studio...
);
// Client-only Studio component
const ClientOnlyStudio = () => {
const adapter = useMemo(() => {
// Create the HTTP client that communicates with our API endpoint
const executor = createStudioBFFClient({
url: "/api/studio",
});
// Create the MySQL adapter using the executor
return createMySQLAdapter({ executor });
}, []);
return ;
};
export default function App() {
return (
}>
);
}
```
3.5. Start your development server and test the embedded Studio [#35-start-your-development-server-and-test-the-embedded-studio]
Start your Next.js development server:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
Open your browser and go to `http://localhost:3000`. You should now see Prisma Studio running inside your application:
Here's what to look for:
1. **Prisma Studio interface**: The full Prisma Studio UI should render within your app layout.
2. **Your data**: The `User` and `Post` tables you defined (plus any seeded data) should appear.
3. **Interactive features**:
* Browse and filter records in your tables
* Edit values inline by double-clicking cells
* Add new records using the "Add record" button
* Delete records you no longer need
* Explore relationships by navigating between related tables
Verify whether everything works by testing the basics:
* Click on different tables to confirm your data loads.
* Update a record to check that changes are saved.
* Add a new record and confirm it appears instantly.
* Try filtering data to make sure queries run correctly.
* Navigate through relationships (for example, view a user's posts) to confirm associations work.
Once these actions work as expected, your embedded Prisma Studio is set up and connected to your database.
Next steps [#next-steps]
At this point you have Prisma Studio running inside your Next.js application and connected to your database. You can browse, edit, and manage your data without leaving your app. To make this setup production-ready, consider these improvements:
1. **Add authentication**: Currently, anyone who can open your app has access to Prisma Studio. [Add user authentication](/studio/integrations/embedding#adding-user-authentication) and only allow specific roles (for example, admins) to use the embedded Studio. You can do this by checking authentication tokens in your `/api/studio` endpoint before running queries.
2. **Use environment-specific configuration**: In development you may want a test database, while in production you'll need a separate live database. Update your `.env` file to use different `DATABASE_URL` values for each environment, and confirm that your `/api/studio` endpoint is reading the correct one.
3. **Apply custom styling**: The Studio component ships with a default look. Pass in [your own theme](/studio/integrations/embedding#custom-styling) and adjust colors, typography, or branding to match the rest of your application. This helps Studio feel like a native part of your app rather than a standalone tool.
By adding authentication, environment-specific settings, and styling, you move from a working demo to a secure and polished production setup.
For more patterns and examples, see the [Prisma Studio Core demo repository](https://github.com/prisma/studio-core-demo), which includes an alternative implementation using Hono.js and React. If you prefer a guided walkthrough, watch the YouTube video: [\*\*Use Prisma Studio in Your Own Applications
\*\*](https://www.youtube.com/watch?v=Up5vG2YHPvc).
# GitHub Actions (/docs/guides/integrations/github-actions)
Overview [#overview]
This guide shows you how to automatically create and delete [Prisma Postgres](https://www.prisma.io/postgres) databases using GitHub Actions and [the Prisma Postgres management API](https://api.prisma.io/v1/swagger-editor). The setup provisions a new database for every pull request, seeds it with sample data, and the `github-actions` bot leaves a comment with the database name and the status.
After the PR is closed, the database is automatically deleted. This allows you to test changes in isolation without affecting the main development database.
Prerequisites [#prerequisites]
Make sure you have the following:
* Node.js 20 or later
* A [Prisma Data Platform](https://console.prisma.io?utm_source=actions_guide\&utm_medium=docs) account
* GitHub repository
1. Set up your project [#1-set-up-your-project]
Initialize your project:
npm
pnpm
yarn
bun
```bash
mkdir prisma-gha-demo && cd prisma-gha-demo
npm init -y
```
```bash
mkdir prisma-gha-demo && cd prisma-gha-demo
pnpm init -y
```
```bash
mkdir prisma-gha-demo && cd prisma-gha-demo
yarn init -y
```
```bash
mkdir prisma-gha-demo && cd prisma-gha-demo
bun init -y
```
2. Install and configure Prisma [#2-install-and-configure-prisma]
In this section, you'll set up Prisma in your project and verify that it works locally before integrating it into GitHub Actions. This involves installing Prisma's dependencies, connecting to a Prisma Postgres database, defining your data models, applying your schema, and seeding the database with sample data.
By the end of this section, your project will be fully prepared to use Prisma both locally and in a CI workflow.
2.1. Install dependencies [#21-install-dependencies]
To get started with Prisma, install the required dependencies:
npm
pnpm
yarn
bun
```bash
npm install prisma tsx @types/pg dotenv --save-dev
```
```bash
pnpm add prisma tsx @types/pg dotenv --save-dev
```
```bash
yarn add prisma tsx @types/pg dotenv --dev
```
```bash
bun add prisma tsx @types/pg dotenv --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg pg
```
```bash
bun add @prisma/client @prisma/adapter-pg pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Once installed, initialize Prisma:
npm
pnpm
yarn
bun
```bash
npx prisma init --db --output ../src/generated/prisma
```
```bash
pnpm dlx prisma init --db --output ../src/generated/prisma
```
```bash
yarn dlx prisma init --db --output ../src/generated/prisma
```
```bash
bunx --bun prisma init --db --output ../src/generated/prisma
```
This creates:
* A `prisma/` directory with `schema.prisma`
* A `.env` file with `DATABASE_URL`
* A generated client in `src/generated/prisma`
2.2. Define your Prisma schema [#22-define-your-prisma-schema]
Edit `prisma/schema.prisma` to:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
}
```
Create a `prisma.config.ts` file to configure Prisma with seeding:
```typescript title="prisma.config.ts"
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config"; // [!code ++]
// [!code ++]
export default defineConfig({
// [!code ++]
schema: "prisma/schema.prisma", // [!code ++]
migrations: {
// [!code ++]
path: "prisma/migrations", // [!code ++]
seed: `tsx src/seed.ts`, // [!code ++]
}, // [!code ++]
datasource: {
// [!code ++]
url: env("DATABASE_URL"), // [!code ++]
}, // [!code ++]
}); // [!code ++]
```
You'll need to install the `dotenv` package:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
2.3. Run initial migration and generate client [#23-run-initial-migration-and-generate-client]
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
Then generate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
This pushes your schema and prepares the client.
2.4. Seed the database [#24-seed-the-database]
Create a file at `src/seed.ts`:
```tsx title="src/seed.ts"
import { PrismaClient } from "../src/generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
import "dotenv/config";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
const userData = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://twitter.com/prisma",
published: true,
},
],
},
},
];
export async function main() {
for (const u of userData) {
await prisma.user.create({ data: u });
}
}
main()
.catch(console.error)
.finally(() => prisma.$disconnect());
```
Update your `package.json`:
```json title="package.json"
{
{
"name": "prisma-gha-demo",
"version": "1.0.0",
"description": "",
"scripts": {
"seed": "tsx src/seed.ts" // [!code ++]
},
// other configurations...
}
```
Then run:
npm
pnpm
yarn
bun
```bash
npm run seed
npx prisma studio
```
```bash
pnpm run seed
pnpm dlx prisma studio
```
```bash
yarn seed
yarn dlx prisma studio
```
```bash
bun run seed
bun x prisma studio
```
Navigate to `http://localhost:5555` and verify that the database has been seeded with sample data. Now you're ready to automate this process with GitHub Actions.
3. Add the GitHub Actions workflow [#3-add-the-github-actions-workflow]
In this step, you will set up a GitHub Actions workflow that automatically provisions a Prisma Postgres database when a new pull request (PR) is opened. Once the PR is closed, the workflow will clean up the database.
3.1 Create the workflow file [#31-create-the-workflow-file]
Start by creating the required directory and file:
```bash
mkdir -p .github/workflows
touch .github/workflows/prisma-postgres-management.yml
```
This file will contain the logic to manage databases on a per-PR basis. This GitHub Actions workflow:
* Provisions a temporary Prisma Postgres database when a PR is opened
* Seeds the database with test data
* Cleans up the database when the PR is closed
* Supports manual execution for both provisioning and cleanup
This workflow uses `us-east-1` as the default region for Prisma Postgres. You can change this to your preferred region by modifying the `region` parameter in the API calls, or even by adding a `region` input to the workflow.
3.2. Add the base configuration [#32-add-the-base-configuration]
Paste the following into `.github/workflows/prisma-postgres-management.yml`. This sets up when the workflow runs and provides required environment variables.
```yaml title=".github/workflows/prisma-postgres-management.yml"
name: Prisma Postgres Management API Workflow
on:
pull_request:
types: [opened, reopened, closed]
workflow_dispatch:
inputs:
action:
description: "Action to perform"
required: true
default: "provision"
type: choice
options:
- provision
- cleanup
database_name:
description: "Database name (for testing, will be sanitized)"
required: false
type: string
env:
PRISMA_POSTGRES_SERVICE_TOKEN: ${{ secrets.PRISMA_POSTGRES_SERVICE_TOKEN }}
PRISMA_PROJECT_ID: ${{ secrets.PRISMA_PROJECT_ID }}
# Sanitize database name once at workflow level
DB_NAME: ${{ github.event.pull_request.number != null && format('pr-{0}-{1}', github.event.pull_request.number, github.event.pull_request.head.ref) || (inputs.database_name != '' && inputs.database_name || format('test-{0}', github.run_number)) }}
# Prevent concurrent runs of the same PR
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
```
Now you will be adding the provision and cleanup jobs to this workflow. These jobs will handle the creation and deletion of Prisma Postgres databases based on the pull request events.
3.3. Add a provision job to the workflow [#33-add-a-provision-job-to-the-workflow]
Now add a job to provision the database when the PR is opened or when triggered manually. The provision job:
* Installs dependencies
* Checks for existing databases
* Creates a new one if needed
* Seeds the database
* Comments on the PR with status
Append the following under the `jobs:` key in your workflow file:
```yaml title=".github/workflows/prisma-postgres-management.yml"
jobs:
provision-database:
if: (github.event_name == 'pull_request' && github.event.action != 'closed') || (github.event_name == 'workflow_dispatch' && inputs.action == 'provision')
runs-on: ubuntu-latest
permissions: write-all
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "npm"
- name: Install Dependencies
run: npm install
- name: Validate Environment Variables
run: |
if [ -z "${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" ]; then
echo "Error: PRISMA_POSTGRES_SERVICE_TOKEN secret is not set"
exit 1
fi
if [ -z "${{ env.PRISMA_PROJECT_ID }}" ]; then
echo "Error: PRISMA_PROJECT_ID secret is not set"
exit 1
fi
- name: Sanitize Database Name
run: |
# Sanitize the database name to match Prisma's requirements
DB_NAME="$(echo "${{ env.DB_NAME }}" | tr '/' '_' | tr '-' '_' | tr '[:upper:]' '[:lower:]')"
echo "DB_NAME=$DB_NAME" >> $GITHUB_ENV
- name: Check If Database Exists
id: check-db
run: |
echo "Fetching all databases..."
RESPONSE=$(curl -s -X GET \
-H "Authorization: Bearer ${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" \
-H "Content-Type: application/json" \
"https://api.prisma.io/v1/projects/${{ env.PRISMA_PROJECT_ID }}/databases")
echo "Looking for database with name: ${{ env.DB_NAME }}"
# Extract database ID using jq to properly parse JSON
DB_EXISTS=$(echo "$RESPONSE" | jq -r ".data[]? | select(.name == \"${{ env.DB_NAME }}\") | .id")
if [ ! -z "$DB_EXISTS" ] && [ "$DB_EXISTS" != "null" ]; then
echo "Database ${{ env.DB_NAME }} exists with ID: $DB_EXISTS."
echo "exists=true" >> $GITHUB_OUTPUT
echo "db-id=$DB_EXISTS" >> $GITHUB_OUTPUT
else
echo "No existing database found with name ${{ env.DB_NAME }}"
echo "exists=false" >> $GITHUB_OUTPUT
fi
- name: Create Database
id: create-db
if: steps.check-db.outputs.exists != 'true'
run: |
echo "Creating database ${{ env.DB_NAME }}..."
RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer ${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" \
-H "Content-Type: application/json" \
-d "{\"name\": \"${{ env.DB_NAME }}\", \"region\": \"us-east-1\"}" \
"https://api.prisma.io/v1/projects/${{ env.PRISMA_PROJECT_ID }}/databases")
# Check if response contains an id (success case)
if echo "$RESPONSE" | grep -q '"id":'; then
echo "Database created successfully"
CONNECTION_STRING=$(echo "$RESPONSE" | jq -r '.data.connectionString')
echo "connection-string=$CONNECTION_STRING" >> $GITHUB_OUTPUT
else
echo "Failed to create database"
echo "$RESPONSE"
exit 1
fi
- name: Get Connection String for Existing Database
id: get-connection
if: steps.check-db.outputs.exists == 'true'
run: |
echo "Creating new connection string for existing database..."
CONNECTION_RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer ${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{"name":"read_write_key"}' \
"https://api.prisma.io/v1/databases/${{ steps.check-db.outputs.db-id }}/connections")
CONNECTION_STRING=$(echo "$CONNECTION_RESPONSE" | jq -r '.data.connectionString')
echo "connection-string=$CONNECTION_STRING" >> $GITHUB_OUTPUT
- name: Setup Database Schema
run: |
# Get connection string from appropriate step
if [ "${{ steps.check-db.outputs.exists }}" = "true" ]; then
CONNECTION_STRING="${{ steps.get-connection.outputs.connection-string }}"
else
CONNECTION_STRING="${{ steps.create-db.outputs.connection-string }}"
fi
# Set the DATABASE_URL
export DATABASE_URL="$CONNECTION_STRING"
# Generate Prisma Client
npx prisma generate
# Push schema to database
npx prisma db push
- name: Seed Database
run: |
# Get connection string from appropriate step
if [ "${{ steps.check-db.outputs.exists }}" = "true" ]; then
CONNECTION_STRING="${{ steps.get-connection.outputs.connection-string }}"
else
CONNECTION_STRING="${{ steps.create-db.outputs.connection-string }}"
fi
# Set the DATABASE_URL environment variable for the seed script
export DATABASE_URL="$CONNECTION_STRING"
# Generate Prisma Client
npx prisma generate
# Run the seed script
npm run seed
- name: Comment PR
if: success() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `🗄️ Database provisioned successfully!\n\nDatabase name: ${{ env.DB_NAME }}\nStatus: Ready and seeded with sample data`
})
- name: Output Database Info
if: success() && github.event_name == 'workflow_dispatch'
run: |
echo "🗄️ Database provisioned successfully!"
echo "Database name: ${{ env.DB_NAME }}"
echo "Status: Ready and seeded with sample data"
```
3.4. Add a cleanup job to the workflow [#34-add-a-cleanup-job-to-the-workflow]
When a pull request is closed, you can automatically remove the associated database by adding a cleanup job. The cleanup job:
* Finds the database by name
* Deletes it from the Prisma Postgres project
* Can also be triggered manually with `action: cleanup`
Append the following to your `jobs:` section, after the `provision-database` job:
```yaml title=".github/workflows/prisma-postgres-management.yml"
cleanup-database:
if: (github.event_name == 'pull_request' && github.event.action == 'closed') || (github.event_name == 'workflow_dispatch' && inputs.action == 'cleanup')
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Validate Environment Variables
run: |
if [ -z "${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" ]; then
echo "Error: PRISMA_POSTGRES_SERVICE_TOKEN secret is not set"
exit 1
fi
if [ -z "${{ env.PRISMA_PROJECT_ID }}" ]; then
echo "Error: PRISMA_PROJECT_ID secret is not set"
exit 1
fi
- name: Sanitize Database Name
run: |
# Sanitize the database name
DB_NAME="$(echo "${{ env.DB_NAME }}" | tr '/' '_' | tr '-' '_' | tr '[:upper:]' '[:lower:]')"
echo "DB_NAME=$DB_NAME" >> $GITHUB_ENV
- name: Delete Database
run: |
echo "Fetching all databases..."
RESPONSE=$(curl -s -X GET \
-H "Authorization: Bearer ${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" \
-H "Content-Type: application/json" \
"https://api.prisma.io/v1/projects/${{ env.PRISMA_PROJECT_ID }}/databases")
echo "Looking for database with name: ${{ env.DB_NAME }}"
# Extract database ID using jq to properly parse JSON
DB_EXISTS=$(echo "$RESPONSE" | jq -r ".data[]? | select(.name == \"${{ env.DB_NAME }}\") | .id")
if [ ! -z "$DB_EXISTS" ] && [ "$DB_EXISTS" != "null" ]; then
echo "Database ${{ env.DB_NAME }} exists with ID: $DB_EXISTS. Deleting..."
DELETE_RESPONSE=$(curl -s -X DELETE \
-H "Authorization: Bearer ${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" \
-H "Content-Type: application/json" \
"https://api.prisma.io/v1/databases/$DB_EXISTS")
echo "Delete API Response: $DELETE_RESPONSE"
if echo "$DELETE_RESPONSE" | grep -q '"error":'; then
ERROR_MSG=$(echo "$DELETE_RESPONSE" | jq -r '.message // "Unknown error"')
echo "Failed to delete database: $ERROR_MSG"
exit 1
else
echo "Database deletion initiated successfully"
fi
else
echo "No existing database found with name ${{ env.DB_NAME }}"
fi
```
This completes your Prisma Postgres management workflow setup. In the next step, you'll configure the required GitHub secrets to authenticate with the Prisma API.
4. Store the code in GitHub [#4-store-the-code-in-github]
Initialize a git repository and push to [GitHub](https://github.com/):
If you don't have a repository in GitHub yet, [create one on GitHub](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-new-repository). Once the repository is ready, run the following commands:
```bash
git add .
git commit -m "Initial commit with Prisma Postgres integration"
git branch -M main
git remote add origin https://github.com//.git
git push -u origin main
```
Replace `` and `` with your GitHub username and the name of your repository.
5. Retrieve the secrets for the workflow [#5-retrieve-the-secrets-for-the-workflow]
5.1. Retrieve your Prisma Postgres service token [#51-retrieve-your-prisma-postgres-service-token]
To manage Prisma Postgres databases, you also need a service token. Follow these steps to retrieve it:
1. Make sure you are in the same workspace where you created your project in the last step.
2. Navigate to the **Settings** page of your workspace and select **Service Tokens**.
3. Click **New Service Token**.
4. Copy the generated token and save it in your `.env` file as `PRISMA_POSTGRES_SERVICE_TOKEN`. This token is required for the next step's script and must also be added to your GitHub Actions secrets.
5.2 Retrieve the project ID where you want to provision Prisma Postgres databases [#52-retrieve-the-project-id-where-you-want-to-provision-prisma-postgres-databases]
To avoid conflicts with your development databases, you'll now create a dedicated project specifically for CI workflows. Use the following curl command to create a new Prisma Postgres project using the Prisma Postgres Management API:
```bash
curl -X POST https://api.prisma.io/v1/projects \
-H "Authorization: Bearer $PRISMA_POSTGRES_SERVICE_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"region\": \"us-east-1\", \"name\": \"$PROJECT_NAME\"}"
```
Make sure to replace the `$PRISMA_POSTGRES_SERVICE_TOKEN` variable with the service token you stored earlier.
Replace the $PRISMA\_POSTGRES\_SERVICE\_TOKEN with the service token and the `$PROJECT_NAME`with a name for your project (e.g.,`my-gha-preview`). The script will create a new Prisma Postgres project in the `us-east-1` region.
The CLI output will then look like this:
```json
{
"data": {
"id": "$PRISMA_PROJECT_ID",
"type": "project",
"name": "$PROJECT_NAME",
"createdAt": "2025-07-15T08:35:10.546Z",
"workspace": {
"id": "$PRISMA_WORKSPACE_ID",
"name": "$PRISMA_WORKSPACE_NAME"
}
}
}
```
Copy and store the `$PRISMA_PROJECT_ID` from the output. This is your Prisma project ID, which you will use in the next step.
6. Add secrets in GitHub [#6-add-secrets-in-github]
To add secrets:
1. Go to your GitHub repository.
2. Navigate to **Settings**.
3. Click and expand the **Secrets and variables** section.
4. Click **Actions**.
5. Click **New repository secret**.
6. Add the following:
* `PRISMA_PROJECT_ID` - Your Prisma project ID from the Prisma Console.
* `PRISMA_POSTGRES_SERVICE_TOKEN` - Your service token.
These secrets will be accessed in the workflow file via `env`.
7. Try the workflow [#7-try-the-workflow]
You can test the setup in two ways:
**Option 1: Automatic trigger via PR**
1. Open a pull request on the repository.
2. GitHub Actions will provision a new Prisma Postgres database.
3. It will push your schema and seed the database.
4. A comment will be added to the PR confirming database creation.
5. When the PR is closed, the database will be deleted automatically.
**Option 2: Manual trigger**
1. Go to the **Actions** tab in your repository.
2. Select the **Prisma Postgres Management API Workflow** on the left sidebar.
3. Click the **Run workflow** dropdown
4. Choose `provision` as the action and optionally provide a custom database name. You can also choose `cleanup` to delete an *existing* database.
5. Click **Run workflow**.
Next steps [#next-steps]
You now have a fully automated GitHub Actions setup for managing ephemeral Prisma Postgres databases.
This gives you:
* Isolated databases for every pull request.
* Automatic schema sync and seed.
* Cleanup of unused databases after merges.
This setup improves confidence in changes and reduces the risk of shared database conflicts. You can extend this by integrating test suites, or integrating it in your workflow.
# Neon with Accelerate (/docs/guides/integrations/neon-accelerate)
Introduction [#introduction]
This guides teaches you how to add connection pooling to a PostgreSQL database hosted on [Neon](https://neon.tech/) using [Prisma Accelerate](/accelerate).
Prisma Accelerate is a robust and mature connection pooler enabling your database to function properly during traffic spikes and high load scenarios. Check out this [video](https://www.youtube.com/watch?v=cnL75if6Aq0) demonstrating how it performs in a load test or [learn why connection pooling is important](https://www.prisma.io/blog/saving-black-friday-with-connection-pooling).
Prerequisites [#prerequisites]
To successfully complete this guide, you need **a connection string for a PostgreSQL instance hosted on Neon**. It typically looks similar to this:
```bash no-copy
postgresql://neondb_owner:[YOUR-PASSWORD]@ep-lingering-hat-a2e7tkt3.eu-central-1.aws.neon.tech/neondb?sslmode=require
```
If you already have a project using Prisma ORM, you can skip the first two steps and jump ahead to [Step 3. Install the Accelerate extension](#3-install-the-accelerate-extension).
1. Set up Prisma ORM [#1-set-up-prisma-orm]
Start by installing the Prisma CLI in your project:
npm
pnpm
yarn
bun
```bash
npm install prisma --save-dev
```
```bash
pnpm add prisma --save-dev
```
```bash
yarn add prisma --dev
```
```bash
bun add prisma --dev
```
Then, run the following command to initialize a new project:
npm
pnpm
yarn
bun
```bash
npx prisma init
```
```bash
pnpm dlx prisma init
```
```bash
yarn dlx prisma init
```
```bash
bunx --bun prisma init
```
This will create a new `prisma` directory with a `schema.prisma` file and add a `.env` file with the `DATABASE_URL` environment variable.
Update the file and set the `DATABASE_URL` to your Neon connection string:
```text title=".env"
DATABASE_URL="postgresql://neondb_owner:[YOUR-PASSWORD]@ep-lingering-hat-a2e7tkt3.eu-central-1.aws.neon.tech/neondb?sslmode=require"
```
Create a `prisma.config.ts` file to configure Prisma:
```typescript title="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"),
},
});
```
You'll need to install the `dotenv` package to load environment variables:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
2. Introspect your database [#2-introspect-your-database]
Next, run the following command to introspect your database and create your data model:
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
This command reads your database schema and creates new models in your `schema.prisma` file that match the tables in your database.
If you want to use Prisma Migrate in the future, you also need to [baseline your database](/orm/prisma-migrate/workflows/baselining).
3. Install the Accelerate extension [#3-install-the-accelerate-extension]
Install the Prisma Client extension for Accelerate:
npm
pnpm
yarn
bun
```bash
npm install @prisma/extension-accelerate
```
```bash
pnpm add @prisma/extension-accelerate
```
```bash
yarn add @prisma/extension-accelerate
```
```bash
bun add @prisma/extension-accelerate
```
This is needed to access Prisma Accelerate's connection pool.
4. Set up Accelerate in the Prisma Console [#4-set-up-accelerate-in-the-prisma-console]
To set up Accelerate in the Prisma Console, follow these steps:
1. Log into the [Prisma Console](https://console.prisma.io).
2. Select **New project**
3. Choose a **Name** for your project
4. In the **Choose your starting product** section, find the **Accelerate** card and click **Get started**
5. In the field for your **Database connection string**, paste your Neon connection string
6. Select the **Region** that's closest to your database
7. Click **Create project**
8. On the next screen, click **Enable Accelerate**
Once you went through these steps, you'll be redirected to another page where you need to the click the **Generate API key** button.
You'll then be shown a new connection URL which enables you to connect to Prisma Accelerate's connection pool. This needs to be set as the new `DATABASE_URL` in your `.env` file:
```text title=".env"
DATABASE_URL="prisma://accelerate.prisma-data.net/?api_key=ey..."
```
If you want to use Prisma Migrate with Prisma Accelerate, you need to provide a direct database URL in your `prisma.config.ts` file. The Accelerate URL (starting with `prisma://`) is used for queries via PrismaClient, while the direct database URL is used for migrations.
Update your `prisma.config.ts`:
```typescript title="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("DIRECT_URL"), // Direct database URL for migrations
},
});
```
And add the `DIRECT_URL` to your `.env` file:
```text title=".env"
DATABASE_URL="prisma://accelerate.prisma-data.net/?api_key=ey..."
DIRECT_URL="postgresql://neondb_owner:[YOUR-PASSWORD]@ep-lingering-hat-a2e7tkt3.eu-central-1.aws.neon.tech/neondb?sslmode=require"
```
5. Generate Prisma Client [#5-generate-prisma-client]
With your Prisma schema in place, you can go ahead and generate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
In Prisma v7, the `--no-engine` flag is no longer required when using Prisma Accelerate. Previously, you would run `prisma generate --no-engine`, but now the standard `prisma generate` command works for all use cases.
6. Send queries through the connection pool [#6-send-queries-through-the-connection-pool]
In your application code, you now need to apply the Accelerate extension to your Prisma Client instance:
```ts
import { PrismaClient } from "./generated/prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient({
accelerateUrl: process.env.DATABASE_URL,
}).$extends(withAccelerate());
```
At this point, you can now start sending queries which will be routed through the connection pool to your database.
# Permit.io (/docs/guides/integrations/permit-io)
Introduction [#introduction]
[Permit.io](https://www.permit.io/) is an authorization-as-a-service platform that lets you implement fine-grained access control
rules based on real-world relationships.
This guide explains how to connect Permit.io to a new Express + Prisma app, define a
[Relationship-Based Access Control (ReBAC)](https://www.permit.io/blog/what-is-rebac) policy,
and automatically filter Prisma queries so users only see the data they're allowed to access.
You'll build a small project-task API to demonstrate access inheritance in action - no manual `WHERE` clauses required.
You can find a complete example of this guide [here](https://www.permit.io/blog/prisma-orm-data-filtering-with-rebac).
Prerequisites [#prerequisites]
* [Node.js v20+](https://nodejs.org/)
* [PostgreSQL](https://www.postgresql.org/) (local or hosted)
* [Prisma CLI](/orm/reference/prisma-cli-reference) (`npx prisma`)
* [TypeScript](https://www.typescriptlang.org/)
* [Permit CLI](https://github.com/permitio/permit-cli) (`npm install -g @permitio/cli`)
1. Set up your project [#1-set-up-your-project]
First of all, you'll create a new Express + Prisma project from scratch using TypeScript.
You'll also install the tools needed to support ReBAC filtering with Permit.io.
1.1 Create the project folder [#11-create-the-project-folder]
npm
pnpm
yarn
bun
```bash
mkdir prisma-rebac-filtering
cd prisma-rebac-filtering
npm init -y
```
```bash
mkdir prisma-rebac-filtering
cd prisma-rebac-filtering
pnpm init -y
```
```bash
mkdir prisma-rebac-filtering
cd prisma-rebac-filtering
yarn init -y
```
```bash
mkdir prisma-rebac-filtering
cd prisma-rebac-filtering
bun init -y
```
1.2 Install the required dependencies [#12-install-the-required-dependencies]
Install application and development dependencies:
npm
pnpm
yarn
bun
```bash
npm install express cors dotenv @prisma/client @prisma/adapter-pg pg
```
```bash
pnpm add express cors dotenv @prisma/client @prisma/adapter-pg pg
```
```bash
yarn add express cors dotenv @prisma/client @prisma/adapter-pg pg
```
```bash
bun add express cors dotenv @prisma/client @prisma/adapter-pg pg
```
npm
pnpm
yarn
bun
```bash
npm install -D prisma typescript tsx @types/pg
```
```bash
pnpm add -D prisma typescript tsx @types/pg
```
```bash
yarn add --dev prisma typescript tsx @types/pg
```
```bash
bun add --dev prisma typescript tsx @types/pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Then, initialize your Prisma setup:
npm
pnpm
yarn
bun
```bash
npx prisma init
```
```bash
pnpm dlx prisma init
```
```bash
yarn dlx prisma init
```
```bash
bunx --bun prisma init
```
This creates:
* A `prisma/` directory with a default `schema.prisma` file
* A `prisma.config.ts` file for configuring Prisma
* A `.env` file at the root.
1.3 Set up your TypeScript config [#13-set-up-your-typescript-config]
Create a `tsconfig.json` file:
```json
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"moduleResolution": "bundler",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"outDir": "dist"
},
"include": ["src", "scripts"]
}
```
1.4 Create your folder structure [#14-create-your-folder-structure]
Set up your project folders:
```bash
mkdir -p src/controllers src/middleware src/config scripts
```
You're now ready to define your Prisma data model.
2. The authorization model [#2-the-authorization-model]
Before we continue with the setup, it's important to define how access control will work in your application.
This guide uses **Relationship-Based Access Control (ReBAC)** to automatically restrict database queries based on a user's relationship to the data.
Let's see what this looks like:
Scenario overview [#scenario-overview]
You're building a **project management API** that supports team-level access controls. Each project belongs to a team (like Marketing or Engineering), and users should only be able to access the projects—and their associated tasks—that they're assigned to.
This is a perfect use case for ReBAC, because:
* Access depends on relationships between users and data (e.g., team membership)
* You want task access to inherit from project access
* You want to avoid manually checking permissions in every controller
Resources [#resources]
These are the main data entities you'll protect:
* `Project`: Represents a team-specific workspace that may contain business-critical data (timelines, budgets, client deliverables).
* `Task`: Represents an item of work that belongs to a project
Relationships [#relationships]
* Projects contain tasks (`Project → Task`)
* Users are members of projects (`User → Project`)
Instance-level roles [#instance-level-roles]
Instance-level roles describe what users can do with specific resources:
| Role | Description |
| ---------------- | ------------------------------------- |
| `project#Member` | User can access a specific project |
| `task#Member` | User can access tasks in that project |
Role derivation [#role-derivation]
ReBAC lets you **automatically derive roles** based on relationships. In this case:
* If a user is a `project#Member`, they automatically become a `task#Member` for all tasks within that project.
* New tasks inherit project access—no need to update permissions manually.
Access policies [#access-policies]
Once relationships and roles are defined, access policies determine what users can do:
| Role | Action | Resource |
| ---------------- | ------ | -------- |
| `project#Member` | `read` | Project |
| `task#Member` | `read` | Task |
This model ensures that:
* Users can only access the projects and tasks they're assigned to
* No cross-team visibility
* Access automatically stays in sync with the business structure
3. Define your data model [#3-define-your-data-model]
To support permission-aware data filtering, you need to structure your database so that relationships are clearly defined. In this case, every `Task` belongs to a `Project`, and users gain access to tasks by being members of the parent project.
3.1 Update your Prisma schema [#31-update-your-prisma-schema]
Open `prisma/schema.prisma` and replace the contents with the following:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
}
datasource db {
provider = "postgresql"
}
model Project {
id String @id @default(uuid())
name String
tasks Task[] // One-to-many relationship for permission inheritance
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Task {
id String @id @default(uuid())
name String
description String?
projectId String
project Project @relation(fields: [projectId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
3.2 Add dotenv to prisma.config.ts [#32-add-dotenv-to-prismaconfigts]
To get access to the variables in the `.env` file, they can either be loaded by your runtime, or by using `dotenv`.
Include an import for `dotenv` at the top of the `prisma.config.ts`
```ts
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
3.3 Run your first migration [#33-run-your-first-migration]
To create the database schema:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
This will:
* Apply your schema to the connected PostgreSQL database
* Generate your Prisma Client
* Create tables for `Project` and `Task` with a one-to-many relationship
3.3 Confirm the structure [#33-confirm-the-structure]
You can open Prisma Studio to inspect your database:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
This structure allows the `@permitio/permit-prisma` extension to filter records by user relationships at query time. Next, you'll seed test data to simulate distinct team ownership over projects and tasks.
4. Seed test data with project boundaries [#4-seed-test-data-with-project-boundaries]
To test your data filtering logic, you'll create two projects, each with its own set of tasks. This separation simulates team ownership and will allow you to validate that users only see the data of their assigned project.
4.1 Create the seed script [#41-create-the-seed-script]
Create a new file at `scripts/seed.ts` and add the following:
```ts
import { PrismaClient } from "../src/generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const prisma = new PrismaClient({
adapter,
});
async function main() {
console.log("🌱 Seeding test data...");
// Clear existing records
await prisma.task.deleteMany();
await prisma.project.deleteMany();
// Create Project Alpha for the Marketing team
const projectAlpha = await prisma.project.create({
data: {
id: "project_alpha",
name: "Marketing Campaign Q2",
},
});
// Create Project Beta for the Engineering team
const projectBeta = await prisma.project.create({
data: {
id: "project_beta",
name: "API Development Sprint",
},
});
// Add tasks to Project Alpha
await prisma.task.createMany({
data: [
{
id: "task-alpha-1",
name: "Strategy Planning",
description: "Define campaign goals and KPIs",
projectId: projectAlpha.id,
},
{
id: "task-alpha-2",
name: "Budget Review",
description: "Review marketing budget with finance",
projectId: projectAlpha.id,
},
],
});
// Add tasks to Project Beta
await prisma.task.createMany({
data: [
{
id: "task-beta-1",
name: "Implement Auth API",
description: "Create endpoints for user login/signup",
projectId: projectBeta.id,
},
{
id: "task-beta-2",
name: "Schema Migration",
description: "Update tables for new user roles",
projectId: projectBeta.id,
},
],
});
console.log("✅ Seeded 2 projects and 4 tasks with distinct ownership");
}
main()
.catch((e) => {
console.error("❌ Error seeding data:", e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
4.2 Run the seed script [#42-run-the-seed-script]
npm
pnpm
yarn
bun
```bash
npx tsx scripts/seed.ts
```
```bash
pnpm dlx tsx scripts/seed.ts
```
```bash
yarn dlx tsx scripts/seed.ts
```
```bash
bunx --bun tsx scripts/seed.ts
```
If successful, you'll see:
✅ Seeded 2 projects and 4 tasks with distinct ownership
At this point, if you run a query like `prisma.task.findMany()`, it will return all tasks. In the next steps, you'll connect Permit.io to filter these results automatically based on the user's access rights.
5. Install and configure ReBAC filtering [#5-install-and-configure-rebac-filtering]
In this section, you'll install the `@permitio/permit-prisma` extension and configure it to automatically filter Prisma queries based on your access control policies.
5.1 Install the Permit extension [#51-install-the-permit-extension]
Install the `permit-prisma` package:
npm
pnpm
yarn
bun
```bash
npm install @permitio/permit-prisma
```
```bash
pnpm add @permitio/permit-prisma
```
```bash
yarn add @permitio/permit-prisma
```
```bash
bun add @permitio/permit-prisma
```
5.2 Configure the Permit client [#52-configure-the-permit-client]
Create a new file at `src/config/permit-config.ts`:
```ts
import dotenv from "dotenv";
dotenv.config();
export const clientExtensionConfig = {
permitConfig: {
token: process.env.PERMIT_API_KEY!, // Your Permit.io API key
pdp: process.env.PERMIT_PDP_URL || "http://localhost:7766", // Local or cloud PDP
debug: true,
},
enableAutomaticChecks: true,
enableDataFiltering: true, // Enables automatic query filtering
enableResourceSync: true, // (Optional) Keeps Permit in sync with resource changes
};
```
API Key
You can find your API key and PDP URL in your [Permit.io dashboard](https://app.permit.io/).
5.3 What this configuration does [#53-what-this-configuration-does]
When you later extend the Prisma Client with this config:
* All Prisma queries will automatically check access rules
* `findMany()` and similar methods will **only return data the user is allowed to access**
* You no longer need to manually add `WHERE` clauses to enforce permissions
You're now ready to define your ReBAC policy using the Permit CLI.
6. Define your access control policy in Permit.io [#6-define-your-access-control-policy-in-permitio]
Next, you'll use the **Permit CLI** to apply a ready-made ReBAC template that matches your project-task structure.
6.1 Install the Permit CLI [#61-install-the-permit-cli]
npm
pnpm
yarn
bun
```bash
npm install -g @permitio/cli
```
```bash
pnpm add -g @permitio/cli
```
```bash
yarn global add @permitio/cli
```
```bash
bun add --global @permitio/cli
```
6.2 Log in to your Permit account [#62-log-in-to-your-permit-account]
Use the CLI to authenticate:
```bash
permit login
```
This opens a browser window where you can log in to your Permit.io account and link your CLI session to an environment.
6.3 Apply the ReBAC policy template [#63-apply-the-rebac-policy-template]
Permit provides a prebuilt policy structure for hierarchical data filtering.
Apply it using:
```bash
permit env template apply --template orm-data-filtering
```
This will create:
* **Resources**: `project`, `task`
* **Relationships**: `project` is the parent of `task`
* **Roles**:
* `project#Member`: User can access a specific project
* `task#Member`: Derived from project membership
* **Access policies**: Users with the appropriate roles can `read` each resource
6.4 View the policy in the Permit UI [#64-view-the-policy-in-the-permit-ui]
Go to the [Permit.io dashboard](https://app.permit.io/) and navigate to your environment to explore:
* Your resource graph
* Role derivations
* Relationship mappings
* Policy rules for `read` access
These rules are used by the @permitio/permit-prisma extension to determine which records to return for each user—automatically.
With your policy in place, you're now ready to wire up user context and filtering logic in your Express middleware.
7. Add middleware to set user context [#7-add-middleware-to-set-user-context]
To filter Prisma queries per user, you need to:
1. Identify the current user (simulated via an email header)
2. Attach the filtered Prisma Client instance to the request
3. Set the user in the Permit context (`prisma.$permit.setUser()`)
7.1 Create the middleware file [#71-create-the-middleware-file]
Create a new file: `src/middleware/auth.middleware.ts`
```ts
import { Request, Response, NextFunction } from "express";
import { PrismaClient } from "../generated/prisma/client.js";
import { PrismaPg } from "@prisma/adapter-pg";
import createPermitClientExtension from "@permitio/permit-prisma";
import { clientExtensionConfig } from "../config/permit-config";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
// Extend PrismaClient with Permit
const prisma = new PrismaClient({
adapter,
}).$extends(createPermitClientExtension(clientExtensionConfig));
// Extend Request type with Prisma and user context
export interface AuthRequest extends Request {
user?: { email: string };
prisma?: typeof prisma;
}
export const authenticate = (req: AuthRequest, res: Response, next: NextFunction): void => {
const userEmail = req.headers["x-user-email"] as string;
if (!userEmail) {
res.status(401).json({ error: "Missing user email" });
return;
}
// Register the user in Permit context
prisma.$permit.setUser(userEmail);
// Add user + Prisma client to request
req.user = { email: userEmail };
req.prisma = prisma;
next();
};
```
Going to prod.
In a production app, you'd replace the x-user-email header with proper authentication logic (e.g. JWT or session validation).
7.2 What this middleware does [#72-what-this-middleware-does]
* Reads the user's email from the request header
* Sets the user identity in the Permit context (used for query filtering)
* Adds the filtered Prisma client to the request object (`req.prisma`)
* Makes the user and database client available to all downstream route handlers
You're now ready to build your API endpoints without writing a single line of access control logic.
8. Build your API endpoints [#8-build-your-api-endpoints]
You'll now create two endpoints:
* `GET /api/projects`: returns all projects the user has access to
* `GET /api/tasks`: returns all tasks the user has access to (inherited from project membership)
Thanks to the Permit-Prisma integration, **you won't need to add any manual filtering logic**—it's handled automatically.
8.1 Get user-visible projects [#81-get-user-visible-projects]
Create a controller file: `src/controllers/project.controller.ts`
```ts
import { Response } from "express";
import { AuthRequest } from "../middleware/auth.middleware";
export const getProjects = async (req: AuthRequest, res: Response) => {
try {
const prisma = req.prisma!;
const projects = await prisma.project.findMany(); // Auto-filtered
res.json({
user: req.user?.email,
count: projects.length,
projects,
});
} catch (error: any) {
console.error("Error fetching projects:", error);
res.status(500).json({ error: error.message });
}
};
```
> Even though this is a raw findMany() query, only authorized records will be returned for the current user.
8.2 Get user-visible tasks [#82-get-user-visible-tasks]
Create another controller: `src/controllers/task.controller.ts`
```ts
import { Response } from "express";
import { AuthRequest } from "../middleware/auth.middleware";
export const getTasks = async (req: AuthRequest, res: Response) => {
try {
const prisma = req.prisma!;
const projectId = req.query.projectId as string;
const where = projectId ? { projectId } : undefined;
const tasks = await prisma.task.findMany({ where }); // Still filtered
res.json({
user: req.user?.email,
count: tasks.length,
tasks,
});
} catch (error: any) {
console.error("Error fetching tasks:", error);
res.status(500).json({ error: error.message });
}
};
```
projectId
Even if you provide a projectId manually, the query results are still filtered by permissions.
8.3 What this demonstrates [#83-what-this-demonstrates]
* You can write **normal Prisma queries**
* Users will only get records they're allowed to see
* You don't need custom role-checking logic in every handler
* Task access is **automatically derived** from project membership
You're now ready to wire it all together and launch the app.
9.1 Create your Express app [#91-create-your-express-app]
Create `src/app.ts`:
```ts
import express from "express";
import cors from "cors";
import { authenticate } from "./middleware/auth.middleware";
import { getProjects } from "./controllers/project.controller";
import { getTasks } from "./controllers/task.controller";
const app = express();
const PORT = process.env.PORT || 3000;
app.use(cors());
app.use(express.json());
// Auth middleware applies ReBAC filtering per request
app.get("/api/projects", authenticate, getProjects);
app.get("/api/tasks", authenticate, getTasks);
app.listen(PORT, () => {
console.log(`🚀 Server running at http://localhost:${PORT}`);
console.log(`🔐 ReBAC filtering is now active`);
});
```
9.2 Run the server [#92-run-the-server]
Start the development server with:
npm
pnpm
yarn
bun
```bash
npx tsx src/app.ts
```
```bash
pnpm dlx tsx src/app.ts
```
```bash
yarn dlx tsx src/app.ts
```
```bash
bunx --bun tsx src/app.ts
```
If everything is set up correctly, the console will display:
```
🚀 Server running at http://localhost:3000
🔐 ReBAC filtering is now active
```
9.3 Test your API [#93-test-your-api]
You can simulate requests as different users by setting the `x-user-email` header. This mimics logged-in users with access to specific projects.
Example: John (Marketing team member) [#example-john-marketing-team-member]
```bash
curl -H "x-user-email: john@company.com" http://localhost:3000/api/projects
```
This should only return Project Alpha (and its tasks).
Example: Mary (Engineering team member) [#example-mary-engineering-team-member]
```bash
curl -H "x-user-email: mary@company.com" http://localhost:3000/api/tasks
```
This should only return tasks from Project Beta.
If you haven't yet assigned users to project memberships in the Permit.io UI, visit the Policy Editor and assign users to roles (project#Member).
Once you've confirmed these results, your Prisma API is now enforcing secure, relationship-based access control, all **without adding manual filtering logic anywhere in your code.**
You've now built a secure API that:
* Filters query results based on user relationships
* Uses ReBAC to avoid role explosion and brittle permission logic
* Keeps Prisma queries clean, safe, and scalable
10. Next steps [#10-next-steps]
Now that you've successfully implemented data filtering with Prisma and ReBAC, you can extend this foundation to support more complex authorization use cases and developer tooling.
Extend your model [#extend-your-model]
* Add a `User` model and create a many-to-many `Membership` relationship between users and projects.
* Introduce instance-level roles like `Editor` or `Owner` with different permissions.
* Support additional actions like `create`, `update`, and `delete`, using Permit.io's role policies.
Add authentication [#add-authentication]
Integrate your API with an auth provider (e.g., [Clerk](/guides/authentication/clerk/nextjs), Auth0) and replace the `x-user-email` header with a secure identity mechanism (like a JWT token).
Use Permit Elements [#use-permit-elements]
Permit.io provides UI components for:
* Managing user access visually
* Reviewing access logs
* Approving access requests (MCP)
Explore [Permit Elements](https://docs.permit.io/embeddable-uis/overview/) to make access management easier for your end users or admins.
More resources [#more-resources]
* [Permit.io ReBAC Policy Setup Guide](https://docs.permit.io/overview/create-a-rebac-policy)
* [Read the full guide: Data Filtering with Prisma and ReBAC](https://docs.permit.io/how-to/enforce-permissions/data-filtering)
* [ReBAC vs RBAC - Learn when to use which](https://www.permit.io/blog/rbac-vs-rebac)
# Shopify (/docs/guides/integrations/shopify)
Introduction [#introduction]
[Shopify](https://www.shopify.com/) is a popular platform for building e-commerce stores. This guide will show you how to connect a Shopify app to a [Prisma Postgres](https://www.prisma.io/postgres) database in order to create internal notes for products.
Prerequisites [#prerequisites]
* [Node.js](https://nodejs.org/en/download/)
* [Shopify CLI](https://shopify.dev/docs/api/shopify-cli)
* [Shopify Partner Account](https://www.shopify.com/partners) and a [development store](https://shopify.dev/docs/api/development-stores#create-a-development-store-to-test-your-app)
1. Set up your project [#1-set-up-your-project]
If you do not have the Shopify CLI installed, you can install it with `npm install -g @shopify/cli`.
To start, initialize a new Shopify app using the Shopify CLI:
```bash
shopify app init
```
During setup, you'll be prompted to customize your app. Don't worry—just follow these recommended options to get started quickly and ensure your app is set up for success:
* *Get started building your app:* `Build a Remix app (recommended)`
* *For your Remix template, which language do you want:* `JavaScript`
* *App Name:* `prisma-store` *(name cannot contain `shopify`)*
Navigate to the `prisma-store` directory:
```bash
cd prisma-store
```
2. Set up Prisma [#2-set-up-prisma]
Prisma comes pre-installed in your project, but let's take a moment to update it to the latest version. This ensures you have access to the newest features, improvements, and the best possible experience as you build your app.
You will be swapping to a Prisma Postgres database, so delete the `migrations` folder along with the `dev.sqlite` file, inside of the `prisma` directory.
You need to update a few things in the `schema.prisma` file to get it working with Remix and Prisma Postgres.
* Swap to the new `prisma-client` generator.
* Update the provider to `postgresql`.
* Update the url to the new database URL.
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client-js" // [!code --]
provider = "prisma-client" // [!code ++]
output = "../app/generated/prisma" // [!code ++]
}
datasource db {
provider = "sqlite" // [!code --]
provider = "postgresql" // [!code ++]
url = "file:../dev.db" // [!code --]
}
model Session {
// ... existing model
}
```
Create a `prisma.config.ts` file to configure Prisma:
```typescript title="prisma.config.ts"
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config"; // [!code ++]
// [!code ++]
export default defineConfig({
// [!code ++]
schema: "prisma/schema.prisma", // [!code ++]
migrations: {
// [!code ++]
path: "prisma/migrations", // [!code ++]
}, // [!code ++]
datasource: {
// [!code ++]
url: env("DATABASE_URL"), // [!code ++]
}, // [!code ++]
}); // [!code ++]
```
Since Shopify apps typically have dotenv pre-installed, you should already have access to it. If not, install it with:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
To enable your app to store notes for each product, let's add a new `ProductNote` model to your Prisma schema.
This model will allow you to save and organize notes linked to individual products in your database through the `productGid` field.
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model Session {
// ... existing model
}
model ProductNote { // [!code ++]
id String @id @default(uuid()) // [!code ++]
productGid String // [!code ++]
body String? // [!code ++]
createdAt DateTime @default(now()) // [!code ++]
updatedAt DateTime @updatedAt // [!code ++]
} // [!code ++]
```
Next, Prisma will need to be updated to the latest version. Run:
npm
pnpm
yarn
bun
```bash
npm install prisma @types/pg --save-dev
```
```bash
pnpm add prisma @types/pg --save-dev
```
```bash
yarn add prisma @types/pg --dev
```
```bash
bun add prisma @types/pg --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client @prisma/adapter-pg pg
```
```bash
pnpm add @prisma/client @prisma/adapter-pg pg
```
```bash
yarn add @prisma/client @prisma/adapter-pg pg
```
```bash
bun add @prisma/client @prisma/adapter-pg pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Prisma Postgres allows you to create a new database on the fly, you can create a new database at the same time you initialize your project by adding the `--db` flag:
npm
pnpm
yarn
bun
```bash
npx prisma init --db
```
```bash
pnpm dlx prisma init --db
```
```bash
yarn dlx prisma init --db
```
```bash
bunx --bun prisma init --db
```
Once you've completed the prompts, it's time to access your new database:
1. **Open the [Prisma Console](https://console.prisma.io):**
* Log in and select your newly created database project.
2. **Get your database connection string:**
* Click the **Connect** button.
* Copy the connection string that appears. It should look similar to this:
```text
DATABASE_URL="postgresql://user:password@host:5432/database?sslmode=require"
```
3. **Configure your environment:**
* Create a new `.env` file in the root of your project.
* Paste the `DATABASE_URL` you just copied into this file.
4. **Apply your database schema:**
* Run the following command to create your tables and get your database ready:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
Then generate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
Now, before moving on, let's update your `db.server.ts` file to use the newly generated Prisma client with the driver adapter:
```tsx title="app/db.server.ts"
import { PrismaClient } from "@prisma/client"; // [!code --]
import { PrismaClient } from "./generated/prisma/client.js"; // [!code ++]
import { PrismaPg } from "@prisma/adapter-pg"; // [!code ++]
// [!code ++]
const adapter = new PrismaPg({
// [!code ++]
connectionString: process.env.DATABASE_URL, // [!code ++]
}); // [!code ++]
if (process.env.NODE_ENV !== "production") {
if (!global.prismaGlobal) {
global.prismaGlobal = new PrismaClient(); // [!code --]
global.prismaGlobal = new PrismaClient({ adapter }); // [!code ++]
}
}
const prisma = global.prismaGlobal ?? new PrismaClient(); // [!code --]
const prisma = global.prismaGlobal ?? new PrismaClient({ adapter }); // [!code ++]
export default prisma;
```
It is recommended to add `app/generated/prisma` to your `.gitignore` file.
3. Create your Remix model [#3-create-your-remix-model]
To keep your project organized, let's create a new `models/` folder. Inside this folder, add a file named `notes.server.js`. This will be the home for all your note-related logic and make your codebase easier to manage as your app grows.
The `notes.server.js` file will contain two functions:
* `getNotes` - This will get all the notes for a given product.
* `createNote` - This will create a new note for a given product.
Start by importing the Prisma client from `db.server.ts` and creating the `getNotes` function:
```js title="models/notes.server.js"
import prisma from "../db.server"; // [!code ++]
// [!code ++]
export const getNotes = async (productGid) => {
// [!code ++]
const notes = await prisma.productNote.findMany({
// [!code ++]
where: { productGid: productGid.toString() }, // [!code ++]
orderBy: { createdAt: "desc" }, // [!code ++]
}); // [!code ++]
return notes; // [!code ++]
}; // [!code ++]
```
To enable users to add new notes to your database, let's create a function in `notes.server.js` that uses `prisma.productNote.create`:
```js title="models/notes.server.js"
import prisma from "../db.server";
export const getNotes = async (productGid) => {
const notes = await prisma.productNote.findMany({
where: { productGid: productGid.toString() },
orderBy: { createdAt: "desc" },
});
return notes;
};
export const createNote = async (note) => {
// [!code ++]
const newNote = await prisma.productNote.create({
// [!code ++]
data: {
// [!code ++]
body: note.body, // [!code ++]
productGid: note.productGid, // [!code ++]
}, // [!code ++]
}); // [!code ++]
return newNote; // [!code ++]
}; // [!code ++]
```
4. Create your layout route [#4-create-your-layout-route]
Before those functions are able to be called, our route needs a layout to sit in. This layout route will feature a button for selecting a product, and will act as the parent for your `ProductNotes` route, keeping your app organized and user-friendly.
4.1. Create the ProductNotesLayout component [#41-create-the-productnoteslayout-component]
Start by creating the folder `routes/app.product-notes.jsx` and adding the `ProductNotesLayout` component inside of it:
```jsx title="app/routes/app.product-notes.jsx"
import { Page, Layout } from "@shopify/polaris"; // [!code ++]
// [!code ++]
export default function ProductNotesLayout() {
// [!code ++]
return (
// [!code ++]
{" "}
// [!code ++]
{" "}
// [!code ++]
// [!code ++]
{" "}
// [!code ++]
// [!code ++]
); // [!code ++]
} // [!code ++]
```
Next, create the `selectProduct` function and a `Button` to let the user pick a product:
```jsx title="app/routes/app.product-notes.jsx"
import { useNavigate } from "@remix-run/react";
import { Page, Layout } from "@shopify/polaris"; // [!code --]
import { Button, Page, Layout } from "@shopify/polaris"; // [!code ++]
export default function ProductNotesLayout() {
const navigate = useNavigate(); // [!code ++]
async function selectProduct() {
// [!code ++]
const products = await window.shopify.resourcePicker({
// [!code ++]
type: "product", // [!code ++]
action: "select", // [!code ++]
}); // [!code ++]
const selectedGid = products[0].id; // [!code ++]
navigate(`/app/product-notes/${encodeURIComponent(selectedGid)}`); // [!code ++]
} // [!code ++]
return (
{" "}
// [!code ++]
);
}
```
Remix renders provides the ability to render a nested route. Add an `` to the `routes/app.product-notes.jsx` file where the `ProductNotes` route will be rendered:
```jsx title="app/routes/app.product-notes.jsx"
import { useNavigate } from "@remix-run/react"; // [!code --]
import { Outlet, useNavigate } from "@remix-run/react"; // [!code ++]
import { Page, Button, Layout } from "@shopify/polaris";
export default function ProductNotesLayout() {
const navigate = useNavigate();
async function selectProduct() {
const products = await window.shopify.resourcePicker({
type: "product",
action: "select",
});
const selectedGid = products[0].id;
navigate(`/app/product-notes/${encodeURIComponent(selectedGid)}`);
}
return (
// [!code ++]
);
}
```
4.2. Add the ProductNotesLayout to the sidebar [#42-add-the-productnoteslayout-to-the-sidebar]
If you run `npm run dev`, you won't be able to see the `Product Notes` route. To fix this, you need to add the `ProductNotesLayout` to the `app.jsx` file so it shows up in the sidebar:
```jsx title="app/routes/app.jsx"
import { Link, Outlet, useLoaderData, useRouteError } from "@remix-run/react";
import { boundary } from "@shopify/shopify-app-remix/server";
import { AppProvider } from "@shopify/shopify-app-remix/react";
import { NavMenu } from "@shopify/app-bridge-react";
import polarisStyles from "@shopify/polaris/build/esm/styles.css?url";
import { authenticate } from "../shopify.server";
export const links = () => [{ rel: "stylesheet", href: polarisStyles }];
export const loader = async ({ request }) => {
await authenticate.admin(request);
return { apiKey: process.env.SHOPIFY_API_KEY || "" };
};
export default function App() {
const { apiKey } = useLoaderData();
return (
[ Home ](/app) [Product Notes](/app/product-notes) // [!code ++]
);
}
// Shopify needs Remix to catch some thrown responses, so that their headers are included in the response.
export function ErrorBoundary() {
return boundary.error(useRouteError());
}
export const headers = (headersArgs) => {
return boundary.headers(headersArgs);
};
```
5. Create your product notes route [#5-create-your-product-notes-route]
Currently, if you run `npm run dev` and navigate to the `Product Notes` route, you will see nothing once selecting a product.
Follow these steps to create the product notes route:
Create a new `routes/app/app.notes.$productGid.jsx` file which will take in the productGid as a parameter, and return the product notes associated with the product as well as a form to create a new note:
```jsx title="app/routes/app/app.notes.$productGid.jsx"
export default function ProductNotes() {
// [!code ++]
return (
// [!code ++]
<>> // [!code ++]
); // [!code ++]
} // [!code ++]
```
5.1. Render the notes [#51-render-the-notes]
On load, the route will need to fetch the notes for the product and display them.
Add a `loader` function to the route:
```jsx title="app/routes/app/app.notes.$productGid.jsx"
import { json } from "@remix-run/node"; // [!code ++]
import { useLoaderData } from "@remix-run/react"; // [!code ++]
import { getNotes } from "../models/note.server"; // [!code ++]
export const loader = async ({ params }) => {
// [!code ++]
const { productGid } = params; // [!code ++]
const notes = await getNotes(productGid); // [!code ++]
return json({ notes, productGid }); // [!code ++]
}; // [!code ++]
export default function ProductNotes() {
const { notes, productGid } = useLoaderData(); // [!code ++]
return <>>;
}
```
Map out the notes in the `ProductNotes` component, using Polaris components:
```jsx title="app/routes/app/app.notes.$productGid.jsx"
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { getNotes } from "../models/note.server";
import { Card, Layout, Text, BlockStack } from "@shopify/polaris"; // [!code ++]
export const loader = async ({ params }) => {
const { productGid } = params;
const notes = await getNotes(productGid);
return json({ notes, productGid });
};
export default function ProductNotes() {
const { notes, productGid } = useLoaderData();
return (
<>
{" "}
// [!code ++]
{" "}
// [!code ++]
{notes.length === 0 ? ( // [!code ++]
{" "}
// [!code ++] No notes yet. // [!code ++]
// [!code ++]
) : (
// [!code ++]
notes.map(
(
note, // [!code ++]
) => (
{" "}
// [!code ++]
{" "}
// [!code ++]
{note.body && ( // [!code ++]
{" "}
// [!code ++]
{note.body} // [!code ++]
// [!code ++]
)}{" "}
// [!code ++]
{" "}
// [!code ++] Added: {new Date(note.createdAt).toLocaleString()} // [!code ++]
{" "}
// [!code ++]
{" "}
// [!code ++]
// [!code ++]
),
) // [!code ++]
)}{" "}
// [!code ++]
{" "}
// [!code ++]
{" "}
// [!code ++]
>
);
}
```
You should be seeing "No notes yet.". If so, you're on the right track.
5.2. Add the form [#52-add-the-form]
A few things need to be added to the route in order to create a new note:
* Add an `action` function to the route.
* Display a `Toast` notification when a note is created.
* Import the `createNote` function from `models/note.server.js`.
* Import the `useActionData` and `useAppBridge`
```jsx title="app/routes/app/app.notes.$productGid.jsx"
import { json, redirect } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react"; // [!code --]
import { useLoaderData, useActionData } from "@remix-run/react"; // [!code ++]
import { getNotes } from "../models/note.server"; // [!code --]
import { getNotes, createNote } from "../models/note.server"; // [!code ++]
import { Card, Layout, Text, BlockStack } from "@shopify/polaris";
import { useAppBridge } from "@shopify/app-bridge-react"; // [!code ++]
export const loader = async ({ params }) => {
const { productGid } = params;
const notes = await getNotes(productGid);
return json({ notes, productGid });
};
export const action = async ({ request, params }) => {
// [!code ++]
const formData = await request.formData(); // [!code ++]
const body = formData.get("body")?.toString() || null; // [!code ++]
const { productGid } = params; // [!code ++]
// [!code ++]
await createNote({ productGid, body }); // [!code ++]
return redirect(`/app/product-notes/${encodeURIComponent(productGid)}`); // [!code ++]
}; // [!code ++]
export default function ProductNotes() {
const { notes, productGid } = useLoaderData();
const actionData = useActionData(); // [!code ++]
const app = useAppBridge(); // [!code ++]
useEffect(() => {
// [!code ++]
if (actionData?.ok) {
// [!code ++]
app.toast.show("Note saved", { duration: 3000 }); // [!code ++]
setBody(""); // [!code ++]
} // [!code ++]
}, [actionData, app]); // [!code ++]
return (
<>
{notes.length === 0 ? (
No notes yet.
) : (
notes.map((note) => (
{note.body && (
{note.body}
)}
Added: {new Date(note.createdAt).toLocaleString()}
))
)}
>
);
}
```
Now, you can build out the form that will call the `action` function:
```jsx title="app/routes/app/app.notes.$productGid.jsx"
import { json, redirect } from "@remix-run/node";
import { useLoaderData, useActionData } from "@remix-run/react";
import { getNotes, createNote } from "../models/note.server";
import { Card, Layout, Text, BlockStack } from "@shopify/polaris"; // [!code --]
import {
Card,
Layout,
Text,
BlockStack,
Form,
FormLayout,
TextField,
Button,
} from "@shopify/polaris"; // [!code ++]
import { useAppBridge } from "@shopify/app-bridge-react";
export const loader = async ({ params }) => {
const { productGid } = params;
const notes = await getNotes(productGid);
return json({ notes, productGid });
};
export const action = async ({ request, params }) => {
const formData = await request.formData();
const body = formData.get("body")?.toString() || null;
const { productGid } = params;
await createNote({ productGid, body });
return redirect(`/app/product-notes/${encodeURIComponent(productGid)}`);
};
export default function ProductNotes() {
const { notes, productGid } = useLoaderData();
const actionData = useActionData(); // [!code ++]
const app = useAppBridge(); // [!code ++]
useEffect(() => {
// [!code ++]
if (actionData?.ok) {
// [!code ++]
app.toast.show("Note saved", { duration: 3000 }); // [!code ++]
setBody(""); // [!code ++]
} // [!code ++]
}, [actionData, app]); // [!code ++]
return (
<>
{" "}
// [!code ++]
{" "}
// [!code ++]
{" "}
// [!code ++]
{" "}
// [!code ++]
{" "}
// [!code ++]
{notes.length === 0 ? (
No notes yet.
) : (
notes.map((note) => (
{note.body && (
{note.body}
)}
Added: {new Date(note.createdAt).toLocaleString()}
))
)}
>
);
}
```
You should now be able to add a note to a product and see it displayed.
6. Test your route [#6-test-your-route]
Run `npm run dev` and navigate to the `Product Notes` route.
* Navigate to Product Notes on the sidebar
* Select a product
* Add a note
* Verify that notes are displayed and saved correctly.
Next Steps [#next-steps]
Now that you have a working Shopify app connected to a Prisma Postgres database, you can:
* Extend your Prisma schema with more models and relationships
* Add create/update/delete routes and forms
More Info [#more-info]
* [Prisma Documentation](/orm)
* [Shopify Dev Documentation](https://shopify.dev/docs)
# Supabase with Accelerate (/docs/guides/integrations/supabase-accelerate)
Introduction [#introduction]
This guides teaches you how to add connection pooling to a PostgreSQL database hosted on [Supabase](https://supabase.com/) using [Prisma Accelerate](/accelerate).
Prisma Accelerate is a robust and mature connection pooler enabling your database to function properly during traffic spikes and high load scenarios. Check out this [video](https://www.youtube.com/watch?v=cnL75if6Aq0) demonstrating how it performs in a load test or [learn why connection pooling is important](https://www.prisma.io/blog/saving-black-friday-with-connection-pooling).
Prerequisites [#prerequisites]
To successfully complete this guide, you need **a connection string for a PostgreSQL instance hosted on Supabase**. It typically looks similar to this:
```bash no-copy
postgresql://postgres:[YOUR-PASSWORD]@db.nzpppscrldfwlzfalbrf.supabase.co:5432/postgres
```
If you already have a project using Prisma ORM, you can skip the first two steps and jump ahead to [Step 3. Install the Accelerate extension](#3-install-the-accelerate-extension).
1. Set up Prisma ORM [#1-set-up-prisma-orm]
Start by installing the Prisma CLI in your project:
npm
pnpm
yarn
bun
```bash
npm install prisma --save-dev
```
```bash
pnpm add prisma --save-dev
```
```bash
yarn add prisma --dev
```
```bash
bun add prisma --dev
```
Then, run the following command to initialize a new project:
npm
pnpm
yarn
bun
```bash
npx prisma init
```
```bash
pnpm dlx prisma init
```
```bash
yarn dlx prisma init
```
```bash
bunx --bun prisma init
```
This will create a new `prisma` directory with a `schema.prisma` file and add a `.env` file with the `DATABASE_URL` environment variable.
Update the file and set the `DATABASE_URL` to your Supabase connection string:
```text title=".env"
DATABASE_URL="postgresql://postgres:[YOUR-PASSWORD]@db.nzpppscrldfwlzfalbrf.supabase.co:5432/postgres"
```
Create a `prisma.config.ts` file to configure Prisma:
```typescript title="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"),
},
});
```
You'll need to install the `dotenv` package to load environment variables:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
2. Introspect your database [#2-introspect-your-database]
Next, run the following command to introspect your database and create your data model:
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
This command reads your database schema and creates new models in your `schema.prisma` file that match the tables in your database.
If you want to use Prisma Migrate in the future, you also need to [baseline your database](/orm/prisma-migrate/workflows/baselining).
3. Install the Accelerate extension [#3-install-the-accelerate-extension]
Install the Prisma Client extension for Accelerate:
npm
pnpm
yarn
bun
```bash
npm install @prisma/extension-accelerate
```
```bash
pnpm add @prisma/extension-accelerate
```
```bash
yarn add @prisma/extension-accelerate
```
```bash
bun add @prisma/extension-accelerate
```
This is needed to access Prisma Accelerate's connection pool.
4. Set up Accelerate in the Prisma Console [#4-set-up-accelerate-in-the-prisma-console]
To set up Accelerate in the Prisma Console, follow these steps:
1. Log into the [Prisma Console](https://console.prisma.io).
2. Select **New project**
3. Choose a **Name** for your project
4. In the **Choose your starting product** section, find the **Accelerate** card and click **Get started**
5. In the field for your **Database connection string**, paste your Supabase connection string
6. Select the **Region** that's closest to your database
7. Click **Create project**
8. On the next screen, click **Enable Accelerate**
Once you went through these steps, you'll be redirected to another page where you need to the click the **Generate API key** button.
You'll then be shown a new connection URL which enables you to connect to Prisma Accelerate's connection pool. This needs to be set as the new `DATABASE_URL` in your `.env` file:
```text title=".env"
DATABASE_URL="prisma://accelerate.prisma-data.net/?api_key=ey..."
```
If you want to use Prisma Migrate with Prisma Accelerate, you need to provide a direct database URL in your `prisma.config.ts` file. The Accelerate URL (starting with `prisma://`) is used for queries via PrismaClient, while the direct database URL is used for migrations.
Update your `prisma.config.ts`:
```typescript title="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("DIRECT_URL"), // Direct database URL for migrations
},
});
```
And add the `DIRECT_URL` to your `.env` file:
```text title=".env"
DATABASE_URL="prisma://accelerate.prisma-data.net/?api_key=ey..."
DIRECT_URL="postgresql://postgres:[YOUR-PASSWORD]@db.nzpppscrldfwlzfalbrf.supabase.co:5432/postgres"
```
5. Generate Prisma Client [#5-generate-prisma-client]
With your Prisma schema in place, you can go ahead and generate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
In Prisma v7, the `--no-engine` flag is no longer required when using Prisma Accelerate. Previously, you would run `prisma generate --no-engine`, but now the standard `prisma generate` command works for all use cases.
6. Send queries through the connection pool [#6-send-queries-through-the-connection-pool]
In your application code, you now need to apply the Accelerate extension to your Prisma Client instance:
```ts
import { PrismaClient } from "./generated/prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";
const prisma = new PrismaClient({
accelerateUrl: process.env.DATABASE_URL,
}).$extends(withAccelerate());
```
At this point, you can now start sending queries which will be routed through the connection pool to your database.
# Vercel app deployment (/docs/guides/integrations/vercel-deployment)
Introduction [#introduction]
This guide shows you how to implement instant app deployment using [Vercel](https://vercel.com)'s API with integrated [Prisma Postgres](/postgres) databases. You'll learn to programmatically create, deploy, and transfer full-stack applications with a single API call.
Instant app deployment solves a critical problem for AI coding platforms, no-code tools, and educational platforms: getting from generated code to a live, production-ready application. Instead of requiring users to manually set up hosting infrastructure, you can offer one-click deployments with both application and database.
By the end of this guide, you'll understand how to integrate Vercel's deployment API with Prisma Postgres to create a smooth deployment experience for your users.
Try the live demo [#try-the-live-demo]
Experience the instant deployment flow with [our interactive demo](https://pris.ly/vercel-app-demo-live). You can deploy and claim real applications to see the complete process in action.
**Available examples:**
* **Next.js + Prisma**: Basic full-stack application with database integration
* **Next.js + Prisma + Better Auth**: Complete application with authentication using [Better Auth](https://www.better-auth.com/)
**Demo features:**
* Deploy applications with one click
* Generate claim codes for user transfer
* Experience the complete claiming flow
* View source code and implementation details
[Visit the GitHub repository for the demo](https://pris.ly/vercel_app_deployment_demo?utm_source=docs).
Who is this for [#who-is-this-for]
This guide is designed for developers building:
* **AI-powered development platforms** that generate full applications and need instant deployment
* **No-code/low-code tools** that want to offer hosting without managing infrastructure
* **Educational platforms** where students need to deploy projects quickly
* **CI/CD systems** that need programmatic deployment capabilities
* **Rapid prototyping tools** that transform ideas into deployed applications
Core concepts [#core-concepts]
Before implementing the deployment flow, let's understand the key concepts:
Vercel deployment architecture [#vercel-deployment-architecture]
* **Projects**: Containers that hold your application code and configuration
* **Deployments**: Specific instances of your project deployed to Vercel's edge network
* **Teams**: Organizational units that own projects and manage billing
* **Integrations**: Third-party services (like Prisma) that connect to your projects
Prisma integration components [#prisma-integration-components]
* **Integration configuration**: Your team's connection to the Prisma service
* **Authorization**: Permission to create resources on behalf of your team
* **Database stores**: Individual Prisma Postgres instances
* **Resource connections**: Links between databases and Vercel projects
API endpoints overview [#api-endpoints-overview]
The deployment process uses several key Vercel API endpoints:
* `POST /v10/projects` - Create a new Vercel project
* `POST /v1/integrations/billing/authorization` - Authorize Prisma integration
* `POST /v1/storage/stores/integration` - Create Prisma Postgres database
* `POST /v13/deployments` - Deploy application code
* `POST /v9/projects/{id}/transfer-request` - Generate claim code for user transfer
Required API keys and environment variables [#required-api-keys-and-environment-variables]
Contact us for elevated partner level access for db creation
By default, every new partner is on our free plan which limited to 5 dbs per account, so if you are trying out this API and need higher db creation limits (which we suspect that most of you will), then please [contact us](https://www.prisma.io/partners#contact-us) to get partner level access.
Vercel access token [#vercel-access-token]
Your primary authentication token for Vercel API calls.
**Where to get it:**
1. Go to [Vercel Account Settings](https://vercel.com/account/tokens)
2. Click **Create Token**
3. Name it (e.g., "Instant Deployment API")
4. Set scope to your **team** (not personal account)
5. Copy the token immediately (you won't see it again)
You need "Owner" level access to the Vercel team to ensure the `ACCESS_TOKEN` works for all the API calls.
```bash
ACCESS_TOKEN="vercel_token_here"
```
Credit card requirement
Vercel requires a credit card to be attached to your account (even on the Hobby plan) to use the deployment APIs. Make sure to add payment information in your Vercel account settings before proceeding.
Team ID [#team-id]
Your Vercel team identifier for API requests.
**Where to get it:**
1. Go to [Vercel Dashboard](https://vercel.com/dashboard)
2. Switch to your **Team** (not personal account)
3. Go to **Team Settings**
4. Copy the Team ID displayed at the top (format: `team_abc123xyz`)
```bash
TEAM_ID="team_abc123xyz"
```
Prisma integration config ID [#prisma-integration-config-id]
Your team's Prisma integration configuration identifier.
**Where to get it:**
1. In Vercel Dashboard, go to your **Team**
2. Click **Integrations** tab
3. Find **Prisma** and click **Manage** (install it first if needed)
4. In the browser URL, copy the config ID: `https://vercel.com/teams/your-team/integrations/icfg_abc123xyz`
5. Copy the `icfg_abc123xyz` part
```bash
INTEGRATION_CONFIG_ID="icfg_abc123xyz"
```
Prisma Product ID [#prisma-product-id]
The Prisma Product ID is used to identify the Prisma integration in the Vercel API and it's a constant value of: `iap_yVdbiKqs5fLkYDAB` or `prisma-postgres`.
```bash
PRISMA_PRODUCT_ID="iap_yVdbiKqs5fLkYDAB"
```
Prisma Postgres region [#prisma-postgres-region]
The region where your Prisma Postgres database will be deployed. Choose a region close to your users for optimal performance.
**Available regions:**
* `iad1` - US East (Virginia)
* `fra1` - Europe (Frankfurt)
* `sfo1` - US West (San Francisco)
* `sin1` - Asia Pacific (Singapore)
* `hnd1` - Asia Pacific (Tokyo)
* `cdg1` - Europe (Paris)
```bash
PRISMA_POSTGRES_REGION="iad1"
```
See the complete list of [supported Prisma Postgres regions](/postgres/faq#what-regions-is-prisma-postgres-available-in) and their corresponding [Vercel region codes](https://vercel.com/docs/regions#region-list).
Prisma billing plan [#prisma-billing-plan]
The billing plan determines database limits and features. Available plans:
* `free` - Limited to 5 databases, suitable for development
* `pro` - Higher limits with connection pooling and caching
* `business` - Enterprise features with priority support
* `enterprise` - Custom limits and dedicated support
* `partnerEntry` - Partner-level access with high database limits
```bash
PRISMA_BILLING_PLAN="partnerEntry"
```
Partner access recommended
For production deployments requiring multiple databases, we recommend the `partnerEntry` plan which provides higher database creation limits. [Apply for partner access](https://www.prisma.io/partners) to unlock these capabilities.
Complete deployment example [#complete-deployment-example]
The code snippet below shows the complete deployment flow:
```typescript
const CONFIG = {
ACCESS_TOKEN: process.env.ACCESS_TOKEN,
TEAM_ID: process.env.TEAM_ID,
INTEGRATION_CONFIG_ID: process.env.INTEGRATION_CONFIG_ID,
PRISMA_PRODUCT_ID: process.env.PRISMA_PRODUCT_ID || "iap_yVdbiKqs5fLkYDAB", // or can be `prisma-postgres`
PRISMA_POSTGRES_REGION: process.env.PRISMA_POSTGRES_REGION || "iad1",
PRISMA_BILLING_PLAN: process.env.PRISMA_BILLING_PLAN || "partnerEntry",
VERCEL_API_URL: "https://api.vercel.com",
};
async function deployApp() {
console.log("🚀 Starting instant deployment...");
// 1. Create project
const project = await createProject();
// 2. Authorize Prisma integration
const auth = await createPrismaAuthorization();
// 3. Create database
const database = await createPrismaDatabase(project.name, auth.id, auth.configId);
// 4. Connect database to project
await connectDatabaseToProject(project.id, database.id, auth.configId);
// 5. Deploy application (assumes files already uploaded)
const deployment = await deployApplication(project.name, fileSha);
// 6. Generate claim code
const transfer = await createProjectTransfer(project.id);
console.log("🎉 Deployment completed!");
console.log(`Live URL: https://${deployment.url}`);
console.log(`Claim URL: ${transfer.claimUrl}`);
return {
projectId: project.id,
deploymentUrl: `https://${deployment.url}`,
claimCode: transfer.code,
claimUrl: transfer.claimUrl,
};
}
```
Step-by-step deployment process [#step-by-step-deployment-process]
The complete example above demonstrates the entire deployment process. Now let's break down each step in detail.
Step 1: Create a Vercel project [#step-1-create-a-vercel-project]
Every deployment starts with creating a project container.
```typescript
async function createProject(): Promise<{ id: string; name: string }> {
const projectName = `demo-project-${Date.now()}`;
const response = await fetch(`${CONFIG.VERCEL_API_URL}/v10/projects?teamId=${CONFIG.TEAM_ID}`, {
method: "POST",
headers: {
Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ name: projectName }),
});
const project = await response.json();
console.log(`✅ Project created: ${project.name} (${project.id})`);
return { id: project.id, name: project.name };
}
```
**Key parameters:**
* `name`: Unique project identifier (auto-generated with timestamp)
* `teamId`: Your team ID for proper project ownership
Learn more in the [Vercel Projects API documentation](https://vercel.com/docs/rest-api/reference/endpoints/projects/create-a-new-project).
Step 2: Authorize Prisma integration [#step-2-authorize-prisma-integration]
Before creating databases, you need authorization to use Prisma on behalf of your team.
```typescript
async function createPrismaAuthorization(): Promise<{
id: string;
configId: string;
}> {
const response = await fetch(
`${CONFIG.VERCEL_API_URL}/v1/integrations/billing/authorization?teamId=${CONFIG.TEAM_ID}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
integrationIdOrSlug: "prisma",
productId: CONFIG.PRISMA_PRODUCT_ID,
billingPlanId: CONFIG.PRISMA_BILLING_PLAN,
metadata: JSON.stringify({ region: CONFIG.PRISMA_POSTGRES_REGION }),
integrationConfigurationId: CONFIG.INTEGRATION_CONFIG_ID,
}),
},
);
const authData = await response.json();
return {
id: authData.authorization.id,
configId: authData.authorization.integrationConfigurationId,
};
}
```
**Key parameters:**
* `billingPlanId`: Billing plan ("partnerEntry" recommended for production)
* `region`: Database region for optimal performance
* `metadata`: JSON string containing region and other configuration
Learn more in the [Vercel Integrations API documentation](https://vercel.com/docs/integrations/create-integration/marketplace-api).
Step 3: Provision Prisma Postgres database [#step-3-provision-prisma-postgres-database]
Create a new database instance with automatic connection pooling and caching.
```typescript
async function createPrismaDatabase(
projectName: string,
authId: string,
configId: string,
): Promise<{ id: string }> {
const response = await fetch(
`${CONFIG.VERCEL_API_URL}/v1/storage/stores/integration?teamId=${CONFIG.TEAM_ID}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
metadata: { region: CONFIG.PRISMA_POSTGRES_REGION },
billingPlanId: CONFIG.PRISMA_BILLING_PLAN,
name: `postgres-${projectName}`,
integrationConfigurationId: configId,
integrationProductIdOrSlug: CONFIG.PRISMA_PRODUCT_ID,
authorizationId: authId,
source: "marketplace",
}),
},
);
const storageData = await response.json();
return {
id: storageData.store.id,
};
}
```
**Key parameters:**
* `name`: Database identifier (typically matches project name)
* `source`: "marketplace" for Vercel marketplace integrations
* `billingPlanId`: Billing plan that determines features and limits
Learn more in the [Vercel Storage API documentation](https://vercel.com/docs/rest-api/reference/endpoints/integrations/create-integration-store-free-and-paid-plans).
Step 4: Connect database to project [#step-4-connect-database-to-project]
Link the database to your Vercel project for automatic environment variable injection.
```typescript
async function connectDatabaseToProject(
projectId: string,
storeId: string,
configId: string,
): Promise {
await fetch(
`${CONFIG.VERCEL_API_URL}/v1/integrations/installations/${configId}/products/${CONFIG.PRISMA_PRODUCT_ID}/resources/${storeId}/connections?teamId=${CONFIG.TEAM_ID}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ projectId }),
},
);
console.log("✅ Database connected to project");
}
```
This connection automatically adds `DATABASE_URL` and other environment variables to your project.
Learn more in the [Vercel Integration Resources documentation](https://vercel.com/docs/rest-api/reference/endpoints/integrations/connect-integration-resource-to-project).
Step 5: Deploy the application [#step-5-deploy-the-application]
Deploy your application code to Vercel.
```typescript
async function deployApplication(
projectName: string,
fileSha: string,
): Promise<{ id: string; url: string }> {
const response = await fetch(
`${CONFIG.VERCEL_API_URL}/v13/deployments?teamId=${CONFIG.TEAM_ID}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
files: [{ file: ".vercel/source.tgz", sha: fileSha }],
name: `deployment-${Date.now()}`,
projectSettings: { framework: "nextjs" },
project: projectName,
}),
},
);
const deploymentData = await response.json();
return {
id: deploymentData.id,
url: deploymentData.alias?.[0] || deploymentData.url,
};
}
```
**Key parameters:**
* `files`: Array of uploaded files (requires prior file upload in `tgz` format)
* `framework`: "nextjs", "react", "vue", etc. for automatic configuration
* `projectSettings`: Framework-specific build and runtime settings
Learn more in the [Vercel Deployments API documentation](https://vercel.com/docs/rest-api/reference/endpoints/deployments/create-a-new-deployment) or see the [Vercel API Reference](https://vercel.com/docs/rest-api/reference).
Step 6: Generate claim code for user transfer [#step-6-generate-claim-code-for-user-transfer]
Create a transfer code that allows users to claim ownership of the deployed project.
```typescript
async function createProjectTransfer(
projectId: string,
): Promise<{ code: string; claimUrl: string }> {
const response = await fetch(
`${CONFIG.VERCEL_API_URL}/v9/projects/${projectId}/transfer-request?teamId=${CONFIG.TEAM_ID}`,
{
method: "POST",
headers: {
Authorization: `Bearer ${CONFIG.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
},
);
const transferData = await response.json();
const claimUrl = `https://vercel.com/claim-deployment?code=${transferData.code}&returnUrl=https://myapp.com/dashboard/projects`;
return {
code: transferData.code,
claimUrl,
};
}
```
**Key details:**
* Transfer codes are valid for **24 hours**
* Users can claim projects to any team in their Vercel account
* The `returnUrl` redirects users to a specific page if the claim URL is invalid or expired
Learn more in the [Vercel Claim Deployments documentation](https://vercel.com/docs/deployments/claim-deployments).
User claim flow [#user-claim-flow]
After deployment, users can claim ownership through a secure transfer process:
How claiming works [#how-claiming-works]
1. **User receives claim URL**: Your platform provides the generated claim URL
2. **User authentication**: Vercel prompts for login if not authenticated
3. **Team selection**: User chooses which Vercel team should own the project
4. **Transfer completion**: Project and database transfer to user's selected team
5. **Billing transfer**: User's team becomes responsible for hosting costs
Claim URL structure [#claim-url-structure]
```
https://vercel.com/claim-deployment?code=xxx&returnUrl=https://myapp.com/dashboard/projects
```
**Parameters:**
* `code`: The transfer code from Step 6 (valid 24 hours)
* `returnUrl`: Redirects users to a specific page if the claim URL is invalid or expired
What gets transferred [#what-gets-transferred]
When a user claims a deployment, they receive:
* **Full project ownership** with all source code and configuration
* **Database ownership** including all data and connection strings
* **Environment variables** automatically updated for the new team
* **Deployment history** and build logs
Learn more in the [Claim Deployments documentation](https://vercel.com/docs/deployments/claim-deployments).
Error handling and best practices [#error-handling-and-best-practices]
Common error scenarios [#common-error-scenarios]
```typescript
async function handleApiErrors(response: Response, operation: string) {
if (!response.ok) {
const errorData = await response.text();
// Handle specific error cases
switch (response.status) {
case 401:
throw new Error(`Authentication failed: Check your ACCESS_TOKEN`);
case 403:
throw new Error(`Permission denied: Verify team access and scopes`);
case 429:
throw new Error(`Rate limit exceeded: Implement retry logic`);
case 404:
throw new Error(`Resource not found: Check IDs and configuration`);
default:
throw new Error(`${operation} failed: ${response.status} - ${errorData}`);
}
}
}
```
Proper error handling prevents deployment failures and provides clear debugging information to your users.
Rate limiting considerations [#rate-limiting-considerations]
Vercel enforces rate limits on API endpoints. You can implement exponential backoff to handle rate limits:
```typescript
async function apiCallWithRetry(url: string, options: RequestInit, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch(url, options);
if (response.status === 429) {
const waitTime = Math.pow(2, attempt) * 1000; // Exponential backoff
await new Promise((resolve) => setTimeout(resolve, waitTime));
continue;
}
return response;
} catch (error) {
if (attempt === maxRetries) throw error;
}
}
}
```
Retry logic ensures your deployment service remains reliable during high-traffic periods.
Learn more in the [Vercel API Limits documentation](https://vercel.com/docs/limits).
Security best practices [#security-best-practices]
* **Store tokens securely**: Never expose API tokens in client-side code
* **Validate inputs**: Sanitize project names and user-provided data
* **Monitor usage**: Track API calls to prevent abuse
* **Implement timeouts**: Set reasonable request timeouts for reliability
These practices protect your integration from common security vulnerabilities and ensure stable operation.
Production considerations [#production-considerations]
The following are some production considerations for your deployment service:
Integration with existing platforms [#integration-with-existing-platforms]
You can integrate your deployment service with existing platforms to provide a smooth experience for your users:
```typescript
// Example integration with an AI coding platform
class DeploymentService {
async deployGeneratedApp(code: string, userId: string) {
// 1. Package generated code
const packagedCode = await this.packageCode(code);
// 2. Deploy with Vercel + Prisma
const deployment = await this.deployApp(packagedCode);
// 3. Store deployment info
await this.storeDeployment(userId, deployment);
// 4. Notify user
await this.notifyUser(userId, deployment.claimUrl);
return deployment;
}
}
```
Monitoring and analytics [#monitoring-and-analytics]
Track key metrics for your deployment service:
* **Deployment success rate**: Monitor API failures and timeouts
* **Claim conversion rate**: Track how many users claim their deployments
* **Performance metrics**: Measure deployment time and user experience
* **Cost analysis**: Monitor Vercel and Prisma usage costs
Next steps [#next-steps]
Now that you understand instant app deployment with Vercel and Prisma Postgres, you can:
* **Integrate into your platform**: Add deployment capabilities to your existing application
* **Customize the flow**: Adapt the process for your specific use case and user experience
* **Scale your implementation**: Handle high-volume deployments with proper queuing and error handling
* **Monitor and optimize**: Track performance and user adoption metrics
Additional resources [#additional-resources]
* [Vercel REST API Documentation](https://vercel.com/docs/rest-api)
* [Vercel Claim Deployments Guide](https://vercel.com/docs/deployments/claim-deployments)
* [Vercel Integration API Reference](https://vercel.com/docs/integrations/create-integration/marketplace-api)
* [Prisma Postgres Documentation](/postgres)
* [Vercel Limits and Quotas](https://vercel.com/docs/limits)
For questions or support with your integration, reach out through the [Prisma Community Discord](https://pris.ly/discord) or [Vercel Support](https://vercel.com/help).
# Fly.io (/docs/guides/postgres/flyio)
[Fly.io](https://fly.io/) is a cloud application platform that lets you deploy full-stack applications globally. This guide shows you how to deploy a Node.js application using Prisma Postgres to Fly.io.
Prerequisites [#prerequisites]
* A [Fly.io account](https://fly.io/docs/getting-started/launch/)
* The [Fly CLI](https://fly.io/docs/flyctl/install/) installed
* An existing application using [Prisma Postgres](/postgres) (see [Quickstart](/prisma-postgres/quickstart/prisma-orm))
Deploy your application [#deploy-your-application]
1. Generate Prisma Client in postinstall [#1-generate-prisma-client-in-postinstall]
Ensure your `package.json` includes a `postinstall` script to generate Prisma Client during deployment:
```json title="package.json"
{
// ...
"scripts": {
// ...
"postinstall": "prisma generate" // [!code ++]
}
}
```
2. Launch your app with Fly.io [#2-launch-your-app-with-flyio]
From your project directory, run:
```bash
fly launch
```
Follow the prompts to configure your application. Fly.io will auto-detect your Node.js application and create the necessary configuration.
3. Set your database connection string [#3-set-your-database-connection-string]
Add your Prisma Postgres `DATABASE_URL` as a secret in Fly.io:
```bash
fly secrets set DATABASE_URL="your-prisma-postgres-connection-string"
```
You can find your `DATABASE_URL` in your `.env` file or in the [Prisma Console](https://console.prisma.io).
4. Deploy [#4-deploy]
If not already deployed during `fly launch`, deploy your application:
```bash
fly deploy
```
Once the deployment completes, you'll see a success message with your app's URL:
```
🎉 SUCCESS! Your app is live and ready to use! 🎉
Visit: https://your-app-name.fly.dev/
```
In the Fly.io dashboard, your app's status may show as "Pending" initially. It typically transitions to "Deployed" within a few minutes.
Additional considerations [#additional-considerations]
Ensure your project uses the correct environment variable [#ensure-your-project-uses-the-correct-environment-variable]
Ensure that the data source in your `prisma.config.ts` file is configured to use the `DATABASE_URL` environment variable:
```ts title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
datasource: {
url: env("DATABASE_URL"),
},
schema: "./prisma/schema.prisma",
});
```
Running migrations in production [#running-migrations-in-production]
To run migrations on your deployed Fly.io app, you can use:
```bash
fly ssh console -C "npx prisma migrate deploy"
```
Or add a release command to your `fly.toml`:
```toml title="fly.toml"
[deploy]
release_command = "npx prisma migrate deploy"
```
Scaling and regions [#scaling-and-regions]
Fly.io lets you scale and place your application in [multiple regions](https://fly.io/docs/reference/regions/). For optimal performance, deploy your app in a region close to your Prisma Postgres database region.
```bash
fly scale count 2 --region iad
```
Troubleshooting [#troubleshooting]
Prisma schema not found or Client not generated correctly [#prisma-schema-not-found-or-client-not-generated-correctly]
If you're using a custom Dockerfile and your build fails because the Prisma Client cannot be found, it's likely due to one of two reasons:
1. **Order of operations**: `npm install` (which runs `postinstall`) runs before the schema is copied.
2. **Incorrect copy path**: The schema is copied to the root instead of the `prisma` folder.
**Solution:** In your Dockerfile, copy the `prisma/` directory to `./prisma` **before** running `npm install`:
```dockerfile
# ❌ Wrong order or path
COPY package*.json ./
COPY prisma . # Copies contents to root (wrong structure)
RUN npm install # postinstall runs but might fail or generate in wrong place
# ✅ Correct order and path
COPY package*.json ./
COPY prisma ./prisma # Copies to ./prisma folder (preserves structure)
RUN npm install # postinstall finds schema in expected location
COPY . .
```
More information [#more-information]
* [Fly.io Node.js documentation](https://fly.io/docs/languages-and-frameworks/node/)
* [Fly.io Prisma documentation](https://fly.io/docs/js/prisma/)
* [Prisma Postgres documentation](/postgres)
# Firebase Studio (/docs/guides/postgres/idx)
If you want to explore Prisma Postgres without leaving your browser, you can try it out the via Google's [Firebase Studio](https://studio.firebase.google.com/), a fully-fledged online IDE:
1. Open the [**Prisma**](https://pris.ly/idx-starter) template.
2. Select **Prisma Postgres** as your database.
3. Give a **Name** to your workspace and click the **Create** button.
4. Wait until the Firebase Studio workspace has initialized and then follow the instructions in the README.
# Netlify (/docs/guides/postgres/netlify)
The [Netlify extension for Prisma Postgres](https://www.netlify.com/integrations/prisma) connects your Netlify sites with Prisma Postgres instances. Once connected, the extension will automatically set the `DATABASE_URL` environment variable on your deployed Netlify sites.
Features [#features]
* Automatic generation of Prisma Postgres API keys for production and preview environments.
* Simplified environment configuration for your Netlify site.
Usage [#usage]
Install the extension [#install-the-extension]
To install the extension, click **Install** at the top of the [Prisma Postgres extension page](https://www.netlify.com/integrations/prisma).
Add the Prisma Platform integration token to your Netlify team [#add-the-prisma-platform-integration-token-to-your-netlify-team]
Perform the following steps *once* to connect your Netlify team with a Prisma Platform workspace:
1. Log in to your [Prisma Console](https://console.prisma.io).
2. Select the workspace you want to connect to Netlify.
3. Navigate to the **Integrations** menu in the left-hand sidebar.
4. Follow the prompts to create a new Netlify integration token and copy the token value.
5. Paste the token into the **Integration Token** field above. The workspace ID will be automatically filled in.
6. Click **Save** to complete the setup.
Once this setup is complete, your Netlify team is connected to your Prisma workspace. You can now configure individual Netlify sites to use Prisma Postgres.
Add Prisma Postgres to a Netlify site [#add-prisma-postgres-to-a-netlify-site]
Perform the following steps *for every Netlify site* in which you want to use Prisma Postgres:
1. Go to the site view in Netlify and click **Prisma Postgres** under the **Extensions** section.
2. From the **Project** selector, choose the Prisma project you want to connect to your Netlify site.
3. Configure the environment for your **Production environment**.
4. Configure the environment for your **Preview environment**.
5. Click **Save** to complete the site setup.
6. The extension will automatically create a Prisma Postgres instance and store its connection URL in the `DATABASE_URL` environment variable.
Additional considerations [#additional-considerations]
Ensure your project uses the DATABASE_URL environment variable [#ensure-your-project-uses-the-database_url-environment-variable]
Ensure that the data source in your `prisma.config.ts` file is configured to use the `DATABASE_URL` environment variable:
```typescript
// prisma.config.ts
import "dotenv/config";
import { defineConfig, env } from "@prisma/config";
export default defineConfig({
datasource: {
url: env("DATABASE_URL"),
},
schema: "./prisma/schema.prisma",
});
```
Generate Prisma Client in a postinstall script in package.json [#generate-prisma-client-in-a-postinstall-script-in-packagejson]
To ensure the generated Prisma Client library is available on your deployed Netlify site, you should add a `postinstall` script to the `scripts` section of your `package.json` file:
```js title="package.json"
{
// ...
"scripts": {
// ...
"postinstall": "prisma generate" // [!code ++]
}
//
}
```
Example: Deploy a Next.js template with Prisma Postgres [#example-deploy-a-nextjs-template-with-prisma-postgres]
This section contains step-by-step instructions for deploying a Netlify site and connecting it to Prisma Postgres from scratch using Netlify's official [Next.js Platform Starter](https://github.com/netlify-templates/next-platform-starter) template.
1. Create a new site using the template [#1-create-a-new-site-using-the-template]
In your Netlify team, create a new site using the template:
1. Select **Sites** in the left sidenav.
2. Click the **Add new site** button.
3. In the dropdown, select **Start from a template**.
4. Select the **Next.js Platform Starter**.
5. Follow the prompts to **Clone this template to your Git provider**.
6. Enter a **Site name** and click the **Deploy site** button.
Once you're done with this, you'll be able to access the deployed version of this starter project.
2. Set up a Prisma Postgres instance [#2-set-up-a-prisma-postgres-instance]
Next, set up a Prisma Postgres instance:
1. Log in to [Prisma Platform](https://console.prisma.io/) and open the Console.
2. In a [workspace](/console/concepts#workspace) of your choice, click the **New project** button.
3. Type a name for your project in the **Name** field, e.g. **hello-ppg**.
4. In the **Prisma Postgres** section, click the **Get started** button.
5. In the **Region** dropdown, select the region that's closest to your current location, e.g. **US East (N. Virginia)**.
6. Click the **Create project** button.
7. Click the **Connect to your Database** button
8. Save the `DATABASE_URL` environment variable, you'll need it in the next section.
3. Locally add Prisma Postgres to the project [#3-locally-add-prisma-postgres-to-the-project]
In this section, you are going to add Prisma Postgres to the starter project *on your local machine*:
3.1. Set up Prisma ORM [#31-set-up-prisma-orm]
1. Clone the Next.js Platform Starter repo that was added to your GitHub account in step 1.
2. Navigate into the project directory, e.g.: `cd next-platform-starter`.
3. Install the Prisma CLI as a development dependency:
npm
pnpm
yarn
bun
```bash
npm install prisma --save-dev
```
```bash
pnpm add prisma --save-dev
```
```bash
yarn add prisma --dev
```
```bash
bun add prisma --dev
```
4. Initialize Prisma ORM to create Prisma schema, config and `.env` file:
npm
pnpm
yarn
bun
```bash
npx prisma init
```
```bash
pnpm dlx prisma init
```
```bash
yarn dlx prisma init
```
```bash
bunx --bun prisma init
```
3.2. Run migration and create sample data [#32-run-migration-and-create-sample-data]
1. Open the newly created `schema.prisma` file and add the following model to it:
```prisma title="schema.prisma"
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
name String? // [!code ++]
email String @unique // [!code ++]
} // [!code ++]
```
2. Open the newly created `.env` file and paste the `DATABASE_URL` environment variable from the previous section into it.
3. Run your first migration to map the `User` model to the database:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
4. Create (at least) one `User` record in the database with Prisma Studio:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
3.3. Update application code to query and show User records [#33-update-application-code-to-query-and-show-user-records]
Open the `app/page.jsx` file and replace the entire contents with this code:
```tsx title="app/page.jsx"
import "dotenv/config";
import { PrismaClient } from "../path/to/generated/prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";
const databaseUrl = process.env.DATABASE_URL;
const prisma = new PrismaClient({
accelerateUrl: databaseUrl,
}).$extends(withAccelerate());
export default async function Page() {
const users = await prisma.user.findMany();
return (
Users
{users.length > 0 ? (
users.map((user) => (
ID: {user.id}
Name: {user.name || "N/A"}
Email: {user.email}
))
) : (
No users found.
)}
);
}
```
With this code in place, you can now go ahead and run the app locally:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
You should see a list of the `User` records that you created in the previous step.
3.4. Add the postinstall script to generate Prisma Client [#34-add-the-postinstall-script-to-generate-prisma-client]
As mentioned [above](#generate-prisma-client-in-a-postinstall-script-in-packagejson), you need to add a `postinstall` script to your `package.json` to ensure your Prisma Client library gets properly generated:
```json title="package.json"
{
"name": "next-netlify-platform-starter",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"postinstall": "prisma generate" // [!code ++]
},
"dependencies": {
"@netlify/blobs": "^8.1.0",
"@prisma/client": "^7.0.0",
"@prisma/extension-accelerate": "^1.2.1",
"blobshape": "^1.0.0",
"bright": "^0.8.5",
"markdown-to-jsx": "^7.4.5",
"next": "15.1.6",
"react": "18.3.1",
"react-dom": "18.3.1",
"unique-names-generator": "^4.7.1"
},
"devDependencies": {
"autoprefixer": "^10.4.18",
"daisyui": "^4.12.8",
"eslint": "8.57.1",
"eslint-config-next": "15.1.6",
"postcss": "^8.4.36",
"prisma": "^7.0.0",
"tailwindcss": "^3.4.1"
}
}
```
4. Configure the Netlify extension for Prisma Postgres [#4-configure-the-netlify-extension-for-prisma-postgres]
In this section, you need to add the Netlify extension to your Netlify site. Follow the instructions in the [Usage](#usage) section above to do that.
After having completed these steps, find the **Trigger deploy** button and select **Clear cache and deploy site** in the dropdown.
5. Validate the deployment [#5-validate-the-deployment]
Open the deployed site by clicking the **Open production deploy** button. You should now see the same UI as you did at the end of step 3 when you were running the app locally.
# Vercel (/docs/guides/postgres/vercel)
The [Vercel Marketplace integration for Prisma Postgres](https://www.vercel.com/marketplace/prisma) connects your Vercel projects with Prisma Postgres instances. Once connected, the integration will automatically set the following environment variable on your deployed Vercel app:
* `DATABASE_URL`: A Prisma Postgres [connection string](/postgres/database/connecting-to-your-database) starting with `postgres://...`
These enable you to connect to the Prisma Postgres instances via any ORM or database library you want to use (Prisma ORM, Drizzle, Kysely, ...).
Features [#features]
* Create and use Prisma Postgres instances without leaving the Vercel dashboard.
* Automatic generation of Prisma Postgres URLs for production and preview environments.
* Simplified environment configuration for your Vercel project.
* Billing workflows to up-/ and downgrade your Prisma Postgres pricing plan.
* Ready-to-deploy fullstack templates for Next.js, Nuxt, SvelteKit and with various ORMs and DB libraries.
Templates [#templates]
The easiest way to use Prisma Postgres on the Vercel Marketplace is via one of the templates:
* [Prisma ORM + NextAuth Starter](https://vercel.com/templates/next.js/prisma-postgres)
* [Postgres + Kysely Next.js Starter](https://vercel.com/templates/next.js/postgres-kysely)
* [Postgres + Drizzle Next.js Starter](https://vercel.com/templates/next.js/postgres-drizzle)
* [Postgres + SvelteKit Starter](https://vercel.com/templates/svelte/postgres-sveltekit)
Usage [#usage]
Install the extension [#install-the-extension]
To install the extension, click **Install** at the top of the [Prisma Postgres integration page](https://www.vercel.com/marketplace/prisma).
The integration will now show up on your list of integrations, e.g. `https://vercel.com//~/integrations`.
Create a new database [#create-a-new-database]
Once installed, you can navigate to the **Storage** tab and click **Create Database**.
Select **Prisma Postgres** and click **Continue**. Then select the **Region** for the database and a **Pricing Plan**, and click **Continue** again.
Finally, give the database a **Name** and click **Create**.
The database is now ready and can be connected to your Vercel projects.
Connect database to Vercel project [#connect-database-to-vercel-project]
In your Vercel project, you can now click the **Storage** tab, select the database you just created and then click **Connect**. This will automatically set the `DATABASE_URL` environment variable in that project and enable your application to access your newly created Prisma Postgres instance.
Viewing and editing data in Prisma Studio [#viewing-and-editing-data-in-prisma-studio]
To view and edit the data in your Prisma Postgres instance, you can use the local version of [Prisma Studio](/studio).
In the local version of your project where you have your `DATABASE_URL` set, run the following command to open Prisma Studio:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
Additional considerations when using with Prisma ORM [#additional-considerations-when-using-with-prisma-orm]
Ensure your project uses the correct environment variable [#ensure-your-project-uses-the-correct-environment-variable]
Ensure that the data source in your `prisma.config.ts` file is configured to use the `DATABASE_URL` environment variable:
```ts
import "dotenv/config";
import { defineConfig, env } from "@prisma/config";
export default defineConfig({
datasource: {
url: env("DATABASE_URL"),
},
schema: "./prisma/schema.prisma",
});
```
Generate Prisma Client in a postinstall script in package.json [#generate-prisma-client-in-a-postinstall-script-in-packagejson]
To ensure the generated Prisma Client library is available on your deployed Vercel project, you should add a `postinstall` script to the `scripts` section of your `package.json` file:
```js title="package.json"
{
// ...
"scripts": {
// ...
"postinstall": "prisma generate" // [!code ++]
}
//
}
```
# Viewing data (/docs/guides/postgres/viewing-data)
You can view and edit your data in Prisma Postgres using either [Prisma Studio](/studio) or 3rd party database editors.
Viewing and editing data in Prisma Studio [#viewing-and-editing-data-in-prisma-studio]
With Prisma Postgres, a hosted version of Prisma Studio is available in your project. In your project environment in the [Platform Console](https://console.prisma.io/), select the **Studio** tab in the left-hand navigation to view and edit your data:
You can also run Prisma Studio locally by running:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
This should start a live server in `http://localhost:5555` where you can visit and interact with your database.
Connecting to Prisma Postgres instance with 3rd party database editors [#connecting-to-prisma-postgres-instance-with-3rd-party-database-editors]
You can connect to your Prisma Postgres instance using third party database editors like pgAdmin, TablePlus, Postico etc using [`@prisma/ppg-tunnel` package](https://www.npmjs.com/package/@prisma/ppg-tunnel). See the example below to connect using TablePlus.
1. Create a TCP tunnel to access Prisma Postgres directly [#1-create-a-tcp-tunnel-to-access-prisma-postgres-directly]
If you already have a `.env` file in your current directory with `DATABASE_URL` set, the tunnel CLI will automatically pick it up, no need to manually export it. However, if you haven't set up a `.env` file, you'll need to set the `DATABASE_URL` environment variable explicitly.
In your terminal, to set the environment variable `DATABASE_URL` referring to your Prisma Postgres instance which you want to connect to (be sure to replace the `API_KEY` placeholder with the connection string value for your Prisma Postgres instance):
macOS
Linux
Windows
```bash
export DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=API_KEY"
```
```bash
export DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=API_KEY"
```
```cmd
set "DATABASE_URL=prisma+postgres://accelerate.prisma-data.net/?api_key=API_KEY"
```
If you explicitly set `DATABASE_URL` in your terminal, that value will take precedence over the one in your `.env` file.
Run the following command to connect to your Prisma Postgres instance via `@prisma/ppg-tunnel` package:
npm
pnpm
yarn
bun
```bash
npx @prisma/ppg-tunnel --host 127.0.0.1 --port 52604
```
```bash
pnpm dlx @prisma/ppg-tunnel --host 127.0.0.1 --port 52604
```
```bash
yarn dlx @prisma/ppg-tunnel --host 127.0.0.1 --port 52604
```
```bash
bunx --bun @prisma/ppg-tunnel --host 127.0.0.1 --port 52604
```
```text wrap
Prisma Postgres auth proxy listening on 127.0.0.1:52604 🚀
Your connection is authenticated using your Prisma Postgres API key.
...
==============================
hostname: 127.0.0.1
port: 52604
username:
password:
==============================
```
Copy the **`port`** from the output above, you will need it in the next step.
Keep this tunnel process running while you are using the database editor to maintain the connection.
2a. Connect to Prisma Postgres using TablePlus [#2a-connect-to-prisma-postgres-using-tableplus]
Based on the database editor you are using, you can connect to your Prisma Postgres instance using the details you obtained from the output of the `@prisma/ppg-tunnel` package. To add the connection string in TablePlus:
1. Open TablePlus and click on the **+** icon to add a new connection.
2. Select **PostgreSQL** as the database type.
3. Enter the following details:
* **Name**: Any name you want to give to your connection.
* **Host**: `127.0.0.1` in this case.
* **Port**: The **`port`** number you obtained from the output of the `@prisma/ppg-tunnel` package.
* **User**: This will be ignored due to the tunnel, you can provide any value here.
* **Password**: This will be ignored due to the tunnel, you can provide any value here.
4. Click on **Connect** to connect to your Prisma Postgres instance.
2b. Connect to Prisma Postgres using DataGrip [#2b-connect-to-prisma-postgres-using-datagrip]
Based on the database editor you are using, you can connect to your Prisma Postgres instance using the details you obtained from the output of the `@prisma/ppg-tunnel` package. To add the connection string in DataGrip:
1. Open DataGrip and click on the **+** icon and select "Datasource".
2. Select **PostgreSQL** as the database type.
3. Enter the following details:
* **Name**: Any name you want to give to your connection.
* **Host**: `127.0.0.1` in this case.
* **Port**: The **`port`** number you obtained from the output of the `@prisma/ppg-tunnel` package.
* **User**: This will be ignored due to the tunnel, you can keep this field empty.
* **Password**: This will be ignored due to the tunnel, you can keep this field empty.
* **URL**: In the URL append the following query parameter `?sslmode=disable` to the end of the URL.
4. Click on **Test Connection** to ensure that DataGrip can connect to your Prisma Postgres instance. Once successful, click **OK** to save the connection.
2c. Connect to Prisma Postgres using DBeaver [#2c-connect-to-prisma-postgres-using-dbeaver]
Based on the database editor you are using, you can connect to your Prisma Postgres instance using the details you obtained from the output of the `@prisma/ppg-tunnel` package. To add the connection string in DBeaver:
1. Open DBeaver and click on the **New Database Connection** button or **File** > **New** to add a new connection.
2. Select **PostgreSQL** as the database type.
3. Select **URL** option in Connect by section.
4. Enter the URL in this format:
* **URL**: Your URL should be in this format: `jdbc:postgresql://localhost:52604/postgres?sslmode=disable`. Here make sure that you enter the port number you obtained from the output of the `@prisma/ppg-tunnel` package. In this case, the port number is `52604`. There is no need to enter Username or Password as authentication is manged by Tunnel.
5. Click on **Test Connection** to ensure that DBeaver can connect to your Prisma Postgres instance. If successful, click **Finish**.
2d. Connect to Prisma Postgres using Postico [#2d-connect-to-prisma-postgres-using-postico]
Based on the database editor you are using, you can connect to your Prisma Postgres instance using the details you obtained from the output of the `@prisma/ppg-tunnel` package. To add the connection string in Postico:
1. Open Postico and click on the **New Server** button to add a new connection.
2. Enter the following details:
* **Name**: Any name you want to give to your connection.
* **Host**: `127.0.0.1` in this case.
* **Port**: The **`port`** number you obtained from the output of the `@prisma/ppg-tunnel` package.
* **User**: This will be ignored due to the tunnel, you can keep this field empty.
* **Password**: This will be ignored due to the tunnel, you can keep this field empty.
3. Check "Pre-Connect Shell Script" and enter:
```sh
cat <
# VS Code (/docs/guides/postgres/vscode)
Overview [#overview]
[Visual Studio Code](https://code.visualstudio.com) is one of the most popular code editors, offering speed, flexibility, and a vast extension ecosystem. With over 2.5M installs and 350K monthly active users, the [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) is a powerful tool when you're building applications with Prisma Postgres using VS Code as your editor.
Be sure to update the VS Code extension regularly in order to maintain functionality and take
advantage of new features in the latest release of Prisma ORM
Database management UI [#database-management-ui]
The Prisma VS Code extension includes a dedicated UI to manage Prisma Postgres instances (local and remote).
Workflows [#workflows]
The UI enables the following workflows:
* Authenticate with the [Prisma Console](https://console.prisma.io)
* View, create and delete Prisma Postgres instances (local & remote)
* "Push to cloud": Easily deploy a local Prisma Postgres instance
* View and edit data via an embedded Prisma Studio
* Visualize your database schema
Usage [#usage]
To manage Prisma Postgres instances via the UI in the Prisma VS Code extension:
1. Ensure you have the latest version of the [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) installed
2. Find the Prisma logo in the **Activity Bar**
3. Click the **Sign in to get started** button
4. Authenticate with the [Prisma Console](https://console.prisma.io) via the popup and select a target [workspace](/console/concepts#workspace)
Managing versions [#managing-versions]
The Prisma Extension can support both version 6 and version 7 of Prisma ORM. If you open a project
using either version, you can set the supported version by the command palette or the diagnostics
prompt.
Prisma Studio built-in [#prisma-studio-built-in]
Beyond managing your database instances, the Prisma VS Code extension embeds Prisma Studio directly in your editor making it easy to perform create, update, delete steps on your database from right inside of VS Code. Follow these [easy steps](/studio/integrations/vscode-integration) to get started.
Prisma MCP server [#prisma-mcp-server]
Prisma provides its own [Model Context Protocol](/ai/tools/mcp-server) (MCP) server that lets you manage Prisma Postgres databases, model database schemas and chat through migrations.
You can add the Prisma MCP server to VS Code using the one-click installation by clicking on the following link:
VS CODE
INSTALL PRISMA MCP SERVER
This will prompt you to open VS Code. Once opened, you'll be guided to install the Prisma MCP server directly into your VS Code configuration.
If your browser blocks the link, [you can set it up manually](https://code.visualstudio.com/docs/copilot/chat/mcp-servers#_add-an-mcp-server-to-your-workspace) by creating a `.vscode/mcp.json` file in your workspace and adding:
```json title=".vscode/mcp.json"
{
"servers": {
"Prisma-Local": {
"command": "npx",
"args": ["-y", "prisma", "mcp"]
},
"Prisma-Remote": {
"url": "https://mcp.prisma.io/mcp"
}
}
}
```
Learn more about the MCP server in our [MCP server documentation](/ai/tools/mcp-server).
Agent mode [#agent-mode]
VS Code includes an [agent mode](https://pris.ly/vs-code-docs) (powered by GitHub Copilot) that automatically performs code changes and executes Prisma CLI commands based on your prompts.
Capabilities [#capabilities]
The [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) enables support for VS Code agent mode.
VS Code agent mode can perform the following tasks:
* Check migration status (e.g. Flag unapplied migrations)
* Create and apply schema migrations automatically
* Sign in to the Prisma Data Platform
* Provision Prisma Postgres instances, letting you start coding right away
How to enable and use the VS Code agent [#how-to-enable-and-use-the-vs-code-agent]
The [latest version of the Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) fully supports agent mode. Since extensions update automatically, no manual action is required to enable it.
We recommend you to use the latest version of Prisma ORM.
To use the agent mode:
1. Open [GitHub Copilot Chat in VS Code and switch to **Agent** mode](https://code.visualstudio.com/docs/copilot/chat/chat-agent-mode#_use-agent-mode).
2. With GitHub Copilot Chat open and the Prisma extension updated, you can simply type a request such as: "Create a new database for me and add the connection string to the .env file".
3. The agent will request permission to make changes in your workspace.
4. It automatically handles login to your Prisma Data Platform account before proceeding.
5. Upon approval, the agent creates the new database and adds the connection string to your `.env` file.
6. You can also use agent mode to run migrations, generate the Prisma Client, and perform other tasks.
Currently, the agent mode uses your default [workspace](/console/concepts#workspace) in the Prisma Data Platform.
Querying Prisma docs from VS Code using GitHub Copilot [#querying-prisma-docs-from-vs-code-using-github-copilot]
Complementing the agent, the Prisma Copilot extension allows you to query Prisma documentation directly within VS Code.
You need to install the [Prisma for Copilot extension](https://github.com/apps/prisma-for-github-copilot) from the GitHub marketplace.
Then, [switch to **Ask** mode in GitHub Copilot Chat](https://code.visualstudio.com/docs/copilot/chat/chat-ask-mode) and type your question using the `@prisma-for-github-copilot` namespace.
For more details, refer to our [GitHub Copilot documentation](/ai/tools/github-copilot).
# Bun (/docs/guides/runtimes/bun)
Introduction [#introduction]
[Bun](https://bun.sh) is a fast JavaScript runtime that includes a bundler, test runner, and package manager. In this guide, you will set up a Bun project with Prisma ORM and a Prisma Postgres database. You will create a simple HTTP server and build a Bun executable for deployment.
Prerequisites [#prerequisites]
* [Bun](https://bun.sh/docs/installation) installed in your system
* A [Prisma Postgres database](/postgres) (created during setup)
* Basic knowledge of JavaScript/TypeScript
1. Setting up your Bun project [#1-setting-up-your-bun-project]
First, create a directory for your project and navigate to it:
```bash
mkdir bun-prisma
cd bun-prisma
```
Then, initialise a new Bun project:
```bash
bun init -y
```
This creates a basic Bun project that includes a `package.json` file and an `index.ts` file.
2. Installing and configuring Prisma [#2-installing-and-configuring-prisma]
2.1. Install dependencies [#21-install-dependencies]
Install the required Prisma packages and other dependencies:
```bash
bun add -d prisma @types/pg
bun add @prisma/client @prisma/adapter-pg pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
2.2. Initialize Prisma ORM with Prisma Postgres [#22-initialize-prisma-orm-with-prisma-postgres]
Initialize Prisma ORM with Prisma Postgres in your project:
```bash
bunx --bun prisma init --db
```
The `--bun` flag is required to ensure Prisma runs with the Bun runtime. Without it, Prisma falls back to Node.js due to the `#!/usr/bin/env node` shebang in the CLI.
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My Bun Project"
This command creates:
* A `prisma/` directory with your `schema.prisma` file
* A new Prisma Postgres database
* A `prisma.config.ts` file
* A `.env` file with your `DATABASE_URL`
2.3. Configure environment variables for direct connection [#23-configure-environment-variables-for-direct-connection]
We're going to use a direct connection string for connecting to Prisma Postgres. To get it, follow [Connecting to your database](/postgres/database/connecting-to-your-database):
1. Navigate to your recently created Prisma Postgres project dashboard (e.g. "My Bun Project")
2. Click the **Connection Strings** tab in the project's sidebar
3. Click the **Create connection string** button
4. Provide a name for the connection string and click **Create**
5. Copy the connection string starting with `postgres://`
Update your `.env` file to replace the `DATABASE_URL` with the new connection string:
```bash title=".env"
DATABASE_URL="your_database_url_here" # [!code --]
DATABASE_URL="your_direct_connection_string_here" # [!code ++]
```
2.4. Update your Prisma schema [#24-update-your-prisma-schema]
Open `prisma/schema.prisma` and update it to include your data model:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
} // [!code ++]
```
3. Generate Prisma Client and run migrations [#3-generate-prisma-client-and-run-migrations]
Generate the Prisma client and apply your schema to the database:
```bash
bunx --bun prisma migrate dev --name init
bunx --bun prisma generate
```
This command:
* Creates the database tables based on your schema
* Generates the Prisma client in the `generated/prisma` directory
4. Setting up database configuration and creating a seed script [#4-setting-up-database-configuration-and-creating-a-seed-script]
4.1. Create a database utility file [#41-create-a-database-utility-file]
Create a `db.ts` file in your project root to configure `PrismaClient`:
```typescript title="db.ts"
import { PrismaClient } from "./generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
export const prisma = new PrismaClient({
adapter,
});
```
4.2. Create a seed script [#42-create-a-seed-script]
Create a seed script in the `prisma` folder to populate your database with sample data:
```typescript title="prisma/seed.ts"
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,
});
async function main() {
// Create multiple users
await prisma.user.createMany({
data: [
{ email: "alice@example.com", name: "Alice" },
{ email: "bob@example.com", name: "Bob" },
{ email: "charlie@example.com", name: "Charlie" },
{ email: "diana@example.com", name: "Diana" },
{ email: "eve@example.com", name: "Eve" },
{ email: "frank@example.com", name: "Frank" },
{ email: "grace@example.com", name: "Grace" },
{ email: "henry@example.com", name: "Henry" },
{ email: "isabella@example.com", name: "Isabella" },
{ email: "jack@example.com", name: "Jack" },
],
skipDuplicates: true, // prevents errors if you run the seed multiple times
});
console.log("Seed data inserted!");
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
3.3. Add the seed script to Prisma Config [#33-add-the-seed-script-to-prisma-config]
Add the following content to the file:
```typescript title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: `bun run prisma/seed.ts`, // [!code ++]
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Unlike Node.js, Bun automatically loads `.env` files, so the `import 'dotenv/config'` line is not needed. If you see this import in your generated `prisma.config.ts`, you can safely remove it.
Run the seed script to populate your database:
```bash
bunx --bun prisma db seed
```
5. Creating your Bun server [#5-creating-your-bun-server]
Replace the `index.ts` file contents with the following code to build a simple HTTP server that uses Prisma ORM to fetch and display users:
```typescript title="index.ts"
import { prisma } from "./db";
const server = Bun.serve({
port: 3000,
async fetch(req) {
const { pathname } = new URL(req.url);
// Skip favicon route
if (pathname === "/favicon.ico") {
return new Response(null, { status: 204 }); // or serve an icon if you have one
}
// Return all users
const users = await prisma.user.findMany();
// Count all users
const count = await prisma.user.count();
// Format the response with JSON
return new Response(
JSON.stringify({
users: users,
totalUsers: count,
}),
{ headers: { "Content-Type": "application/json" } },
);
},
});
console.log(`Listening on http://localhost:${server.port}`);
```
6. Running your application [#6-running-your-application]
Start your Bun server:
```bash
bun run index.ts
```
You should see `Listening on http://localhost:3000` in the console. When you visit `http://localhost:3000` in your browser, you'll see a JSON response with all the users in your database and the total count.
7. Building and running a Bun executable [#7-building-and-running-a-bun-executable]
Bun can compile your [TypeScript application into a single executable file](https://bun.com/docs/bundler/executables), which is useful for deployment and distribution.
7.1. Build the executable [#71-build-the-executable]
Build your application into an executable:
```bash
bun build --compile index.ts
```
This creates an executable file named `index` (or `index.exe` on Windows) in your project directory.
7.2. Run the executable [#72-run-the-executable]
Run the compiled executable:
```bash
./index
```
You should see the same `Listening on http://localhost:3000` message, and your application will work exactly the same as before. The executable includes all dependencies and can be deployed to any compatible system without requiring Bun or Node.js to be installed.
Bun executables are useful for:
* **Deployment**: Ship a single file instead of managing dependencies
* **Distribution**: Share your application without requiring users to install Bun
* **Performance**: Faster startup times compared to running TypeScript files
* **Security**: Your source code is compiled and not easily readable
Next steps [#next-steps]
You can explore [this example](https://pris.ly/bun_ppg_example) to see a sample application built with Bun and Prisma.
Now that you have a Bun application connected to a Prisma Postgres database, you can continue by:
* Extending your Prisma schema with additional models and relationships
* Implementing authentication and authorization
* Adding input validation and error handling
* Exploring Bun's built-in testing tools
* Deploying your executable to production servers
More info [#more-info]
* [Bun Documentation](https://bun.sh/docs)
* [Prisma Config File](/orm/reference/prisma-config-reference)
* [Prisma Postgres](/postgres)
# Deno (/docs/guides/runtimes/deno)
Introduction [#introduction]
[Deno](https://deno.com) is a secure JavaScript and TypeScript runtime built on V8 with built-in TypeScript support, a permissions system, and web-standard APIs. In this guide, you will set up a Deno project with Prisma ORM and a Prisma Postgres database. You will create a simple HTTP server that reads from the database and returns the results.
Prerequisites [#prerequisites]
* [Deno](https://docs.deno.com/runtime/#install-deno) v2.0 or later installed on your system
* A [Prisma Postgres database](/postgres) (created during setup)
* Basic knowledge of JavaScript/TypeScript
* [Deno extension for VS Code](https://docs.deno.com/runtime/reference/vscode/) (recommended)
1. Setting up your Deno project [#1-setting-up-your-deno-project]
First, create a directory for your project and navigate to it:
```bash
mkdir deno-prisma
cd deno-prisma
```
Then, initialize a new Deno project:
```bash
deno init
```
This creates a basic Deno project with a `deno.json` configuration file and a `main.ts` file.
1.1. Configure Deno for Prisma [#11-configure-deno-for-prisma]
Update the `deno.json` file with the following configuration to set up Node.js compatibility, import maps, and Prisma-related task scripts:
```json title="deno.json"
{
"nodeModulesDir": "auto",
"compilerOptions": {
"lib": ["deno.window"],
"types": ["node"]
},
"imports": {
"@prisma/adapter-pg": "npm:@prisma/adapter-pg@^7.0.0",
"@prisma/client": "npm:@prisma/client@^7.0.0",
"prisma": "npm:prisma@^7.0.0"
},
"tasks": {
"dev": "deno run -A --env=.env --watch main.ts",
"db:generate": "deno run -A --env=.env npm:prisma generate",
"db:push": "deno run -A --env=.env npm:prisma db push",
"db:migrate": "deno run -A --env=.env npm:prisma migrate dev",
"db:seed": "deno run -A --env=.env npm:prisma db seed"
}
}
```
The `nodeModulesDir: "auto"` setting allows Deno to automatically manage a `node_modules` directory, which is needed for Prisma's generated client. The import map entries let you use bare specifiers like `@prisma/client` in your code.
2. Installing and configuring Prisma [#2-installing-and-configuring-prisma]
2.1. Initialize Prisma ORM with Prisma Postgres [#21-initialize-prisma-orm-with-prisma-postgres]
Initialize Prisma ORM with Prisma Postgres in your project:
```bash
deno run -A npm:prisma init --db
```
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My Deno Project".
This command creates:
* A `prisma/` directory with your `schema.prisma` file
* A new Prisma Postgres database
* A `prisma.config.ts` file
* A `.env` file with your `DATABASE_URL`
2.2. Update the Prisma config file [#22-update-the-prisma-config-file]
Open the generated `prisma.config.ts` file. Since Deno loads environment variables using the `--env=.env` flag (configured in `deno.json` tasks), you can remove the `dotenv/config` import if it was generated:
```typescript title="prisma.config.ts"
import "dotenv/config"; // [!code --]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
2.3. Configure environment variables for direct connection [#23-configure-environment-variables-for-direct-connection]
We're going to use a direct connection string for connecting to Prisma Postgres. To get it, follow [Connecting to your database](/postgres/database/connecting-to-your-database):
1. Navigate to your recently created Prisma Postgres project dashboard (e.g. "My Deno Project")
2. Click the **Connection Strings** tab in the project's sidebar
3. Click the **Create connection string** button
4. Provide a name for the connection string and click **Create**
5. Copy the connection string starting with `postgres://`
Update your `.env` file to replace the `DATABASE_URL` with the new connection string:
```bash title=".env"
DATABASE_URL="your_database_url_here" # [!code --]
DATABASE_URL="your_direct_connection_string_here" # [!code ++]
```
2.4. Update your Prisma schema [#24-update-your-prisma-schema]
Open `prisma/schema.prisma` and update it to include the Deno runtime and your data model:
```prisma title="prisma/schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/prisma"
runtime = "deno" // [!code ++]
}
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
email String @unique // [!code ++]
name String? // [!code ++]
} // [!code ++]
```
The `runtime = "deno"` setting in the generator block is required for Prisma Client to work correctly with the Deno runtime.
3. Generate Prisma Client and run migrations [#3-generate-prisma-client-and-run-migrations]
Generate the Prisma Client and apply your schema to the database:
```bash
deno task db:migrate --name init
deno task db:generate
```
This command:
* Creates the database tables based on your schema
* Generates the Prisma Client in the `generated/prisma` directory
4. Setting up database configuration and creating a seed script [#4-setting-up-database-configuration-and-creating-a-seed-script]
4.1. Create a database utility file [#41-create-a-database-utility-file]
Create a `db.ts` file in your project root to configure `PrismaClient`:
```typescript title="db.ts"
import { PrismaClient } from "./generated/prisma/client.ts";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: Deno.env.get("DATABASE_URL")!,
});
export const prisma = new PrismaClient({
adapter,
});
```
4.2. Create a seed script [#42-create-a-seed-script]
Create a seed script in the `prisma` folder to populate your database with sample data:
```typescript title="prisma/seed.ts"
import { PrismaClient } from "../generated/prisma/client.ts";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: Deno.env.get("DATABASE_URL")!,
});
const prisma = new PrismaClient({
adapter,
});
async function main() {
// Create multiple users
await prisma.user.createMany({
data: [
{ email: "alice@example.com", name: "Alice" },
{ email: "bob@example.com", name: "Bob" },
{ email: "charlie@example.com", name: "Charlie" },
{ email: "diana@example.com", name: "Diana" },
{ email: "eve@example.com", name: "Eve" },
{ email: "frank@example.com", name: "Frank" },
{ email: "grace@example.com", name: "Grace" },
{ email: "henry@example.com", name: "Henry" },
{ email: "isabella@example.com", name: "Isabella" },
{ email: "jack@example.com", name: "Jack" },
],
skipDuplicates: true, // prevents errors if you run the seed multiple times
});
console.log("Seed data inserted!");
}
main()
.catch((e) => {
console.error(e);
Deno.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
```
4.3. Add the seed script to Prisma Config [#43-add-the-seed-script-to-prisma-config]
Update the `prisma.config.ts` file to include the seed command:
```typescript title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "deno run -A --env=.env ./prisma/seed.ts", // [!code ++]
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Run the seed script to populate your database:
```bash
deno task db:seed
```
5. Creating your Deno server [#5-creating-your-deno-server]
Replace the `main.ts` file contents with the following code to build a simple HTTP server that uses Prisma ORM to fetch and display users:
```typescript title="main.ts"
import { prisma } from "./db.ts";
async function handler(req: Request): Promise {
const { pathname } = new URL(req.url);
// Skip favicon route
if (pathname === "/favicon.ico") {
return new Response(null, { status: 204 });
}
// Return all users
const users = await prisma.user.findMany();
// Count all users
const count = await prisma.user.count();
// Format the response with JSON
return new Response(
JSON.stringify({
users: users,
totalUsers: count,
}),
{ headers: { "Content-Type": "application/json" } },
);
}
Deno.serve({ port: 8000 }, handler);
```
6. Running your application [#6-running-your-application]
Start your Deno server:
```bash
deno task dev
```
You should see the server running on `http://localhost:8000` in the console. When you visit `http://localhost:8000` in your browser, you'll see a JSON response with all the users in your database and the total count.
Next steps [#next-steps]
Now that you have a Deno application connected to a Prisma Postgres database, you can continue by:
* Extending your Prisma schema with additional models and relationships
* Implementing authentication and authorization
* Adding input validation with Zod
* Exploring Deno's built-in testing tools
* Deploying your application to [Deno Deploy](/guides/integrations/deno)
More info [#more-info]
* [Deno Documentation](https://docs.deno.com)
* [Prisma Config File](/orm/reference/prisma-config-reference)
* [Prisma Postgres](/postgres)
# Drizzle (/docs/guides/switch-to-prisma-orm/from-drizzle)
Introduction [#introduction]
This guide shows you how to migrate your application from Drizzle to Prisma ORM. We'll use a sample project based off of the [Drizzle Next.js example](https://orm.drizzle.team/docs/tutorials/drizzle-nextjs-neon) to demonstrate the migration steps. You can find the example used for this guide on [GitHub](https://github.com/prisma/migrate-from-drizzle-to-prisma).
You can learn how Prisma ORM compares to Drizzle on the [Prisma ORM vs Drizzle](/orm/more/comparisons/prisma-and-drizzle) page.
Prerequisites [#prerequisites]
Before starting this guide, make sure you have:
* A Drizzle project you want to migrate
* Node.js installed (version 16 or higher)
* PostgreSQL or another supported database
* Basic familiarity with Drizzle and Next.js
this migration guide uses Neon PostgreSQL as the example database, but it equally applies to any other relational database that are [supported by Prisma ORM](/orm/reference/supported-databases).
You can learn how Prisma ORM compares to Drizzle on the [Prisma ORM vs Drizzle](/orm/more/comparisons/prisma-and-drizzle) page.
Overview of the migration process [#overview-of-the-migration-process]
Note that the steps for migrating from Drizzle to Prisma ORM are always the same, no matter what kind of application or API layer you're building:
1. Install the Prisma CLI
2. Introspect your database
3. Create a baseline migration
4. Install Prisma Client
5. Gradually replace your Drizzle queries with Prisma Client
These steps apply, no matter if you're building a REST API (e.g. with Express, koa or NestJS), a GraphQL API (e.g. with Apollo Server, TypeGraphQL or Nexus) or any other kind of application that uses Drizzle for database access.
Prisma ORM lends itself really well for **incremental adoption**. This means, you don't have to migrate your entire project from Drizzle to Prisma ORM at once, but rather you can *step-by-step* move your database queries from Drizzle to Prisma ORM.
Step 1. Install the Prisma CLI [#step-1-install-the-prisma-cli]
The first step to adopt Prisma ORM is to [install the Prisma CLI](/orm/reference/prisma-cli-reference) in your project:
npm
pnpm
yarn
bun
```bash
npm install prisma @types/pg --save-dev
npm install @prisma/client @prisma/adapter-pg pg
```
```bash
pnpm add prisma @types/pg --save-dev
pnpm add @prisma/client @prisma/adapter-pg pg
```
```bash
yarn add prisma @types/pg --dev
yarn add @prisma/client @prisma/adapter-pg pg
```
```bash
bun add prisma @types/pg --dev
bun add @prisma/client @prisma/adapter-pg pg
```
If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).
Step 2. Introspect your database [#step-2-introspect-your-database]
2.1. Set up Prisma ORM [#21-set-up-prisma-orm]
Before you can introspect your database, you need to set up your [Prisma schema](/orm/prisma-schema/overview) and connect Prisma to your database. Run the following command in the root of your project to create a basic Prisma schema file:
npm
pnpm
yarn
bun
```bash
npx prisma init --output ../generated/prisma
```
```bash
pnpm dlx prisma init --output ../generated/prisma
```
```bash
yarn dlx prisma init --output ../generated/prisma
```
```bash
bunx --bun prisma init --output ../generated/prisma
```
This command created a new directory called `prisma` with the following files for you:
* `schema.prisma`: Your Prisma schema that specifies your database connection and models
* `.env`: A [`dotenv`](https://github.com/motdotla/dotenv) to configure your database connection URL as an environment variable
You may already have a `.env` file. If so, the `prisma init` command will append lines to it rather than creating a new file.
The Prisma schema currently looks as follows:
```prisma title="prisma/schema.prisma" showLineNumbers
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
datasource db {
provider = "postgresql"
}
generator client {
provider = "prisma-client"
output = "./generated/prisma"
}
```
If you're using VS Code, be sure to install the [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) for syntax highlighting, formatting, auto-completion and a lot more cool features.
2.2. Connect your database [#22-connect-your-database]
If you're not using PostgreSQL, you need to adjust the `provider` field on the `datasource` block to the database you currently use:
PostgreSQL
MySQL
Microsoft SQL Server
SQLite
```prisma title="schema.prisma" showLineNumbers
datasource db {
provider = "postgresql"
}
```
```prisma title="schema.prisma" showLineNumbers
datasource db {
provider = "mysql"
}
```
```prisma title="schema.prisma" showLineNumbers
datasource db {
provider = "sqlserver"
}
```
```prisma title="schema.prisma" showLineNumbers
datasource db {
provider = "sqlite"
}
```
Once that's done, you can configure your [database connection URL](/orm/reference/connection-urls) in the `.env` file. Drizzle and Prisma ORM use the same format for connection URLs, so your existing connection URL should work fine.
2.3. Configure Prisma [#23-configure-prisma]
Create a `prisma.config.ts` file in the root of your project with the following content:
```typescript title="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"),
},
});
```
You'll need to install the `dotenv` package to load environment variables. If you haven't already, install it using your package manager:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
2.4. Introspect your database using Prisma ORM [#24-introspect-your-database-using-prisma-orm]
With your connection URL in place, you can [introspect](/orm/prisma-schema/introspection) your database to generate your Prisma models:
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
If you're using the [sample project](https://github.com/prisma/migrate-from-drizzle-to-prisma) the following model would be created:
```prisma title="prisma/schema.prisma" showLineNumbers
model todo {
id Int @id
text String
done Boolean @default(false)
}
```
The generated Prisma model represents a database table. Prisma models are the foundation for your programmatic Prisma Client API which allows you to send queries to your database.
2.5. Create a baseline migration [#25-create-a-baseline-migration]
To continue using Prisma Migrate to evolve your database schema, you will need to [baseline your database](/orm/prisma-migrate/getting-started).
First, create a `migrations` directory and add a directory inside with your preferred name for the migration. In this example, we will use `0_init` as the migration name:
```bash
mkdir -p prisma/migrations/0_init
```
Next, generate the migration file with `prisma migrate diff`. Use the following arguments:
* `--from-empty`: assumes the data model you're migrating from is empty
* `--to-schema`: the current database state using the URL in the `datasource` block
* `--script`: output a SQL script
npm
pnpm
yarn
bun
```bash
npx prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
```
```bash
pnpm dlx prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
```
```bash
yarn dlx prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
```
```bash
bunx --bun prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
```
Review the generated migration to ensure everything is correct.
Next, mark the migration as applied using `prisma migrate resolve` with the `--applied` argument.
npm
pnpm
yarn
bun
```bash
npx prisma migrate resolve --applied 0_init
```
```bash
pnpm dlx prisma migrate resolve --applied 0_init
```
```bash
yarn dlx prisma migrate resolve --applied 0_init
```
```bash
bunx --bun prisma migrate resolve --applied 0_init
```
The command will mark `0_init` as applied by adding it to the `_prisma_migrations` table.
You now have a baseline for your current database schema. To make further changes to your database schema, you can update your Prisma schema and use `prisma migrate dev` to apply the changes to your database.
2.6. Adjust the Prisma schema (optional) [#26-adjust-the-prisma-schema-optional]
Models that are generated via introspection currently *exactly* map to your database tables. In this section, you'll learn how you can adjust the naming of the Prisma models to adhere to [Prisma ORM's naming conventions](/orm/reference/prisma-schema-reference#naming-conventions).
All of these adjustment are entirely optional and you are free to skip to the next step already if you don't want to adjust anything for now. You can go back and make the adjustments at any later point.
As opposed to the current camelCase notation of Drizzle models, Prisma ORM's naming conventions are:
* PascalCase for model names
* camelCase for field names
You can adjust the naming by *mapping* the Prisma model and field names to the existing table and column names in the underlying database using `@@map` and `@map`.
Here's an example on how you could modify the model above:
```prisma title="prisma/schema.prisma" showLineNumbers
model Todo {
id Int @id
text String
done Boolean @default(false)
@@map("todo")
}
```
Step 3. Generate Prisma Client [#step-3-generate-prisma-client]
Now that you have installed Prisma Client in Step 1, you need to run `generate` in order to have your schema reflected in TypeScript types and autocomplete.
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
Step 4. Replace your Drizzle queries with Prisma Client [#step-4-replace-your-drizzle-queries-with-prisma-client]
In this section, we'll show a few sample queries that are being migrated from Drizzle to Prisma Client based on the example routes from the sample REST API project. For a comprehensive overview of how the Prisma Client API differs from Drizzle, check out the [comparison page](/orm/more/comparisons/prisma-and-drizzle#).
First, to set up the `PrismaClient` instance that you'll use to send database queries from the various route handlers. Create a new file named `prisma.ts` in the `db` directory:
```bash copy
touch db/prisma.ts
```
Now, instantiate `PrismaClient` and export it from the file so you can use it in your route handlers later:
```ts copy title="db/prisma.ts" showLineNumbers
import { PrismaClient } from "../generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
import "dotenv/config";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
export const prisma = new PrismaClient({
adapter,
});
```
4.1. Replacing getData queries [#41-replacing-getdata-queries]
The fullstack Next.js app has several `actions` including `getData`.
The `getData` action is currently implemented as follows:
```ts title="actions/todoActions.ts" showLineNumbers
import db from "@/db/drizzle";
import { todo } from "@/db/schema";
export const getData = async () => {
const data = await db.select().from(todo);
return data;
};
```
Here is the same action implemented using Prisma Client:
```ts title="src/controllers/FeedAction.ts" showLineNumbers
import { prisma } from "@/db/prisma";
export const getData = async () => {
const data = await prisma.todo.findMany();
return data;
};
```
4.2. Replacing queries in POST requests [#42-replacing-queries-in-post-requests]
The [sample project](https://github.com/prisma/migrate-from-drizzle-to-prisma) has four actions that are utilized during `POST` requests:
* `addTodo`: Creates a new `Todo` record
* `deleteTodo`: Deletes an existing `Todo` record
* `toggleTodo`: Toggles the boolean `done` field on an existing `Todo` record
* `editTodo`: Edits the `text` field on an existing `Todo` record
addTodo [#addtodo]
The `addTodo` action is currently implemented as follows:
```ts title="actions/todoActions.ts" showLineNumbers
import { revalidatePath } from "next/cache";
import db from "@/db/drizzle";
import { todo } from "@/db/schema";
export const addTodo = async (id: number, text: string) => {
await db.insert(todo).values({
id: id,
text: text,
});
revalidatePath("/");
};
```
Here is the same action implemented using Prisma Client:
```ts title="actions/todoActions.ts" showLineNumbers
import { revalidatePath } from "next/cache";
import { prisma } from "@/db/prisma";
export const addTodo = async (id: number, text: string) => {
await prisma.todo.create({
data: { id, text },
});
revalidatePath("/");
};
```
deleteTodo [#deletetodo]
The `deleteTodo` action is currently implemented as follows:
```ts title="actions/todoActions.ts" showLineNumbers
import { eq } from "drizzle-orm";
import { revalidatePath } from "next/cache";
import db from "@/db/drizzle";
import { todo } from "@/db/schema";
export const deleteTodo = async (id: number) => {
await db.delete(todo).where(eq(todo.id, id));
revalidatePath("/");
};
```
Here is the same action implemented using Prisma Client:
```ts title="actions/todoActions.ts" showLineNumbers
import { revalidatePath } from "next/cache";
import { prisma } from "@/db/prisma";
export const deleteTodo = async (id: number) => {
await prisma.todo.delete({ where: { id } });
revalidatePath("/");
};
```
toggleTodo [#toggletodo]
The `ToggleTodo` action is currently implemented as follows:
```ts title="actions/todoActions.ts" showLineNumbers
import { eq, not } from "drizzle-orm";
import { revalidatePath } from "next/cache";
import db from "@/db/drizzle";
import { todo } from "@/db/schema";
export const toggleTodo = async (id: number) => {
await db
.update(todo)
.set({
done: not(todo.done),
})
.where(eq(todo.id, id));
revalidatePath("/");
};
```
Here is the same action implemented using Prisma Client:
```ts title="actions/todoActions.ts" showLineNumbers
import { revalidatePath } from "next/cache";
import { prisma } from "@/db/prisma";
export const toggleTodo = async (id: number) => {
const todo = await prisma.todo.findUnique({ where: { id } });
if (todo) {
await prisma.todo.update({
where: { id: todo.id },
data: { done: !todo.done },
});
revalidatePath("/");
}
};
```
Note that Prisma ORM does not have the ability to edit a boolean field "in place", so the record must be fetched before hand.
editTodo [#edittodo]
The `editTodo` action is currently implemented as follows:
```ts title="actions/todoActions.ts" showLineNumbers
import { eq } from "drizzle-orm";
import { revalidatePath } from "next/cache";
import db from "@/db/drizzle";
import { todo } from "@/db/schema";
export const editTodo = async (id: number, text: string) => {
await db
.update(todo)
.set({
text: text,
})
.where(eq(todo.id, id));
revalidatePath("/");
};
```
Here is the same action implemented using Prisma Client:
```ts title="actions/todoActions.ts" showLineNumbers
import { revalidatePath } from "next/cache";
import { prisma } from "@/db/prisma";
export const editTodo = async (id: number, text: string) => {
await prisma.todo.update({
where: { id },
data: { text },
});
revalidatePath("/");
};
```
More [#more]
Implicit many-to-many relations [#implicit-many-to-many-relations]
Unlike Drizzle, Prisma ORM allows you to [model many-to-many relations *implicitly*](/orm/prisma-schema/data-model/relations/many-to-many-relations#implicit-many-to-many-relations). That is, a many-to-many relation where you do not have to manage the [relation table](/orm/prisma-schema/data-model/relations/many-to-many-relations#relation-table-conventions) (also sometimes called JOIN table) *explicitly* in your schema. Here is an example comparing Drizzle with Prisma ORM:
```ts title="schema.ts"
import { boolean, integer, pgTable, serial, text } from "drizzle-orm/pg-core";
export const posts = pgTable("post", {
id: serial("serial").primaryKey(),
title: text("title").notNull(),
content: text("content"),
published: boolean("published").default(false).notNull(),
});
export const categories = pgTable("category", {
id: serial("serial").primaryKey(),
name: text("name").notNull(),
});
export const postsToCategories = pgTable("posts_to_categories", {
postId: integer("post_id")
.notNull()
.references(() => users.id),
categoryId: integer("category_id")
.notNull()
.references(() => chatGroups.id),
});
```
This schema is equivalent to the following Prisma schema:
```prisma title="schema.prisma"
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
postsToCategories PostToCategories[]
@@map("post")
}
model Category {
id Int @id @default(autoincrement())
name String
postsToCategories PostToCategories[]
@@map("category")
}
model PostToCategories {
postId Int
categoryId Int
category Category @relation(fields: [categoryId], references: [id])
post Post @relation(fields: [postId], references: [id])
@@id([postId, categoryId])
@@index([postId])
@@index([categoryId])
@@map("posts_to_categories")
}
```
In this Prisma schema, the many-to-many relation is modeled *explicitly* via the relation table `PostToCategories`.
By instead adhering to the conventions for Prisma ORM relation tables, the relation could look as follows:
```prisma title="schema.prisma" showLineNumbers
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
categories Category[]
}
model Category {
id Int @id @default(autoincrement())
name String
posts Post[]
}
```
This would also result in a more ergonomic and less verbose Prisma Client API to modify the records in this relation, because you have a direct path from `Post` to `Category` (and the other way around) instead of needing to traverse the `PostToCategories` model first.
If your database provider requires tables to have primary keys then you have to use explicit syntax, and manually create the join model with a primary key. This is because relation tables (JOIN tables) created by Prisma ORM (expressed via `@relation`) for many-to-many relations using implicit syntax do not have primary keys.
# Mongoose (/docs/guides/switch-to-prisma-orm/from-mongoose)
Introduction [#introduction]
This guide shows you how to migrate your application from Mongoose to Prisma ORM. We'll use a [sample project](https://github.com/prisma/migrate-from-mongoose-to-prisma) to demonstrate the migration steps.
MongoDB support for Prisma ORM v7
**MongoDB support for Prisma ORM v7 is coming in the near future.** In the meantime, please use **Prisma ORM v6.19** (the latest v6 release) when working with MongoDB.
This guide uses Prisma ORM v6.19 to ensure full compatibility with MongoDB.
You can learn how Prisma ORM compares to Mongoose on the [Prisma ORM vs Mongoose](/orm/more/comparisons/prisma-and-mongoose) page.
This guide currently assumes you are using **Prisma ORM v6**. Support for Prisma ORM v7 with MongoDB is in progress.
Prerequisites [#prerequisites]
Before starting this guide, make sure you have:
* A Mongoose project you want to migrate
* Node.js installed [with the supported version](/guides/upgrade-prisma-orm/v6#minimum-supported-nodejs-versions)
* MongoDB database (4.2+ with replica set deployment recommended)
* Basic familiarity with Mongoose and Express.js
1. Prepare for migration [#1-prepare-for-migration]
1.1. Understand the migration process [#11-understand-the-migration-process]
The steps for migrating from Mongoose to Prisma ORM are always the same, no matter what kind of application or API layer you're building:
1. Install the Prisma CLI
2. Introspect your database
3. Install and generate Prisma Client
4. Gradually replace your Mongoose queries with Prisma Client
These steps apply whether you're building a REST API (e.g., with Express, Koa, or NestJS), a GraphQL API (e.g., with Apollo Server, TypeGraphQL, or Nexus), or any other kind of application that uses Mongoose for database access.
1.2. Install Prisma dependencies [#12-install-prisma-dependencies]
First, install the required Prisma packages:
npm
pnpm
yarn
bun
```bash
npm install prisma@6.19 @types/node --save-dev
```
```bash
pnpm add prisma@6.19 @types/node --save-dev
```
```bash
yarn add prisma@6.19 @types/node --dev
```
```bash
bun add prisma@6.19 @types/node --dev
```
npm
pnpm
yarn
bun
```bash
npm install @prisma/client@6.19 dotenv
```
```bash
pnpm add @prisma/client@6.19 dotenv
```
```bash
yarn add @prisma/client@6.19 dotenv
```
```bash
bun add @prisma/client@6.19 dotenv
```
Why Prisma v6.19?
This is the latest stable version of Prisma ORM v6 that fully supports MongoDB. MongoDB support for Prisma ORM v7 is coming soon.
You can also install `prisma@6` and `@prisma/client@6` to automatically get the latest v6 release.
1.3. Set up Prisma configuration [#13-set-up-prisma-configuration]
Create a new Prisma schema file:
npm
pnpm
yarn
bun
```bash
npx prisma init --datasource-provider mongodb --output ../generated/prisma
```
```bash
pnpm dlx prisma init --datasource-provider mongodb --output ../generated/prisma
```
```bash
yarn dlx prisma init --datasource-provider mongodb --output ../generated/prisma
```
```bash
bunx --bun prisma init --datasource-provider mongodb --output ../generated/prisma
```
This command creates:
* A new directory called `prisma` that contains a `schema.prisma` file; your Prisma schema specifies your database connection and models
* `.env`: A [`dotenv`](https://github.com/motdotla/dotenv) file at the root of your project (if it doesn't already exist), used to configure your database connection URL as an environment variable
* `prisma.config.ts`: Configuration file for Prisma
The Prisma schema uses the ESM-first `prisma-client` generator:
```prisma title="prisma/schema.prisma" showLineNumbers
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
```
For an optimal development experience when working with Prisma ORM, refer to [editor setup](/orm/more/dev-environment/editor-setup) to learn about syntax highlighting, formatting, auto-completion, and many more cool features.
Update the `DATABASE_URL` in the `.env` file with your MongoDB connection string:
```text
DATABASE_URL="mongodb+srv://username:password@cluster.mongodb.net/mydb"
```
Replace `username`, `password`, `cluster`, and `mydb` with your actual MongoDB credentials and database name. You can get your connection string from [MongoDB Atlas](https://www.mongodb.com/cloud/atlas) or your MongoDB deployment.
1.4. Configure Prisma [#14-configure-prisma]
The generated `prisma.config.ts` file should look like this:
```typescript title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
engine: "classic",
datasource: {
url: env("DATABASE_URL"),
},
});
```
Add `dotenv` to load environment variables from your `.env` file:
```typescript title="prisma.config.ts"
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
engine: "classic",
datasource: {
url: env("DATABASE_URL"),
},
});
```
2. Migrate the database schema [#2-migrate-the-database-schema]
2.1. Introspect your database [#21-introspect-your-database]
MongoDB is a *schemaless* database. To incrementally adopt Prisma ORM in your project, ensure your database is populated with sample data. Prisma ORM introspects a MongoDB schema by sampling data stored and inferring the schema from the data in the database.
Run Prisma's introspection to create the Prisma schema from your existing database:
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
This will create a `schema.prisma` file with your database schema.
```prisma title="prisma/schema.prisma" showLineNumbers
type UsersProfile {
bio String
}
model categories {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
name String
}
model posts {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
author String @db.ObjectId
categories String[] @db.ObjectId
content String
published Boolean
title String
}
model users {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
email String @unique(map: "email_1")
name String
profile UsersProfile?
}
```
2.2. Update relations [#22-update-relations]
MongoDB doesn't support relations between different collections. However, you can create references between documents using the [`ObjectId`](/orm/core-concepts/supported-databases/mongodb#using-objectid) field type or from one document to many using an array of `ObjectIds` in the collection. The reference will store id(s) of the related document(s). You can use the `populate()` method that Mongoose provides to populate the reference with the data of the related document.
Update the 1-n relationship between `posts` \<-> `users` as follows:
* Rename the existing `author` reference in the `posts` model to `authorId` and add the `@map("author")` attribute
* Add the `author` relation field in the `posts` model and it's `@relation` attribute specifying the `fields` and `references`
* Add the `posts` relation in the `users` model
Your schema should now look like this:
```prisma title="schema.prisma"
type UsersProfile {
bio String
}
model categories {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
name String
}
model posts {
id String @id @default(auto()) @map("_id") @db.ObjectId
title String
content String
published Boolean
v Int @map("__v")
author String @db.ObjectId // [!code --]
author users @relation(fields: [authorId], references: [id]) // [!code ++]
authorId String @map("author") @db.ObjectId // [!code ++]
categories String[] @db.ObjectId
}
model users {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
email String @unique(map: "email_1")
name String
profile UsersProfile?
posts posts[] // [!code ++]
}
```
Then, update the m-n between `posts` \<-> `categories` references as follows:
* Rename the `categories` field to `categoryIds` and map it using `@map("categories")` in the `posts` model
* Add a new `categories` relation field in the `posts` model
* Add the `postIds` scalar list field in the `categories` model
* Add the `posts` relation in the `categories` model
* Add a [relation scalar](/orm/prisma-schema/data-model/relations#annotated-relation-fields) on both models
* Add the `@relation` attribute specifying the `fields` and `references` arguments on both sides
Your schema should now look like this:
```prisma title="schema.prisma"
type UsersProfile {
bio String
}
model categories {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
name String
posts posts[] @relation(fields: [postIds], references: [id]) // [!code ++]
postIds String[] @db.ObjectId // [!code ++]
}
model posts {
id String @id @default(auto()) @map("_id") @db.ObjectId
title String
content String
published Boolean
v Int @map("__v")
author users @relation(fields: [authorId], references: [id])
authorId String @map("author") @db.ObjectId
categories String[] @db.ObjectId // [!code --]
categories categories[] @relation(fields: [categoryIds], references: [id]) // [!code ++]
categoryIds String[] @map("categories") @db.ObjectId // [!code ++]
}
model users {
id String @id @default(auto()) @map("_id") @db.ObjectId
v Int @map("__v")
email String @unique(map: "email_1")
name String
profile UsersProfile?
posts posts[]
}
```
3. Update your application code [#3-update-your-application-code]
3.1. Generate Prisma Client [#31-generate-prisma-client]
Generate Prisma Client based on your schema:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
This creates a type-safe Prisma Client in the `generated/prisma` directory.
3.2. Replace Mongoose queries [#32-replace-mongoose-queries]
Start replacing your Mongoose queries with Prisma Client. Here's an example of how to convert some common queries:
Mongoose
Prisma Client
```typescript
// Find one
const user = await User.findById(id);
// Create
const user = await User.create({
email: "alice@prisma.io",
name: "Alice",
});
// Update
await User.findByIdAndUpdate(id, {
name: "New name",
});
// Delete
await User.findByIdAndDelete(id);
```
```typescript
// Find one
const user = await prisma.user.findUnique({
where: { id },
});
// Create
const user = await prisma.user.create({
data: {
email: "alice@prisma.io",
name: "Alice",
},
});
// Update
await prisma.user.update({
where: { id },
data: { name: "New name" },
});
// Delete
await prisma.user.delete({
where: { id },
});
```
3.3. Update your controllers [#33-update-your-controllers]
Update your Express controllers to use Prisma Client. For example, here's how to update a user controller:
```typescript
import { prisma } from "../client";
export class UserController {
async create(req: Request, res: Response) {
const { email, name } = req.body;
const result = await prisma.user.create({
data: {
email,
name,
},
});
return res.json(result);
}
}
```
Next steps [#next-steps]
Now that you've migrated to Prisma ORM, you can:
* Add more complex queries using Prisma's powerful query API
* Set up Prisma Studio for database management
* Implement database monitoring
* Add automated tests using Prisma's testing utilities
For more information:
* [Prisma ORM documentation](/orm)
* [Prisma Client API reference](/orm/prisma-client/setup-and-configuration/introduction)
# SQL ORMs (/docs/guides/switch-to-prisma-orm/from-sql-orms)
Introduction [#introduction]
This guide shows you how to migrate your application from Sequelize or TypeORM to Prisma ORM.
You can learn how Prisma ORM compares to these ORMs on the comparison pages:
* [Prisma ORM vs Sequelize](/orm/more/comparisons/prisma-and-sequelize)
* [Prisma ORM vs TypeORM](/orm/more/comparisons/prisma-and-typeorm)
Prerequisites [#prerequisites]
Before starting this guide, make sure you have:
* A Sequelize or TypeORM project you want to migrate
* Node.js installed (version 18 or higher)
* PostgreSQL, MySQL, or another [supported database](/orm/reference/supported-databases)
Overview of the migration process [#overview-of-the-migration-process]
The steps for migrating from Sequelize or TypeORM to Prisma ORM are always the same:
1. Install the Prisma CLI
2. Introspect your database
3. Create a baseline migration
4. Install and generate Prisma Client
5. Gradually replace your ORM queries with Prisma Client
Prisma ORM supports **incremental adoption**, so you can migrate your project step-by-step rather than all at once.
Step 1. Install the Prisma CLI [#step-1-install-the-prisma-cli]
npm
pnpm
yarn
bun
```bash
npm install prisma --save-dev
npm install @prisma/client
```
```bash
pnpm add prisma --save-dev
pnpm add @prisma/client
```
```bash
yarn add prisma --dev
yarn add @prisma/client
```
```bash
bun add prisma --dev
bun add @prisma/client
```
Step 2. Introspect your database [#step-2-introspect-your-database]
Run the following command to create a basic Prisma setup:
npm
pnpm
yarn
bun
```bash
npx prisma init
```
```bash
pnpm dlx prisma init
```
```bash
yarn dlx prisma init
```
```bash
bunx --bun prisma init
```
This creates a `prisma` directory with a `schema.prisma` file and a `.env` file. Update the `DATABASE_URL` in `.env` with your connection string:
```bash
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
```
Then introspect your database to generate Prisma models:
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
To create a baseline migration, run:
npm
pnpm
yarn
bun
```bash
mkdir -p prisma/migrations/0_init
npx prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
npx prisma migrate resolve --applied 0_init
```
```bash
mkdir -p prisma/migrations/0_init
pnpm dlx prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
pnpm dlx prisma migrate resolve --applied 0_init
```
```bash
mkdir -p prisma/migrations/0_init
yarn dlx prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
yarn dlx prisma migrate resolve --applied 0_init
```
```bash
mkdir -p prisma/migrations/0_init
bun x prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
bun x prisma migrate resolve --applied 0_init
```
Step 3. Install and generate Prisma Client [#step-3-install-and-generate-prisma-client]
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
Create a file to instantiate Prisma Client (e.g., `db/prisma.ts`):
```typescript
import { PrismaClient } from "@prisma/client";
export const prisma = new PrismaClient();
```
Step 4. Replace your ORM queries with Prisma Client [#step-4-replace-your-orm-queries-with-prisma-client]
Sequelize
TypeORM
Prisma
```typescript
// Find records
const user = await User.findOne({ where: { id: 1 } });
const users = await User.findAll({
where: { active: true },
limit: 10,
order: [['createdAt', 'DESC']]
});
// Create
const user = await User.create({
name: 'Alice',
email: 'alice@example.com'
});
// Update
await User.update(
{ name: 'Alicia' },
{ where: { id: 1 } }
);
// Delete
await User.destroy({ where: { id: 1 } });
// With relations
const posts = await Post.findAll({
include: [{ model: User }],
limit: 10
});
// Transaction
const result = await sequelize.transaction(async (t) => {
const user = await User.create({ name: 'Alice' }, { transaction: t });
const post = await Post.create({ title: 'Hello', userId: user.id }, { transaction: t });
return { user, post };
});
```
```typescript
// Find records
const user = await userRepository.findOne({ where: { id: 1 } });
const users = await userRepository.find({
where: { active: true },
take: 10,
order: { createdAt: 'DESC' }
});
// Create
const user = userRepository.create({
name: 'Alice',
email: 'alice@example.com'
});
await userRepository.save(user);
// Update
await userRepository.update(1, { name: 'Alicia' });
// Delete
await userRepository.delete(1);
// With relations
const posts = await postRepository.find({
relations: ['author'],
take: 10
});
// Transaction
await connection.transaction(async (manager) => {
const user = manager.create(User, { name: 'Alice' });
await manager.save(user);
const post = manager.create(Post, { title: 'Hello', author: user });
await manager.save(post);
});
```
```typescript
// Find records
const user = await prisma.user.findUnique({ where: { id: 1 } });
const users = await prisma.user.findMany({
where: { active: true },
take: 10,
orderBy: { createdAt: 'desc' }
});
// Create
const user = await prisma.user.create({
data: {
name: 'Alice',
email: 'alice@example.com'
}
});
// Update
await prisma.user.update({
where: { id: 1 },
data: { name: 'Alicia' }
});
// Delete
await prisma.user.delete({ where: { id: 1 } });
// With relations
const posts = await prisma.post.findMany({
include: { author: true },
take: 10
});
// Transaction
const result = await prisma.$transaction(async (tx) => {
const user = await tx.user.create({
data: {
name: 'Alice',
posts: { create: { title: 'Hello' } }
},
include: { posts: true }
});
return user;
});
```
Migration tips [#migration-tips]
* **Incremental adoption**: Start by replacing read operations, then gradually move to write operations
* **Schema naming**: Use `@map` and `@@map` to map Prisma model names to existing table/column names
* **Type safety**: Run `npx prisma generate` after any schema changes
* **Performance**: Use `select` to fetch only needed fields and avoid N+1 issues with `include`
Next steps [#next-steps]
* [Prisma Client API Reference](/orm/reference/prisma-client-reference)
* [Schema Reference](/orm/reference/prisma-schema-reference)
* [Prisma ORM vs Sequelize](/orm/more/comparisons/prisma-and-sequelize)
* [Prisma ORM vs TypeORM](/orm/more/comparisons/prisma-and-typeorm)
# Neon (/docs/guides/switch-to-prisma-postgres/from-neon)
This guide walks you through migrating data from Neon to Prisma Postgres using `pg_dump` and `pg_restore`.
Prerequisites [#prerequisites]
* A Neon database connection URL
* A [Prisma Data Platform](https://console.prisma.io) account
* PostgreSQL CLI tools (`pg_dump`, `pg_restore`) version 17
If you don't have them installed, install PostgreSQL 17 client tools:
```bash
# macOS
brew install libpq
brew link --force libpq
# Debian / Ubuntu
sudo apt-get install postgresql-client-17
# Windows (via installer)
# Download from https://www.postgresql.org/download/windows/
# Select "Command Line Tools" during installation
```
Make sure your PostgreSQL tools match the Prisma Postgres version
Prisma Postgres runs PostgreSQL 17. Run `pg_dump --version` or `pg_restore --version` to confirm.
1. Create a new Prisma Postgres database [#1-create-a-new-prisma-postgres-database]
1. Log in to [Prisma Data Platform](https://console.prisma.io/) and open the Console.
2. In a [workspace](/console/concepts#workspace) of your choice, click **New project**.
3. Name your project, then click **Get started** under **Prisma Postgres**.
4. Select a region and click **Create project**.
Once provisioned, get your direct connection string:
1. Click the **API Keys** tab in your project's sidenav.
2. Click **Create API key**, give it a name, and click **Create**.
3. Copy the connection string starting with `postgres://` — you'll need this in step 3.
2. Export data from Neon [#2-export-data-from-neon]
Copy a **non-pooled** connection string from Neon (disable **Connection pooling**) and ensure it includes `sslmode=require`:
```text
postgresql://USER:PASSWORD@YOUR-NEON-HOST/DATABASE?sslmode=require
```
Export the connection string as an environment variable. Use single quotes so that special characters in your password (like `!`, `$`, or `#`) are not interpreted by the shell:
```bash
export NEON_DATABASE_URL='postgresql://USER:PASSWORD@YOUR-NEON-HOST/DATABASE?sslmode=require'
```
Then run:
```bash
pg_dump \
-Fc \
-d "$NEON_DATABASE_URL" \
-n public \
-f neon_dump.bak
```
3. Import data into Prisma Postgres [#3-import-data-into-prisma-postgres]
Export your [direct connection string](/postgres/database/connecting-to-your-database) from step 1 as an environment variable:
```bash
export PRISMA_POSTGRES_DATABASE_URL='postgres://...'
```
Then restore:
```bash
pg_restore \
--no-owner \
--no-acl \
-d "$PRISMA_POSTGRES_DATABASE_URL" \
neon_dump.bak
```
The `--no-owner` and `--no-acl` flags skip Neon-specific role assignments that don't exist in Prisma Postgres.
You can safely ignore the warning `schema "public" already exists`. The `public` schema is pre-created in every Prisma Postgres database, so the `CREATE SCHEMA public` command from the dump is redundant. Your data is still imported correctly.
To validate the import, open [Prisma Studio](/studio) from the **Studio** tab in your project, or run:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
4. Update your application [#4-update-your-application]
Already using Prisma ORM [#already-using-prisma-orm]
Update `DATABASE_URL` in your `.env` file:
```text title=".env"
DATABASE_URL="postgres://USER:PASSWORD@db.prisma.io:5432/?sslmode=require"
```
Then regenerate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
See the [Prisma ORM with Prisma Postgres quickstart](/prisma-orm/quickstart/prisma-postgres) for driver adapter configuration and best practices.
Not yet using Prisma ORM [#not-yet-using-prisma-orm]
Follow [Add Prisma ORM to an existing project](/prisma-orm/add-to-existing-project/prisma-postgres) to introspect your database, generate a schema, and migrate your queries.
# Supabase (/docs/guides/switch-to-prisma-postgres/from-supabase)
This guide walks you through migrating data from Supabase to Prisma Postgres using `pg_dump` and `pg_restore`.
Prerequisites [#prerequisites]
* A Supabase database connection URL
* A [Prisma Data Platform](https://console.prisma.io) account
* PostgreSQL CLI tools (`pg_dump`, `pg_restore`) version 17
If you don't have them installed, install PostgreSQL 17 client tools:
```bash
# macOS
brew install libpq
brew link --force libpq
# Debian / Ubuntu
sudo apt-get install postgresql-client-17
# Windows (via installer)
# Download from https://www.postgresql.org/download/windows/
# Select "Command Line Tools" during installation
```
Make sure your PostgreSQL tools match the Prisma Postgres version
Prisma Postgres runs PostgreSQL 17. Run `pg_dump --version` or `pg_restore --version` to confirm.
1. Create a new Prisma Postgres database [#1-create-a-new-prisma-postgres-database]
1. Log in to [Prisma Data Platform](https://console.prisma.io/) and open the Console.
2. In a [workspace](/console/concepts#workspace) of your choice, click **New project**.
3. Name your project, then click **Get started** under **Prisma Postgres**.
4. Select a region and click **Create project**.
Once provisioned, get your direct connection string:
1. Click the **API Keys** tab in your project's sidenav.
2. Click **Create API key**, give it a name, and click **Create**.
3. Copy the connection string starting with `postgres://` — you'll need this in step 3.
2. Export data from Supabase [#2-export-data-from-supabase]
Copy the **direct** connection string from your Supabase project. In the Supabase Dashboard, go to **Project Settings** → **Database** → **Connection string** → **URI** and select the **Direct** connection type (not the pooled Supavisor connection):
```text
postgresql://postgres:[PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres
```
Export the connection string as an environment variable. Use single quotes so that special characters in your password (like `!`, `$`, or `#`) are not interpreted by the shell:
```bash
export SUPABASE_DATABASE_URL='postgresql://postgres:[PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres'
```
Then run:
```bash
pg_dump \
-Fc \
-d "$SUPABASE_DATABASE_URL" \
-n public \
-f supabase_dump.bak
```
3. Import data into Prisma Postgres [#3-import-data-into-prisma-postgres]
Export your [direct connection string](/postgres/database/connecting-to-your-database) from step 1 as an environment variable:
```bash
export PRISMA_POSTGRES_DATABASE_URL='postgres://...'
```
Then restore:
```bash
pg_restore \
--no-owner \
--no-acl \
-d "$PRISMA_POSTGRES_DATABASE_URL" \
supabase_dump.bak
```
The `--no-owner` and `--no-acl` flags skip Supabase-specific role assignments that don't exist in Prisma Postgres.
You can safely ignore the warning `schema "public" already exists`. The `public` schema is pre-created in every Prisma Postgres database, so the `CREATE SCHEMA public` command from the dump is redundant. Your data is still imported correctly.
To validate the import, open [Prisma Studio](/studio) from the **Studio** tab in your project, or run:
npm
pnpm
yarn
bun
```bash
npx prisma studio
```
```bash
pnpm dlx prisma studio
```
```bash
yarn dlx prisma studio
```
```bash
bunx --bun prisma studio
```
4. Update your application [#4-update-your-application]
Already using Prisma ORM [#already-using-prisma-orm]
Update `DATABASE_URL` in your `.env` file:
```text title=".env"
DATABASE_URL="postgres://USER:PASSWORD@db.prisma.io:5432/?sslmode=require"
```
Then regenerate Prisma Client:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
See the [Prisma ORM with Prisma Postgres quickstart](/prisma-orm/quickstart/prisma-postgres) for driver adapter configuration and best practices.
Not yet using Prisma ORM [#not-yet-using-prisma-orm]
Follow [Add Prisma ORM to an existing project](/prisma-orm/add-to-existing-project/prisma-postgres) to introspect your database, generate a schema, and migrate your queries.
# Upgrade to v1 (/docs/guides/upgrade-prisma-orm/v1)
This guide provides a comprehensive roadmap for migrating your project from Prisma 1 to the latest version of Prisma ORM. The migration process involves significant architectural changes and requires careful planning and execution.
Before you begin [#before-you-begin]
* **Back up your database** before starting the migration
* Review the [Prisma ORM documentation](/orm) to understand the new architecture
* Set up a separate development environment for testing the migration
* Document your current Prisma 1 setup, including models, relations, and any custom configurations
Key changes [#key-changes]
Architectural changes [#architectural-changes]
| Feature | Prisma 1 | Prisma ORM |
| ----------------------- | ----------------------------- | ----------------------------------------- |
| **Database Connection** | Uses Prisma Server as a proxy | Direct database connection |
| **API** | GraphQL API for database | Programmatic access via Prisma Client |
| **Schema** | GraphQL SDL + `prisma.yml` | Unified Prisma schema |
| **Modeling** | GraphQL SDL | Prisma Schema Language (PSL) |
| **Workflow** | `prisma deploy` | `prisma migrate` and `prisma db` commands |
Feature changes [#feature-changes]
* **Removed**: GraphQL API for database
* **New**: Type-safe database client
* **Improved**: Database introspection and migration tools
* **Enhanced**: Support for more database features and types
Migration Strategy [#migration-strategy]
1. Preparation [#1-preparation]
Install Prisma ORM [#install-prisma-orm]
npm
pnpm
yarn
bun
```bash
# Initialize a new project
npm init -y
npm install prisma @prisma/client
# Initialize Prisma
npx prisma init
```
```bash
# Initialize a new project
pnpm init -y
pnpm add prisma @prisma/client
# Initialize Prisma
pnpm dlx prisma init
```
```bash
# Initialize a new project
yarn init -y
yarn add prisma @prisma/client
# Initialize Prisma
yarn dlx prisma init
```
```bash
# Initialize a new project
bun init -y
bun add prisma @prisma/client
# Initialize Prisma
bun x prisma init
```
Set up Database Connection [#set-up-database-connection]
Update the `DATABASE_URL` in your `.env` file to point to your existing database:
```bash
DATABASE_URL="postgresql://user:password@localhost:5432/your_database?schema=public"
```
2. Schema Migration [#2-schema-migration]
Introspect Database [#introspect-database]
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
This will generate a `schema.prisma` file based on your existing database schema.
Update Schema [#update-schema]
After introspection, you'll need to make several adjustments to the schema:
Default Values [#default-values]
```prisma
// Before (Prisma 1)
model User {
id String @default(cuid())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
Relations [#relations]
```prisma
// Before (Prisma 1)
type Post {
id ID! @id
title String!
author User! @relation(name: "UserPosts")
}
// After (Prisma ORM)
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
}
```
3. Data Model Adjustments [#3-data-model-adjustments]
3.1 Handling Special Types [#31-handling-special-types]
| Prisma 1 Type | Prisma ORM Equivalent | Notes |
| ------------- | ----------------------------- | -------------------------- |
| `ID` | `String @id @default(cuid())` | Add `@id` directive |
| `DateTime` | `DateTime` | No change needed |
| `Json` | `Json` | No change needed |
| `Enum` | `Enum` | Define enums in the schema |
3.2 Relation Handling [#32-relation-handling]
Prisma ORM requires explicit relation fields and foreign keys:
```prisma
model User {
id Int @id @default(autoincrement())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
}
```
4. Update Application Code [#4-update-application-code]
4.1 Replace Prisma 1 Client with Prisma Client [#41-replace-prisma-1-client-with-prisma-client]
```typescript
// Before (Prisma 1)
import { prisma } from './generated/prisma-client';
async function getUser(id: string) {
return prisma.user({ id });
}
// After (Prisma ORM)
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function getUser(id: number) {
return prisma.user.findUnique({
where: { id }
});
}
```
4.2 Update Queries and Mutations [#42-update-queries-and-mutations]
Fetching Data [#fetching-data]
```typescript
// Before (Prisma 1)
const user = await prisma.user({ id: 1 });
const posts = await prisma.user({ id: 1 }).posts();
// After (Prisma ORM)
const user = await prisma.user.findUnique({
where: { id: 1 },
include: { posts: true }
});
const posts = user?.posts;
```
Creating Records [#creating-records]
```typescript
// Before (Prisma 1)
const newUser = await prisma.createUser({
name: 'Alice',
email: 'alice@example.com'
});
// After (Prisma ORM)
const newUser = await prisma.user.create({
data: {
name: 'Alice',
email: 'alice@example.com'
}
});
```
Testing and Validation [#testing-and-validation]
1. Test Data Operations [#1-test-data-operations]
Test all CRUD operations to ensure data consistency:
```typescript
// Test create
const user = await prisma.user.create({
data: { name: 'Test', email: 'test@example.com' }
});
// Test read
const foundUser = await prisma.user.findUnique({
where: { id: user.id }
});
// Test update
const updatedUser = await prisma.user.update({
where: { id: user.id },
data: { name: 'Updated Name' }
});
// Test delete
await prisma.user.delete({
where: { id: user.id }
});
```
2. Test Relations [#2-test-relations]
Verify that all relations work as expected:
```typescript
// Test relation queries
const userWithPosts = await prisma.user.findUnique({
where: { id: 1 },
include: {
posts: true,
profile: true
}
});
// Test nested writes
const userWithNewPost = await prisma.user.create({
data: {
name: 'Bob',
email: 'bob@example.com',
posts: {
create: {
title: 'Hello World',
content: 'This is my first post'
}
}
},
include: {
posts: true
}
});
```
Handling Special Cases [#handling-special-cases]
1. Real-time Subscriptions [#1-real-time-subscriptions]
Prisma ORM doesn't include built-in real-time subscriptions. Consider these alternatives:
Option 1: Database Triggers [#option-1-database-triggers]
```sql
-- PostgreSQL example
CREATE OR REPLACE FUNCTION notify_new_post()
RETURNS TRIGGER AS $$
BEGIN
PERFORM pg_notify('new_post', row_to_json(NEW)::text);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER new_post_trigger
AFTER INSERT ON "Post"
FOR EACH ROW EXECUTE FUNCTION notify_new_post();
```
Option 2: Application-Level Events [#option-2-application-level-events]
```typescript
// Publish event when creating a post
const post = await prisma.post.create({
data: {
title: 'New Post',
content: 'Content',
author: { connect: { id: userId }}
}
});
// Publish event to your pub/sub system
await pubsub.publish('POST_CREATED', { postCreated: post });
```
2. Authentication [#2-authentication]
If you were using Prisma 1's built-in authentication, you'll need to implement your own solution:
```typescript
import { compare } from 'bcryptjs';
import { sign } from 'jsonwebtoken';
export async function login(email: string, password: string) {
const user = await prisma.user.findUnique({ where: { email } });
if (!user) throw new Error('User not found');
const valid = await compare(password, user.password);
if (!valid) throw new Error('Invalid password');
const token = sign({ userId: user.id }, process.env.APP_SECRET!);
return { token, user };
}
```
Migration Tools [#migration-tools]
Prisma 1 Upgrade CLI [#prisma-1-upgrade-cli]
The [Prisma 1 Upgrade CLI](https://github.com/prisma/prisma1-upgrade) can help automate parts of the migration:
npm
pnpm
yarn
bun
```bash
# Install the upgrade CLI
npm install -g prisma1-upgrade
# Run the upgrade helper
prisma1-upgrade
```
```bash
# Install the upgrade CLI
pnpm add -g prisma1-upgrade
# Run the upgrade helper
prisma1-upgrade
```
```bash
# Install the upgrade CLI
yarn global add prisma1-upgrade
# Run the upgrade helper
prisma1-upgrade
```
```bash
# Install the upgrade CLI
bun add --global prisma1-upgrade
# Run the upgrade helper
prisma1-upgrade
```
This tool helps with:
* Converting your Prisma 1 datamodel to Prisma schema
* Identifying potential issues in your schema
* Providing migration recommendations
Performance Considerations [#performance-considerations]
1. **Connection Pooling**: Configure connection pooling for better performance:
```typescript
const prisma = new PrismaClient({
log: ['query', 'info', 'warn', 'error'],
datasources: {
db: {
url: process.env.DATABASE_URL + '&connection_limit=20'
}
}
});
```
2. **Query Optimization**: Use `select` to fetch only needed fields:
```typescript
const user = await prisma.user.findUnique({
where: { id: 1 },
select: {
id: true,
name: true,
email: true
}
});
```
Next Steps [#next-steps]
* [Prisma ORM Documentation](/orm)
* [Prisma Schema Reference](/orm/reference/prisma-schema-reference)
* [Prisma Client API Reference](/orm/reference/prisma-client-reference)
* [Prisma Migrate Guide](/orm/prisma-migrate)
* [Prisma Studio](https://www.prisma.io/studio)
Getting Help [#getting-help]
If you encounter issues during migration:
1. Search the [GitHub Issues](https://github.com/prisma/prisma/issues)
2. Ask for help in the [Prisma Slack](https://slack.prisma.io/)
3. Open a [GitHub Discussion](https://github.com/prisma/prisma/discussions)
# Upgrade to v3 (/docs/guides/upgrade-prisma-orm/v3)
This guide helps you upgrade your project to Prisma ORM v3. Version 3 includes several important changes that may affect your application, so please review this guide carefully before proceeding.
Before you begin [#before-you-begin]
* **Backup your database** before starting the upgrade process
* Review the [release notes](https://github.com/prisma/prisma/releases/tag/3.0.1) for a complete list of changes
* Test the upgrade in a development or staging environment first
Key changes [#key-changes]
Referential Actions [#referential-actions]
Prisma ORM 3 introduces native support for referential actions, which changes how cascading deletes are handled:
* The safety net that previously prevented cascading deletes at runtime has been removed
* You now have more control over referential actions
* You should explicitly define referential actions in your schema
Before (Prisma 2.x): [#before-prisma-2x]
```prisma
model User {
id Int @id @default(autoincrement())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id])
authorId Int
}
```
After (Prisma 3.x): [#after-prisma-3x]
```prisma
model User {
id Int @id @default(autoincrement())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
author User @relation(
fields: [authorId],
references: [id],
onDelete: Cascade, // Explicit action required
onUpdate: Cascade // Optional: define update behavior
)
authorId Int
}
```
**Action Required**: Review all your relation fields and add appropriate `onDelete` and `onUpdate` actions.
Named Constraints and Indexes [#named-constraints-and-indexes]
Prisma ORM 3 changes how constraints and indexes are named:
* New naming convention for constraints and indexes
* Clear distinction between `map` (database-level name) and `name` (Prisma Client API name)
* Primary and foreign key names are now part of the schema for supporting databases
Option 1: Keep Existing Constraint Names [#option-1-keep-existing-constraint-names]
If you need to maintain existing constraint names (for compatibility with other tools or conventions):
1. Run `prisma db pull` to update your schema with existing constraint names
2. The schema will include `@map` attributes for non-default constraint names
Option 2: Use New Default Naming Convention [#option-2-use-new-default-naming-convention]
To use Prisma ORM's new default naming convention:
1. Run `prisma migrate dev` to generate a migration updating constraint names
2. Apply the migration to all environments
**Example of constraint naming in schema**:
```prisma
model User {
id Int @id(map: "Custom_Primary_Key") @default(autoincrement())
email String @unique(map: "Custom_Unique_Constraint")
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id], map: "Custom_Foreign_Key")
authorId Int
}
```
$queryRaw Method Changes [#queryraw-method-changes]
The `$queryRaw` method now only supports template literals for security:
Before (Prisma 2.x): [#before-prisma-2x-1]
```typescript
// String syntax (no longer supported in v3)
const result = await prisma.$queryRaw('SELECT * FROM User WHERE id = 1');
```
After (Prisma 3.x): [#after-prisma-3x-1]
```typescript
// Template literal syntax (recommended)
const userId = 1;
const result = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${userId}`;
// Or use $queryRawUnsafe (use with caution)
const unsafeResult = await prisma.$queryRawUnsafe(
'SELECT * FROM User WHERE id = $1',
userId
);
```
**Action Required**: Update all `$queryRaw` calls in your codebase to use template literals or switch to `$queryRawUnsafe` with proper parameterization.
JSON Null Handling [#json-null-handling]
Prisma ORM 3 introduces more precise handling of null values in JSON fields:
* `{ equals: null }` now checks for database NULL values
* New types are available for different null representations:
* `Prisma.JsonNull`: Represents a JSON null value
* `Prisma.DbNull`: Represents a database NULL value
* `Prisma.AnyNull`: Matches either JSON null or database NULL
Before (Prisma 2.x): [#before-prisma-2x-2]
```typescript
// Ambiguous behavior in v2
const result = await prisma.log.findMany({
where: {
meta: {
equals: null // Could mean either JSON null or database NULL
}
}
});
```
After (Prisma 3.x): [#after-prisma-3x-2]
```typescript
import { Prisma } from '@prisma/client';
// Check for JSON null
const jsonNullResults = await prisma.log.findMany({
where: {
meta: {
equals: Prisma.JsonNull
}
}
});
// Check for database NULL
const dbNullResults = await prisma.log.findMany({
where: {
meta: {
equals: Prisma.DbNull
}
}
});
// Check for either
const anyNullResults = await prisma.log.findMany({
where: {
meta: {
equals: Prisma.AnyNull
}
}
});
// Creating with specific null types
await prisma.log.create({
data: {
meta: Prisma.JsonNull // or Prisma.DbNull
}
});
```
**Action Required**: Update all JSON field operations that involve null values to use the appropriate null type.
Update packages [#update-packages]
To upgrade to Prisma ORM 3 from an earlier version, you need to update both the `prisma` and `@prisma/client` packages:
npm
pnpm
yarn
bun
```bash
npm install @prisma/client@3
npm install -D prisma@3
npx prisma generate
```
```bash
pnpm add @prisma/client@3
pnpm add -D prisma@3
pnpm dlx prisma generate
```
```bash
yarn add @prisma/client@3
yarn add --dev prisma@3
yarn dlx prisma generate
```
```bash
bun add @prisma/client@3
bun add --dev prisma@3
bun x prisma generate
```
For yarn, use `yarn up prisma@3 @prisma/client@3`. For pnpm, use `pnpm upgrade prisma@3 @prisma/client@3`.
Before you upgrade, check each breaking change below to see how the upgrade might affect your application.
Upgrade steps [#upgrade-steps]
1. **Add Referential Actions**: Update your schema to include explicit `onDelete` and `onUpdate` actions for all relations.
2. **Handle Constraint Naming**: Decide whether to keep existing constraint names or migrate to the new naming convention.
3. **Update JSON Fields**: Modify any JSON field operations that involve null values to use the new null types.
4. Update Application Code [#4-update-application-code]
1. **Update Raw Queries**: Convert all `$queryRaw` calls to use template literals or switch to `$queryRawUnsafe`.
2. **Test Thoroughly**: Pay special attention to:
* Relations and cascading deletes
* JSON field operations
* Any raw SQL queries
* Custom constraints and indexes
5. Migration Strategy for Production [#5-migration-strategy-for-production]
1. **Test in Development**: Test the upgrade in a development or staging environment first.
2. **Create a Backup**: Always create a backup of your production database before upgrading.
3. **Schedule Downtime**: Plan for a maintenance window if needed.
4. **Deploy Updates**: Update your application with the new Prisma ORM 3 packages.
5. **Monitor**: Keep an eye on your application after the upgrade.
Troubleshooting [#troubleshooting]
Common Issues [#common-issues]
1. **Missing Referential Actions**
* **Symptom**: Unexpected behavior with cascading deletes
* **Solution**: Add explicit `onDelete` and `onUpdate` actions to your relations
2. **JSON Null Handling**
* **Symptom**: Type errors when filtering JSON fields
* **Solution**: Use `Prisma.JsonNull`, `Prisma.DbNull`, or `Prisma.AnyNull`
3. **Raw Query Errors**
* **Symptom**: Errors with `$queryRaw`
* **Solution**: Convert to template literals or use `$queryRawUnsafe`
Next Steps [#next-steps]
* [Prisma ORM 3 Release Notes](https://github.com/prisma/prisma/releases/tag/3.0.1)
* [Prisma Schema Reference](/orm/reference/prisma-schema-reference)
* [Prisma Client API Reference](/orm/reference/prisma-client-reference)
* [Raw Database Access](/orm/prisma-client/using-raw-sql/raw-queries)
# Upgrade to v4 (/docs/guides/upgrade-prisma-orm/v4)
This guide helps you upgrade your project to Prisma ORM 4. Version 4 includes several important changes that may affect your application, so please review this guide carefully before proceeding.
Before you begin [#before-you-begin]
* **Back up your database** before starting the upgrade
* Review the [release notes](https://github.com/prisma/prisma/releases/tag/4.0.0) for a complete list of changes
* Test the upgrade in a development or staging environment first
* Ensure you're using Node.js 14.17.0 or later (required for Prisma 4+)
Key changes [#key-changes]
System requirements [#system-requirements]
* **Minimum Node.js version**: 14.17.0 or later
* **Database versions**: Check [system requirements](/orm/reference/system-requirements) for database version compatibility
Breaking changes [#breaking-changes]
1. **Schema Changes**
* Explicit `@unique` constraints for one-to-one relations
* Enforced `@unique` or `@id` for one-to-one and one-to-many relations in MySQL/MongoDB
* Scalar list defaults
* Index configuration improvements
* Better string literal grammar
2. **Client changes**
* `queryRaw` return type changes
* JSON null handling updates
* MongoDB composite type default fields
* Removed deprecated APIs
Update packages [#update-packages]
To upgrade to Prisma ORM 4 from an earlier version, you need to update both the `prisma` and `@prisma/client` packages:
npm
pnpm
yarn
bun
```bash
npm install @prisma/client@4
npm install -D prisma@4
npx prisma generate
```
```bash
pnpm add @prisma/client@4
pnpm add -D prisma@4
pnpm dlx prisma generate
```
```bash
yarn add @prisma/client@4
yarn add --dev prisma@4
yarn dlx prisma generate
```
```bash
bun add @prisma/client@4
bun add --dev prisma@4
bun x prisma generate
```
Before you upgrade, check each breaking change below to see how the upgrade might affect your application.
Upgrade steps [#upgrade-steps]
1. **Update Schema**: Review and update your schema to handle breaking changes
2. **Update Application Code**: Make necessary changes to your application code
3. **Test Thoroughly**: Test all functionality, especially:
* One-to-one relations
* JSON field operations
* Raw queries
* Index configurations
Update schema [#update-schema]
Handle Schema Validation Errors [#handle-schema-validation-errors]
Run the following command to check for schema validation errors:
npm
pnpm
yarn
bun
```bash
npx prisma validate
```
```bash
pnpm dlx prisma validate
```
```bash
yarn dlx prisma validate
```
```bash
bunx --bun prisma validate
```
Address any validation errors, paying special attention to:
1. **Explicit `@unique` constraints for one-to-one relations**
* Add `@unique` to relation scalar fields in one-to-one relations
```prisma
// Before
model User {
id Int @id @default(autoincrement())
profile Profile? @relation(fields: [profileId], references: [id])
profileId Int?
}
// After
model User {
id Int @id @default(autoincrement())
profile Profile? @relation(fields: [profileId], references: [id])
profileId Int? @unique // Added @unique
}
```
2. **Enforced `@unique` or `@id` for relations in MySQL/MongoDB**
* Ensure referenced fields in one-to-one and one-to-many relations have `@unique` or `@id`
```prisma
// Before (MySQL/MongoDB)
model User {
id Int @id @default(autoincrement())
email String // Missing @unique
posts Post[]
}
// After (MySQL/MongoDB)
model User {
id Int @id @default(autoincrement())
email String @unique // Added @unique
posts Post[]
}
```
3. **Update SQLite connection strings**
* Remove the `sqlite:` protocol prefix if present
* Change from: `sqlite:./dev.db`
* To: `file:./dev.db`
4. **String literals**
* Update any string literals that use the old grammar
* Change from: `a string with \"quotes\"`
* To: `a string with \"quotes\"` or `a string with "quotes"`
Pull Latest Schema Changes [#pull-latest-schema-changes]
After fixing validation errors, pull the latest schema changes:
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
This will update your schema with new capabilities like improved index configuration.
Update application code [#update-application-code]
Handle queryRaw Return Type Changes [#handle-queryraw-return-type-changes]
In Prisma 4, the return types of `queryRaw` and `queryRawUnsafe` have changed:
| Data Type | Before 4.0.0 | From 4.0.0 |
| ---------- | ------------ | ---------- |
| `DateTime` | `String` | `Date` |
| `BigInt` | `String` | `BigInt` |
| `Bytes` | `String` | `Buffer` |
| `Decimal` | `String` | `Decimal` |
**Update your code** to handle these type changes, especially if you're using TypeScript or performing type checks.
Update JSON Handling [#update-json-handling]
Prisma 4 changes how JSON null values are handled. If you're working with JSON fields:
```typescript
// Before
const result = await prisma.model.findMany({
where: {
jsonField: { equals: null }
}
});
// After
import { Prisma } from '@prisma/client';
const result = await prisma.model.findMany({
where: {
jsonField: { equals: Prisma.JsonNull }
}
});
```
MongoDB Composite Types [#mongodb-composite-types]
For MongoDB users, Prisma 4 changes how default fields on composite types work. If you're using MongoDB with composite types, test your queries to ensure they return the expected results.
Test application [#test-application]
After updating your schema and code, thoroughly test your application:
1. **Run your test suite** to catch any type errors or runtime issues
2. **Test database operations** including:
* CRUD operations
* Relations and nested queries
* Transactions
* Raw queries
3. **Verify performance** of common operations
4. **Check error handling** for edge cases
New Features in Prisma 4 [#new-features-in-prisma-4]
1. Improved Index Configuration (GA) [#1-improved-index-configuration-ga]
The `extendedIndexes` feature is now generally available, with support for:
* **Length configuration** for MySQL indexes
* **Sort order** configuration for indexes
* **Additional index types** for PostgreSQL:
* Hash
* GIN
* GiST
* SP-GiST
* BRIN
* **Index clustering** for SQL Server
Example usage:
```prisma
model User {
id Int @id
email String @unique(sort: Desc)
name String
@@index([name(sort: Asc, length: 10)])
@@index([email], type: Hash) // PostgreSQL specific
}
```
2. Scalar List Defaults [#2-scalar-list-defaults]
You can now set default values for scalar lists in your schema:
```prisma
model User {
id Int @id @default(autoincrement())
favoriteColors String[] @default(["red", "blue", "green"])
luckyNumbers Int[] @default([7, 42])
}
```
3. Better Type Safety [#3-better-type-safety]
Prisma 4 improves type safety with:
* Stricter validation of relation fields
* Better error messages for common mistakes
* Improved type inference for complex queries
Migration checklist [#migration-checklist]
Before Upgrading [#before-upgrading]
* [ ] Back up your database
* [ ] Check Node.js version (14.17.0 or later required)
* [ ] Review breaking changes in this guide
* [ ] Set up a testing environment
During Upgrade [#during-upgrade]
* [ ] Update dependencies to Prisma 4
* [ ] Fix schema validation errors
* [ ] Update relation fields with required `@unique` constraints
* [ ] Update raw query handling for new return types
* [ ] Test JSON field operations
* [ ] Verify MongoDB composite type behavior if applicable
After Upgrading [#after-upgrading]
* [ ] Run your full test suite
* [ ] Test all critical paths in your application
* [ ] Monitor performance in production
* [ ] Update any documentation that references Prisma versions
Troubleshooting [#troubleshooting]
Common Issues [#common-issues]
1. **Schema Validation Errors**
* **Symptom**: Errors about missing `@unique` constraints
* **Solution**: Add `@unique` to required relation fields
2. **Type Errors in `queryRaw`**
* **Symptom**: Type errors after upgrade
* **Solution**: Update type definitions to match new return types
3. **JSON Null Handling**
* **Symptom**: Different behavior with JSON nulls
* **Solution**: Use `Prisma.JsonNull`, `Prisma.DbNull`, or `Prisma.AnyNull` explicitly
Next Steps [#next-steps]
* [Prisma 4.0.0 Release Notes](https://github.com/prisma/prisma/releases/tag/4.0.0)
* [Prisma Schema Reference](/orm/reference/prisma-schema-reference)
* [Prisma Client API Reference](/orm/reference/prisma-client-reference)
* [Raw Database Access](/orm/prisma-client/using-raw-sql/raw-queries)
Getting Help [#getting-help]
If you encounter issues during the upgrade:
1. Check the [GitHub Issues](https://github.com/prisma/prisma/issues) for known problems
2. Ask for help in the [Prisma Slack](https://slack.prisma.io/)
3. Open a [GitHub Discussion](https://github.com/prisma/prisma/discussions)
# Upgrade to v5 (/docs/guides/upgrade-prisma-orm/v5)
Prisma ORM v5.0.0 introduces a number of changes, including the usage of our new JSON Protocol, [which makes Prisma Client faster by default](https://www.prisma.io/blog/prisma-5-f66prwkjx72s). A full list of these changes can be found [in our release notes](https://github.com/prisma/prisma/releases/tag/5.0.0).
This guide explains how upgrading might affect your application and gives instructions on how to handle breaking changes within Prisma ORM 5.
Update packages [#update-packages]
To upgrade to Prisma ORM 5 from an earlier version, you need to update both the `prisma` and `@prisma/client` packages.
npm
pnpm
yarn
bun
```bash
npm install @prisma/client@5
npm install -D prisma@5
npx prisma generate
```
```bash
pnpm add @prisma/client@5
pnpm add -D prisma@5
pnpm dlx prisma generate
```
```bash
yarn add @prisma/client@5
yarn add --dev prisma@5
yarn dlx prisma generate
```
```bash
bun add @prisma/client@5
bun add --dev prisma@5
bun x prisma generate
```
Before you upgrade, check each breaking change below to see how the upgrade might affect your application.
Prerequisites [#prerequisites]
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](/orm/reference/system-requirements) for all minimum version requirements.
Node.js version [#nodejs-version]
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 [end-of-life on 11 September 2023](https://nodejs.org/en/blog/announcements/nodejs16-eol) 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 version [#typescript-version]
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 version [#postgresql-version]
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 [PostgreSQL's versioning policy](https://www.postgresql.org/support/versioning/) to determine which versions are currently supported.
SQLite version [#sqlite-version]
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 [the SQLite changelog](https://www.sqlite.org/changes.html).
Breaking changes [#breaking-changes]
This section gives an overview of the main breaking changes in Prisma ORM 5.
Removed rejectOnNotFound [#removed-rejectonnotfound]
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 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](#removed-rejectonnotfound).
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](#removed-rejectonnotfound).
JSON protocol [#json-protocol]
The `jsonProtocol` preview feature is now Generally Available. This new protocol leads to [significantly improved startup times](https://www.prisma.io/blog/prisma-5-f66prwkjx72s#improved-startup-performance-in-prisma-client) 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:
```prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["jsonProtocol"]
}
```
Prisma ORM 5:
```prisma
generator client {
provider = "prisma-client-js"
}
```
Removed Array Shortcuts [#removed-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:
* `OR` shortcuts
* `in` and `notIn` shortcuts
* PostgreSQL JSON `path` field shortcuts
* Scalar list shortcuts
* MongoDB Composite list shortcuts
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 [#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](/orm/reference/prisma-schema-reference#postgresql) and also the `postgresql` provider, you will need to [baseline your database](/prisma-orm/add-to-existing-project/cockroachdb#5-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 (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](/prisma-orm/add-to-existing-project/cockroachdb#5-baseline-your-database) in order to make your local setup agree with your existing CockroachDB instance.
6. Perform the [baselining steps](/prisma-orm/add-to-existing-project/cockroachdb#5-baseline-your-database). After these steps, you'll have migrated successfully from the `postgresql` provider to the `cockroachdb` provider!
Removed runtime/index.js [#removed-runtimeindexjs]
The `runtime/index.js` file has been removed from Prisma Client.
Using public APIs from @prisma/client/runtime [#using-public-apis-from-prismaclientruntime]
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:
```js
import { Decimal, NotFoundError } from "@prisma/client/runtime";
const num = new Decimal(24.454545);
const notFound = new NotFoundError();
```
will need to be changed to
```js
import { Prisma } from "@prisma/client";
const num = new Prisma.Decimal(24.454545);
const notFound = new Prisma.NotFoundError();
```
Using private APIs for a specific runtime [#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 [please reach out to us on GitHub.](https://github.com/prisma/prisma/discussions/new?category=q-a)
Generated type changes [#generated-type-changes]
Changes to RelationFilterInput to account for nullability [#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:
```prisma
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 [#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:
```prisma
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 [#other-changes]
Removal of deprecated Prisma CLI flags [#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`.
Removal of the beforeExit hook from the library engine [#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:
```js
const exitHandler = () => {
// your exit handler code
};
prisma.$on("beforeExit", exitHandler);
```
Could become:
```js
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:
```diff title="prisma.service.ts"
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect()
}
- async enableShutdownHooks(app: INestApplication) {
- this.$on('beforeExit', async () => {
- await app.close()
- })
- }
}
```
Instead, use the built-in `enableShutdownHooks` method in NestJS if you need to handle lifecycle events:
```diff title="main.ts"
- prismaService.enableShutdownHooks(app)
+ app.enableShutdownHooks()
```
Removal of deprecated prisma2 executable [#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`.
Removed experimentalFeatures [#removed-experimentalfeatures]
The `previewFeatures` field of the [generator block](/orm/reference/prisma-schema-reference#generator) 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.
Renamed migration-engine to schema-engine [#renamed-migration-engine-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 [#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`.
```yaml highlight=6;delete|7;add
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-*'
```
Serverless Framework pattern suggestion
Be sure to include the `@prisma/engines` folder in your package patterns.
```yaml highlight=6;normal
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!
# Upgrade to v6 (/docs/guides/upgrade-prisma-orm/v6)
Prisma ORM v6 introduces a number of **breaking changes** when you upgrade from an earlier Prisma ORM version. This guide explains how this upgrade might affect your application and gives instructions on how to handle any changes.
Questions answered in this page
* What changed in Prisma 6?
* How do I upgrade safely?
* Which breaking changes affect my app?
Update packages [#update-packages]
To upgrade to Prisma ORM v6 from an earlier version, you need to update both the `prisma` and `@prisma/client` packages:
npm
pnpm
yarn
bun
```bash
npm install @prisma/client@6
npm install -D prisma@6
```
```bash
pnpm add @prisma/client@6
pnpm add -D prisma@6
```
```bash
yarn add @prisma/client@6
yarn add --dev prisma@6
```
```bash
bun add @prisma/client@6
bun add --dev prisma@6
```
For yarn, use `yarn up prisma@6 @prisma/client@6`. For pnpm, use `pnpm upgrade prisma@6 @prisma/client@6`. For bun, use `bun add @prisma/client@6` and `bun add prisma@6 --dev`.
Before you upgrade, check each breaking change below to see how the upgrade might affect your application.
Breaking changes [#breaking-changes]
This section gives an overview of breaking changes in Prisma ORM v6.
Minimum supported Node.js versions [#minimum-supported-nodejs-versions]
The new minimum supported Node.js versions for Prisma ORM v6 are:
* for Node.js 18 the minimum supported version is **18.18.0**
* for Node.js 20 the minimum supported version is **20.9.0**
* for Node.js 22 the minimum supported version is **22.11.0**
There is *no* official support for Node.js 16, 17, 19 and 21.
Minimum supported TypeScript version [#minimum-supported-typescript-version]
The new minimum supported TypeScript version for Prisma ORM v6 is: **5.1.0**.
This schema change only applies to PostgreSQL.\
If you are using CockroachDB, you do not need to take any action—the schema for implicit m-to-n relationships remains unchanged.
Schema change for implicit m-n relations on PostgreSQL [#schema-change-for-implicit-m-n-relations-on-postgresql]
If you're using PostgreSQL and are defining [implicit many-to-many relations](/orm/prisma-schema/data-model/relations/many-to-many-relations#implicit-many-to-many-relations) in your Prisma schema, Prisma ORM maintains the [relation table](/orm/prisma-schema/data-model/relations/many-to-many-relations#relation-table-conventions) for you under the hood. This relation table has `A` and `B` columns to represent the tables of the models that are part of this relation.
Previous versions of Prisma ORM used to create a *unique index* on these two columns. In Prisma v6, this unique index is changing to a *primary key* in order to [simplify for the default replica identity behaviour](https://github.com/prisma/prisma/issues/25196).
Expand for an example
As an example, consider the following Prisma schema with an implicit m-n relation between `Post` and `Tag` models:
```prisma
model Post {
id Int @id @default(autoincrement())
title String
categories Tag[]
}
model Tag {
id Int @id @default(autoincrement())
name String
posts Post[]
}
```
In this case, Prisma ORM maintains the following relation table for you under the hood:
```sql
-- CreateTable
CREATE TABLE "_PostToTag" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL
);
-- CreateIndex
CREATE UNIQUE INDEX "_PostToTag_AB_unique" ON "_PostToTag"("A", "B");
-- CreateIndex
CREATE INDEX "_PostToTag_B_index" ON "_PostToTag"("B");
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
```
In Prisma v6, the `UNIQUE INDEX` is changing into a `PRIMARY KEY`:
```sql
-- CreateTable
CREATE TABLE "_PostToTag" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL,
CONSTRAINT "_PostToTag_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateIndex
CREATE INDEX "_PostToTag_B_index" ON "_PostToTag"("B");
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Post"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
```
If you're defining implicit m-n relations in your Prisma schema, **the next migration you'll create will contain `ALTER TABLE` statements for *all* the relation tables** that belong to these relations. These will look similar to this:
```sql
-- AlterTable
ALTER TABLE "_PostToTag" ADD CONSTRAINT "_PostToTag_AB_pkey" PRIMARY KEY ("A", "B");
-- DropIndex
DROP INDEX "_PostToTag_AB_unique";
```
In order to isolate these schema changes (and not having them bundled with your next migration), **we recommend that you create a new migration *right after* having upgraded to Prisma v6**:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name upgrade-to-v6
```
```bash
pnpm dlx prisma migrate dev --name upgrade-to-v6
```
```bash
yarn dlx prisma migrate dev --name upgrade-to-v6
```
```bash
bunx --bun prisma migrate dev --name upgrade-to-v6
```
That way, you have a single, dedicated migration that takes care of this schema change and otherwise keeps your migration history clean.
Full-text search on PostgreSQL [#full-text-search-on-postgresql]
The [`fullTextSearch`](/v6/orm/prisma-client/queries/full-text-search) Preview feature is promoted to General Availability only for MySQL. This means that if you're using PostgreSQL and currently make use of this Preview feature, you now need to use the new [`fullTextSearchPostgres`](/v6/orm/prisma-client/queries/full-text-search#enabling-full-text-search-for-postgresql) Preview feature:
Before [#before]
```prisma title="schema.prisma"
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearch"]
}
```
After [#after]
```prisma title="schema.prisma"
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearchPostgres"]
}
```
Usage of Buffer [#usage-of-buffer]
In an effort to improve compatibility between Prisma and new modern JavaScript runtimes, we're gradually moving away from Node.js-specific APIs in favor of standard JavaScript.
Prisma v6 replaces the usage of [`Buffer`](https://nodejs.org/api/buffer.html) with [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) to represent fields of type `Bytes`. Make sure to replace all your occurrences of the `Buffer` type with the new `Uint8Array`.
Expand to view how to convert between
Buffer
and
Uint8Array
Conversion from Buffer to Uint8Array [#conversion-from-buffer-to-uint8array]
You can directly use the `Buffer` instance as a `Uint8Array`:
```ts
const buffer: Buffer = Buffer.from([1, 2, 3, 4]);
const uint8Array: Uint8Array = buffer; // No conversion needed
```
Conversion from Uint8Array to Buffer [#conversion-from-uint8array-to-buffer]
You can create a `Buffer` from a `Uint8Array` using `Buffer.from`:
```ts
const uint8Array: Uint8Array = new Uint8Array([1, 2, 3, 4]);
const buffer: Buffer = Buffer.from(uint8Array.buffer);
```
Before [#before-1]
Code
Prisma schema
```ts
import { PrismaClient } from "@prisma/client";
async function main() {
const prisma = new PrismaClient();
await prisma.user.deleteMany();
const bytesCreated = await prisma.user.create({
data: {
bytes: Buffer.from([1, 2, 3, 4]),
},
});
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// `bytesCreated` used to have type: {
// bytes: Buffer
// id: number
// }
for (const bytesFound of await prisma.user.findMany()) {
bytesFound.bytes; // Buffer [ 1, 2, 3, 4 ]
}
}
main();
```
```prisma
model User {
id Int @id @default(autoincrement())
bytes Bytes
}
```
After [#after-1]
Code
Prisma schema
```ts
import { PrismaClient } from "@prisma/client";
async function main() {
const prisma = new PrismaClient();
await prisma.user.deleteMany();
const bytesCreated = await prisma.user.create({
data: {
bytes: Uint8Array.from([1, 2, 3, 4]),
},
});
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// `bytesCreated` now has type: {
// bytes: Uint8Array
// id: number
// }
for (const bytesFound of await prisma.user.findMany()) {
bytesFound.bytes; // Uint8Array [ 1, 2, 3, 4 ]
}
}
main();
```
```prisma
model User {
id Int @id @default(autoincrement())
bytes Bytes
}
```
Removed NotFoundError [#removed-notfounderror]
In Prisma v6, we removed the `NotFoundError` in favor of `PrismaClientKnownRequestError` with error code [`P2025`](/orm/reference/error-reference#p2025) in [`findUniqueOrThrow()`](/orm/reference/prisma-client-reference#finduniqueorthrow) and [`findFirstOrThrow()`](/orm/reference/prisma-client-reference#findfirstorthrow). If you've relied on catching `NotFoundError` instances in your code, you need to adjust the code accordingly.
Before [#before-2]
```ts
import { PrismaClient, NotFoundError } from "@prisma/client";
// inside an `async` function
try {
const user = await prisma.user.findUniqueOrThrow({
where: { id: 42 },
});
console.log(user);
} catch (error) {
if (error instanceof NotFoundError) {
// [!code highlight]
console.error("User not found!"); // [!code highlight]
} // [!code highlight]
else {
console.error("Unexpected error:", error);
}
}
```
After [#after-2]
```ts
import { PrismaClient, Prisma } from "@prisma/client";
// inside an `async` function
try {
const user = await prisma.user.findUniqueOrThrow({
where: { id: 42 },
});
console.log(user);
} catch (error) {
if (
// [!code highlight]
error instanceof Prisma.PrismaClientKnownRequestError && // [!code highlight]
error.code === "P2025" // Specific code for "record not found" // [!code highlight]
) {
// [!code highlight]
console.error("User not found!"); // [!code highlight]
} // [!code highlight]
else {
console.error("Unexpected error:", error);
}
}
```
New keywords that can't be used as model names: async, await, using [#new-keywords-that-cant-be-used-as-model-names-async-await-using]
With this release, you can't use `async`, `await` and `using` as model names any more.
Preview features promoted to General Availability [#preview-features-promoted-to-general-availability]
In this release, we are promoting a number of [Preview](/orm/more/releases#preview) features to [General Availability](/orm/more/releases#generally-available-ga).
fullTextIndex [#fulltextindex]
If you use the [full-text index](/orm/prisma-schema/data-model/indexes#full-text-indexes-mysql-and-mongodb) feature in your app, you can now remove `fullTextIndex` from the `previewFeatures` in your Prisma schema:
```prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextIndex"] // [!code --]
}
```
fullTextSearch [#fulltextsearch]
If you use the [full-text search](/v6/orm/prisma-client/queries/full-text-search) feature with **MySQL** in your app, you can now remove `fullTextSearch` from the `previewFeatures` in your Prisma schema:
```prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearch"] // [!code --]
}
```
If you are using it with **PostgreSQL**, you need to update the name of the feature flag to `fullTextSearchPostgres`:
```prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["fullTextSearchPostgres"] // [!code highlight]
}
```
# Upgrade to v7 (/docs/guides/upgrade-prisma-orm/v7)
Prisma ORM v7 introduces **breaking changes** when you upgrade from an earlier Prisma ORM version. This guide explains how this upgrade might affect your application and gives instructions on how to handle any changes.
Questions answered in this page
* What changed in Prisma v7?
* How do I upgrade safely?
* Which breaking changes affect my app?
For developers using AI Agents, we have a [migration prompt](/ai/prompts/prisma-7) that you can
add to your project for automatic migrations.
If you are using MongoDB, please note that Prisma ORM v7 does not yet support MongoDB. You should continue using Prisma ORM v6 for now. Support for MongoDB is coming soon in v7.
Update packages [#update-packages]
To upgrade to Prisma ORM v7 from an earlier version, you need to update both the `prisma` and `@prisma/client` packages:
npm
pnpm
yarn
bun
```bash
npm install @prisma/client@7
npm install -D prisma@7
```
```bash
pnpm add @prisma/client@7
pnpm add -D prisma@7
```
```bash
yarn add @prisma/client@7
yarn add --dev prisma@7
```
```bash
bun add @prisma/client@7
bun add --dev prisma@7
```
Before you upgrade, check each breaking change below to see how the upgrade might affect your application.
Breaking changes [#breaking-changes]
This section gives an overview of breaking changes in Prisma ORM v7.
Prerequisites [#prerequisites]
| | Minimum Version | Recommended |
| ---------- | --------------- | ----------- |
| Node | 20.19.0 | 22.x |
| TypeScript | 5.4.0 | 5.9.x |
ESM support [#esm-support]
Prisma ORM now ships as an ES module, the module format supported in Bun, Deno, and Node. Set the
`type` field in your `package.json` to `module`
```json
{
"type": "module",
"scripts": {...},
}
```
If you are using TypeScript, you need to configure your `tsconfig.json` to be able to consume ES modules
```json
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"target": "ES2023",
"strict": true,
"esModuleInterop": true
}
}
```
Schema changes [#schema-changes]
The older `prisma-client-js` provider will be removed in future releases of Prisma ORM. Upgrade to
the new `prisma-client` provider which uses the new Rust-free client. This will give you faster
queries, smaller bundle size, and require less system resources when deployed to your server.
Additionally, the `output` field is now **required** in the generator block. Prisma Client will no longer be generated in `node_modules` by default. You must specify a custom output path.
Before
After
```prisma
generator client {
provider = "prisma-client-js"
engineType = "binary"
}
```
```prisma
generator client {
provider = "prisma-client"
output = "./generated/prisma"
}
```
After running `npx prisma generate`, you'll need to update your imports to use the new generated path:
```ts
// Before
import { PrismaClient } from "@prisma/client";
// After
import { PrismaClient } from "./generated/prisma/client";
```
The import path depends on where you place your generated client. Adjust the path based on your `output` configuration and the location of the file you're importing from.
Additionally other fields such as `url`, `directUrl`, and `shadowDatabaseUrl` in the `datasource` block are deprecated. You can configure them in the [Prisma Config](/orm/reference/prisma-config-reference).
If you were previously using `directUrl` to run migrations then you need to pass the `directUrl` value in the `url` field of `prisma.config.ts` instead as the connection string defined in `url` is used by Prisma CLI for migrations.
```ts title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
datasource: {
url: env("DATABASE_URL"),
shadowDatabaseUrl: env("SHADOW_DATABASE_URL"),
},
});
```
Driver adapters [#driver-adapters]
The way to create a new Prisma Client has changed to require a driver adapter for all databases.
This change aligns with the move to make the main Prisma Client as lean and open as possible. For
instance, if you are using Prisma Postgres, you now need the `@prisma/adapter-pg` adapter. This also
means the signature for creating a new Prisma Client has changed slightly:
Connection pools have changed.
Driver adapters use the connection pool settings from the underlying Node.js database driver, which may differ significantly from Prisma ORM v6 defaults. For example, the `pg` driver has no connection timeout by default (`0`), while Prisma ORM v6 used a 5-second timeout.
**If you experience timeout issues after upgrading**, configure your driver adapter to match v6 behavior. See the [connection pool guide](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool#prisma-orm-v7-driver-adapter-defaults) for detailed configuration examples for each database.
Before [#before]
```ts
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient({
datasources: {
db: { url: process.env.DATABASE_URL },
},
datasourceUrl: process.env.DATABASE_URL,
});
```
After [#after]
```ts
import { PrismaClient } from "./generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
export const prisma = new PrismaClient({ adapter });
```
If you are using SQLite, you can use the `@prisma/adapter-better-sqlite3`:
```ts
import { PrismaClient } from "./generated/prisma/client";
import { PrismaBetterSqlite3 } from "@prisma/adapter-better-sqlite3";
const adapter = new PrismaBetterSqlite3({
url: process.env.DATABASE_URL || "file:./dev.db",
});
export const prisma = new PrismaClient({ adapter });
```
Prisma Accelerate [#prisma-accelerate]
If you used Prisma Accelerate (including Prisma Postgres' `prisma+postgres://` URLs) in v6, keep using the Accelerate URL with the Accelerate extension. Do **not** pass the Accelerate URL to a driver adapter—`PrismaPg` expects a direct database connection string and will fail with `prisma://` or `prisma+postgres://`.
1. Keep your Accelerate URL in `.env` (for example `DATABASE_URL="prisma://..."` or `prisma+postgres://...`).
2. You can point `prisma.config.ts` directly to that same Accelerate URL for CLI operations:
```ts title="prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: env("DATABASE_URL"),
},
});
```
* If you prefer a separate direct URL for migrations, you can still use `DIRECT_DATABASE_URL` as above—but it's optional for Accelerate users.
3. Instantiate Prisma Client with the Accelerate URL and extension (no adapter):
```ts
import { PrismaClient } from "./generated/prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";
export const prisma = new PrismaClient({
accelerateUrl: process.env.DATABASE_URL,
}).$extends(withAccelerate());
```
If you later switch away from Accelerate to direct TCP, provide the direct URL to the appropriate driver adapter (for example `PrismaPg`) instead of `accelerateUrl`.
SSL certificate validation changes [#ssl-certificate-validation-changes]
Since Prisma ORM v7 uses `node-pg` instead of the Rust-based query engine, SSL certificate defaults have changed. Previously, invalid SSL certificates were ignored. In v7, you may encounter the following error:
```bash
Error: P1010: User was denied access on the database
```
To fix this, either keep the previous behavior:
```ts
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false },
});
```
Or properly configure your database certificates using `node --use-openssl-ca` or by setting the `NODE_EXTRA_CA_CERTS` environment variable.
For more details, see [GitHub issue #28795](https://github.com/prisma/prisma/issues/28795).
Environment variables [#environment-variables]
In Prisma ORM 7.0.0, environment variables are not loaded by default. Instead developers need to
explicitly load the variables when calling the `prisma` CLI. Libraries like [`dotenv`](https://github.com/motdotla/dotenv) can be used to manage loading environment variables by reading the appropriate `.env` file.
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
For bun users, no action is required as bun will automatically load `.env` files.
Prisma config [#prisma-config]
Prisma Config is now the default place for configuring how the Prisma CLI interacts with your
database. You now configure your database URL, schema location, migration output, and custom seed
scripts.
The `prisma.config.ts` file should be placed at the **root of your project** (where your `package.json` is located).
```ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
// the main entry for your schema
schema: "prisma/schema.prisma",
// where migrations should be generated
// what script to run for "prisma db seed"
migrations: {
path: "prisma/migrations",
seed: "tsx prisma/seed.ts",
},
// The database URL
datasource: {
// Type Safe env() helper
// Does not replace the need for dotenv
url: env("DATABASE_URL"),
},
});
```
Metrics removed [#metrics-removed]
The Metrics preview feature was deprecated in [Prisma ORM 6.14.0](https://github.com/prisma/prisma/releases/tag/6.14.0) and has been removed for Prisma ORM 7.0.0.
If you need this feature, you can use the underlying driver adapter for your database, or Client Extensions to make this information available.
For example, a basic `totalQueries` counter:
```ts
const total = 0;
const prisma = new PrismaClient().$extends({
client: {
$log: (s: string) => console.log(s),
async $totalQueries() {
return total;
},
},
query: {
$allModels: {
async $allOperations({ query, args }) {
total += 1;
return query(args);
},
},
},
});
async function main() {
prisma.$log("Hello world");
const totalQueries = await prisma.$totalQueries();
console.log(totalQueries);
}
```
Mapped enum values in generated TypeScript [#mapped-enum-values-in-generated-typescript]
Reversion to Prisma 6 behavior
The mapped enum implementation that was initially planned for Prisma ORM v7 has been reverted. Mapped enum behavior now matches Prisma ORM v6 to avoid breaking changes. We plan to implement a similar feature in the future with different syntax.
In Prisma ORM v7, the generated TypeScript enum values use the **schema names**, not the mapped values. This maintains compatibility with Prisma ORM v6 behavior.
Prisma ORM v6 behavior [#prisma-orm-v6-behavior]
Given this Prisma schema:
```prisma
enum SuggestionStatus {
PENDING @map("pending")
ACCEPTED @map("accepted")
REJECTED @map("rejected")
}
```
In v6, the generated TypeScript enum was:
```ts
export const SuggestionStatus = {
PENDING: "PENDING",
ACCEPTED: "ACCEPTED",
REJECTED: "REJECTED",
} as const;
```
Prisma ORM v7 (reverted behavior) [#prisma-orm-v7-reverted-behavior]
In v7, the same schema generates the same TypeScript as v6:
```ts
export const SuggestionStatus = {
PENDING: "PENDING",
ACCEPTED: "ACCEPTED",
REJECTED: "REJECTED",
} as const;
```
This means that `SuggestionStatus.PENDING` evaluates to `"PENDING"`, not `"pending"`. The mapping is handled at the database level only.
Migration steps [#migration-steps]
No migration is required for this change. The behavior now matches Prisma ORM v6, so existing code will continue to work as expected.
Client middleware removed [#client-middleware-removed]
The client middleware API has been removed. If possible, use [Client Extensions](/orm/prisma-client/client-extensions).
```ts
// ❌ Old (removed)
prisma.$use(async (params, next) => {
// middleware logic
return next(params);
});
// ✅ New (use extensions)
const prisma = new PrismaClient().$extends({
query: {
user: {
async findMany({ args, query }) {
// extension logic
return query(args);
},
},
},
});
```
Seeding changes [#seeding-changes]
In Prisma ORM v6 and earlier, running `prisma migrate dev` or `prisma migrate reset` would automatically execute your seed script after applying migrations. This automatic seeding behavior has been removed in Prisma ORM v7.
To seed your database in v7, you must explicitly run:
npm
pnpm
yarn
bun
```bash
npx prisma db seed
```
```bash
pnpm dlx prisma db seed
```
```bash
yarn dlx prisma db seed
```
```bash
bunx --bun prisma db seed
```
Removed CLI flags [#removed-cli-flags]
The `--skip-generate` flag was removed from `prisma migrate dev` and `prisma db push`. The `--skip-seed` flag was removed from `prisma migrate dev`.
`migrate dev` and `db push` no longer run `prisma generate` automatically. You must run `prisma generate` explicitly to generate Prisma Client.
Removed db execute flags [#removed-db-execute-flags]
The `--schema` and `--url` flags have been removed from the `prisma db execute` command. Previously, you could use `--schema` to specify the path to your Prisma schema file, or `--url` to specify the database URL directly. Now, the database connection must be configured in `prisma.config.ts`.
Before (v6) [#before-v6]
```bash
# Using --schema
prisma db execute --file ./script.sql --schema prisma/schema.prisma
# Using --url
prisma db execute --file ./script.sql --url "$DATABASE_URL"
```
After (v7) [#after-v7]
Configure your database connection in `prisma.config.ts` instead:
```ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
datasource: {
url: env("DATABASE_URL"),
},
});
```
Then run the command without `--schema` or `--url`:
```bash
prisma db execute --file ./script.sql
```
Migrate diff changes [#migrate-diff-changes]
Several options have been removed from `prisma migrate diff` and replaced with new options that use `prisma.config.ts`:
| Removed Option | Replacement |
| -------------------------- | ------------------------------- |
| `--from-url` | `--from-config-datasource` |
| `--to-url` | `--to-config-datasource` |
| `--from-schema-datasource` | `--from-config-datasource` |
| `--to-schema-datasource` | `--to-config-datasource` |
| `--shadow-database-url` | Configure in `prisma.config.ts` |
Before (v6) [#before-v6-1]
```bash
prisma migrate diff \
--from-url "$DATABASE_URL" \
--to-schema schema.prisma \
--script
```
After (v7) [#after-v7-1]
Configure your database connection in `prisma.config.ts`, then use `--from-config-datasource` or `--to-config-datasource`:
```bash
prisma migrate diff \
--from-config-datasource \
--to-schema schema.prisma \
--script
```
Various environment variables have been removed [#various-environment-variables-have-been-removed]
We've removed a small selection of Prisma-specific environment variables.
* `PRISMA_CLI_QUERY_ENGINE_TYPE`
* `PRISMA_CLIENT_ENGINE_TYPE`
* `PRISMA_QUERY_ENGINE_BINARY`
* `PRISMA_QUERY_ENGINE_LIBRARY`
* `PRISMA_GENERATE_SKIP_AUTOINSTALL`
* `PRISMA_SKIP_POSTINSTALL_GENERATE`
* `PRISMA_GENERATE_IN_POSTINSTALL`
* `PRISMA_GENERATE_DATAPROXY`
* `PRISMA_GENERATE_NO_ENGINE`
* `PRISMA_CLIENT_NO_RETRY`
* `PRISMA_MIGRATE_SKIP_GENERATE`
* `PRISMA_MIGRATE_SKIP_SEED`
# API patterns (/docs/orm/core-concepts/api-patterns)
Prisma Client can be used to query your database from any server-side JavaScript or TypeScript application. This page covers common patterns for REST APIs, GraphQL servers, and fullstack frameworks.
REST APIs [#rest-apis]
When building REST APIs, use Prisma Client inside your route controllers to execute database queries.
Supported frameworks [#supported-frameworks]
* [Express](https://expressjs.com/)
* [Fastify](https://fastify.dev/)
* [hapi](https://hapi.dev/)
* [koa](https://koajs.com/)
* [NestJS](https://nestjs.com/)
* [Next.js API Routes](https://nextjs.org/)
Example routes [#example-routes]
```ts
// GET /feed - fetch published posts
app.get("/feed", async (req, res) => {
const posts = await prisma.post.findMany({
where: { published: true },
include: { author: true },
});
res.json(posts);
});
// POST /post - create a post
app.post("/post", async (req, res) => {
const { title, content, authorEmail } = req.body;
const result = await prisma.post.create({
data: {
title,
content,
author: { connect: { email: authorEmail } },
},
});
res.json(result);
});
// PUT /publish/:id - publish a post
app.put("/publish/:id", async (req, res) => {
const post = await prisma.post.update({
where: { id: Number(req.params.id) },
data: { published: true },
});
res.json(post);
});
// DELETE /post/:id - delete a post
app.delete("/post/:id", async (req, res) => {
const post = await prisma.post.delete({
where: { id: Number(req.params.id) },
});
res.json(post);
});
```
GraphQL [#graphql]
Prisma ORM works with any GraphQL library. Use Prisma Client inside your resolvers to read and write data.
Supported tools [#supported-tools]
| Library | Purpose |
| :-------------- | :------------- |
| `graphql-yoga` | HTTP server |
| `apollo-server` | HTTP server |
| `pothos` | Schema builder |
| `nexus` | Schema builder |
| `type-graphql` | Schema builder |
Framework integrations [#framework-integrations]
* [Redwood.js](https://rwsdk.com/) - Built on Prisma ORM
Prisma's role [#prismas-role]
Prisma ORM is used inside GraphQL resolvers the same way you'd use any other ORM:
* **Queries**: Read data from the database to return in the response
* **Mutations**: Write data to the database (create, update, delete)
Fullstack frameworks [#fullstack-frameworks]
Modern fullstack frameworks blur server/client boundaries. Use Prisma Client in the server-side portion of your application.
Supported frameworks [#supported-frameworks-1]
* [Next.js](https://nextjs.org/)
* [Remix](https://remix.run)
* [SvelteKit](https://svelte.dev/)
* [Nuxt](https://nuxt.com/)
* [Redwood](https://rwsdk.com/)
* [Wasp](https://wasp-lang.dev/)
Supported runtimes [#supported-runtimes]
* [Node.js](https://nodejs.org/)
* [Bun](https://bun.sh/)
* [Deno](https://deno.com/)
Next.js example [#nextjs-example]
```ts
// In getServerSideProps or API routes
export const getServerSideProps = async () => {
const feed = await prisma.post.findMany({
where: { published: true },
});
return { props: { feed } };
};
```
Example projects [#example-projects]
Find ready-to-run examples in the [`prisma-examples`](https://github.com/prisma/prisma-examples/) repository:
| Example | Type | Description |
| :------------------------------------------- | :-------- | :----------------------------- |
| [Next.js](https://pris.ly/e/orm/nextjs) | Fullstack | Next.js 15 app |
| [Express](https://pris.ly/e/ts/rest-express) | REST | Express REST API |
| [Fastify](https://pris.ly/e/ts/rest-fastify) | REST | Fastify REST API |
| [GraphQL Yoga](https://pris.ly/e/ts/graphql) | GraphQL | GraphQL server with Pothos |
| [NestJS](https://pris.ly/e/ts/rest-nestjs) | REST | NestJS REST API |
| [Remix](https://pris.ly/e/ts/remix) | Fullstack | Remix with actions and loaders |
| [SvelteKit](https://pris.ly/e/ts/sveltekit) | Fullstack | SvelteKit app |
# Data modeling (/docs/orm/core-concepts/data-modeling)
What is data modeling? [#what-is-data-modeling]
The term *data modeling* refers to the **process of defining the shape and structure of the objects in an application**. These objects are often called "application models". In relational databases (like PostgreSQL), they are stored in *tables* . When using document databases (like MongoDB), they are stored in *collections*.
Depending on the domain of your application, the models will be different. For example, if you're writing a blogging application, you might have models such as *blog*, *author*, *article*. When writing a car-sharing app, you probably have models like *driver*, *car*, *route*. Application models enable you to represent these different entities in your code by creating respective *data structures*.
When modeling data, you typically ask questions like:
* What are the main entities/concepts in my application?
* How do they relate to each other?
* What are their main characteristics/properties?
* How can they be represented with my technology stack?
Data modeling without Prisma ORM [#data-modeling-without-prisma-orm]
Data modeling typically needs to happen on (at least) two levels:
* On the **database** level
* On the **application** level (i.e., in your programming language)
The way that the application models are represented on both levels might differ due to a few reasons:
* Databases and programming languages use different data types
* Relations are represented differently in a database than in a programming language
* Databases typically have more powerful data modeling capabilities, like indexes, cascading deletes, or a variety of additional constraints (e.g. unique, not null, ...)
* Databases and programming languages have different technical constraints
Data modeling on the database level [#data-modeling-on-the-database-level]
Relational databases [#relational-databases]
In relational databases, models are represented by *tables*. For example, you might define a `users` table to store information about the users of your application. Using PostgreSQL, you'd define it as follows:
```sql
CREATE TABLE users (
user_id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR(255),
email VARCHAR(255) UNIQUE NOT NULL,
isAdmin BOOLEAN NOT NULL DEFAULT false
);
```
A visual representation of the `users` table with some random data might look as follows:
| `user_id` | `name` | `email` | `isAdmin` |
| :-------- | :------ | :---------------- | :-------- |
| `1` | `Alice` | `alice@prisma.io` | `false` |
| `2` | `Bob` | `bob@prisma.io` | `false` |
| `3` | `Sarah` | `sarah@prisma.io` | `true` |
It has the following columns:
* `user_id`: An integer that increments with every new record in the `users` table. It also represents the [primary key](https://en.wikipedia.org/wiki/Primary_key) for each record.
* `name`: A string with at most 255 characters.
* `email`: A string with at most 255 characters. Additionally, the added constraints express that no two records can have duplicate values for the `email` column, and that *every* record needs to have a value for it.
* `isAdmin`: A boolean that indicates whether the user has admin rights (default value: `false`)
MongoDB [#mongodb]
In MongoDB databases, models are represented by *collections* and contain *documents* that can have any structure:
```js
{
_id: '607ee94800bbe41f001fd568',
slug: 'prisma-loves-mongodb',
title: 'Prisma <3 MongoDB',
body: "This is my first post. Isn't MongoDB + Prisma awesome?!"
}
```
Prisma Client currently expects a consistent model and [normalized model design](https://www.mongodb.com/docs/manual/data-modeling/best-practices/#std-label-data-modeling-best-practices). This means that:
* If a model or field is not present in the Prisma schema, it is ignored
* If a field is mandatory but not present in the MongoDB dataset, you will get an error
Data modeling on the application level [#data-modeling-on-the-application-level]
In addition to creating the tables that represent the entities from your application domain, you also need to create application models in your programming language. In object-oriented languages, this is often done by creating *classes* to represent your models. Depending on the programming language, this might also be done with *interfaces* or *structs*.
There often is a strong correlation between the tables in your database and the models you define in your code. For example, to represent records from the aforementioned `users` table in your application, you might define a JavaScript (ES6) class looking similar to this:
```js
class User {
constructor(user_id, name, email, isAdmin) {
this.user_id = user_id;
this.name = name;
this.email = email;
this.isAdmin = isAdmin;
}
}
```
When using TypeScript, you might define an interface instead:
```js
interface User {
user_id: number
name: string
email: string
isAdmin: boolean
}
```
Notice how the `User` model in both cases has the same properties as the `users` table in the previous example. While it's often the case that there's a 1:1 mapping between database tables and application models, it can also happen that models are represented completely differently in the database and your application.
With this setup, you can retrieve records from the `users` table and store them as instances of your `User` type. The following example code snippet uses [`pg`](https://node-postgres.com/) as the driver for PostgreSQL and creates a `User` instance based on the above defined JavaScript class:
```js
const resultRows = await client.query("SELECT * FROM users WHERE user_id = 1");
const userData = resultRows[0];
const user = new User(userData.user_id, userData.name, userData.email, userData.isAdmin);
// user = {
// user_id: 1,
// name: "Alice",
// email: "alice@prisma.io",
// isAdmin: false
// }
```
Notice that in these examples, the application models are "dumb", meaning they don't implement any logic but their sole purpose is to carry data as *plain old JavaScript objects*.
Data modeling with ORMs [#data-modeling-with-orms]
ORMs are commonly used in object-oriented languages to make it easier for developers to work with a database. The key characteristic of an ORM is that it lets you model your application data in terms of *classes* which are mapped to *tables* in the underlying database.
The main difference compared to the approaches explained above is these classes not only carry data but also implement a substantial amount of logic. Mostly for storage, retrieval, serialization, and deserialization, but sometimes they also implement business logic that's specific to your application.
This means, you don't write SQL statements to read and write data in the database, but instead the instances of your model classes provide an API to store and retrieve data.
[Sequelize](https://sequelize.org/) is a popular ORM in the Node.js ecosystem, this is how you'd define the same `User` model from the sections before using Sequelize's modeling approach:
```js
class User extends Model {}
User.init(
{
user_id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: Sequelize.STRING(255),
email: {
type: Sequelize.STRING(255),
unique: true,
},
isAdmin: Sequelize.BOOLEAN,
},
{ sequelize, modelName: "user" },
);
```
To get an example with this `User` class to work, you still need to create the corresponding table in the database. With Sequelize, you have two ways of doing this:
* Run `User.sync()` (typically not recommended for production)
* Use [Sequelize migrations](https://sequelize.org/v5/manual/migrations.html) to change your database schema
Note that you'll never instantiate the `User` class manually (using `new User(...)`) as was shown in the previous section, but rather call *static* methods on the `User` class which then return the `User` model instances:
```js
const user = await User.findByPk(42);
```
The call to `findByPk` creates a SQL statement to retrieve the `User` record that's identified by the ID value `42`.
The resulting `user` object is an instance of Sequelize's `Model` class (because `User` inherits from `Model`). It's not a POJO (Plain Old JavaScript Object), but an object that implements additional behavior from Sequelize.
Data modeling with Prisma ORM [#data-modeling-with-prisma-orm]
Depending on which parts of Prisma ORM you want to use in your application, the data modeling flow looks slightly different. The following two sections explain the workflows for using [**only Prisma Client**](#using-only-prisma-client) and using [**Prisma Client and Prisma Migrate**](#using-prisma-client-and-prisma-migrate).
No matter which approach though, with Prisma ORM you never create application models in your programming language by manually defining classes, interfaces, or structs. Instead, the application models are defined in your [Prisma schema](/orm/prisma-schema/overview):
* **Only Prisma Client**: Application models in the Prisma schema are *generated based on the introspection of your database schema*. Data modeling happens primarily on the database-level.
* **Prisma Client and Prisma Migrate**: Data modeling happens in the Prisma schema by *manually adding application models* to it. Prisma Migrate maps these application models to tables in the underlying database (currently only supported for relational databases).
As an example, the `User` model from the previous example would be represented as follows in the Prisma schema:
```prisma
model User {
user_id Int @id @default(autoincrement())
name String?
email String @unique
isAdmin Boolean @default(false)
}
```
Once the application models are in your Prisma schema (whether they were added through introspection or manually by you), the next step typically is to generate Prisma Client which provides a programmatic and type-safe API to read and write data in the shape of your application models.
Prisma Client uses TypeScript [type aliases](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-aliases) to represent your application models in your code. For example, the `User` model would be represented as follows in the generated Prisma Client library:
```ts
export type User = {
id: number;
name: string | null;
email: string;
isAdmin: boolean;
};
```
In addition to the generated types, Prisma Client also provides a data access API that you can use once you've installed the `@prisma/client` package:
```js
import { PrismaClient } from '../prisma/generated/client'
// or
// const { PrismaClient } = require('../prisma/generated/client')
const prisma = new PrismaClient()
// use inside an `async` function to `await` the result
await prisma.user.findUnique(...)
await prisma.user.findMany(...)
await prisma.user.create(...)
await prisma.user.update(...)
await prisma.user.delete(...)
await prisma.user.upsert(...)
```
Using only Prisma Client [#using-only-prisma-client]
When using only Prisma Client and *not* using Prisma Migrate in your application, data modeling needs to happen on the database level via SQL. Once your SQL schema is ready, you use Prisma's introspection feature to add the application models to your Prisma schema. Finally, you generate Prisma Client which creates the types as well as the programmatic API for you to read and write data in your database.
Here is an overview of the main workflow:
1. Change your database schema using SQL (e.g. `CREATE TABLE`, `ALTER TABLE`, ...)
2. Run `prisma db pull` to introspect the database and add application models to the Prisma schema
3. Run `prisma generate` to update your Prisma Client API
Using Prisma Client and Prisma Migrate [#using-prisma-client-and-prisma-migrate]
When using [Prisma Migrate](/orm/prisma-migrate), you define your application model in the Prisma schema and with relational databases use the `prisma migrate` subcommand to generate plain SQL migration files, which you can edit before applying. With MongoDB, you use `prisma db push` instead which applies the changes to your database directly.
Here is an overview of the main workflow:
1. Manually change your application models in the Prisma schema (e.g. add a new model, remove an existing one, ...)
2. Run `prisma migrate dev` to create and apply a migration or run `prisma db push` to apply the changes directly (in both cases Prisma Client is automatically generated)
# Best practices (/docs/orm/more/best-practices)
Schema design and modeling [#schema-design-and-modeling]
Naming conventions [#naming-conventions]
Use **PascalCase** for model names (singular) and **camelCase** for field names. Map to legacy database naming with `@map` and `@@map`:
```prisma title="prisma/schema.prisma"
model Comment {
id Int @id @default(autoincrement())
content String @map("comment_text")
email String @map("commenter_email")
@@map("comments")
}
```
This keeps your Prisma schema readable while supporting any database naming convention.
Model relations explicitly [#model-relations-explicitly]
Always define both sides of a relation to keep your schema clear and maintainable:
```prisma title="prisma/schema.prisma"
model User {
id Int @id @default(autoincrement())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id])
authorId Int
}
```
For databases that don't enforce foreign keys (like PlanetScale), Prisma ORM emulates relations and you should manually add indexes on relation scalar fields to avoid full table scans:
```prisma title="prisma/schema.prisma"
model Comment {
postId Int
post Post @relation(fields: [postId], references: [id])
@@index([postId])
}
```
Index strategy [#index-strategy]
Index fields used in `where`, `orderBy`, and relations. Without indexes, the database can be forced to scan entire tables to find matching rows, which becomes slower as tables grow.
```prisma title="prisma/schema.prisma"
model Comment {
id Int @id @default(autoincrement())
postId Int
status String
post Post @relation(fields: [postId], references: [id])
@@index([postId])
@@index([status])
}
```
Enum vs string fields [#enum-vs-string-fields]
Enums provide type-safe, finite sets of values. You can map enum values to match your database naming:
```prisma title="prisma/schema.prisma"
enum Role {
USER @map("user")
ADMIN @map("admin")
@@map("user_role")
}
model User {
id Int @id @default(autoincrement())
role Role @default(USER)
}
```
For values that change frequently or are user-generated, `String` avoids schema changes.
Multi-file schema organization [#multi-file-schema-organization]
For large projects, use multi-file Prisma schemas (available since v6.7.0):
```
prisma/
├── schema.prisma # Main schema with generator and datasource
├── migrations/ # Migration files
├── user.prisma # User-related models
├── product.prisma # Product-related models
└── order.prisma # Order-related models
```
The `schema.prisma` file (containing the `generator` block) and `migrations/` directory must be at the same level. You can also group additional schema files under a subdirectory such as `prisma/models/`.
Query optimization [#query-optimization]
Connection pooling [#connection-pooling]
Create one global `PrismaClient` instance and reuse it throughout your application. Creating multiple instances creates multiple connection pools, which can exhaust your database's connection limit and slow down queries.
```ts title="lib/prisma.ts"
import { PrismaClient } from '../generated/prisma/client'
import { PrismaPg } from '@prisma/adapter-pg'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL
})
export const prisma = new PrismaClient({ adapter })
```
**Serverless environments:**
* Instantiate `PrismaClient` **outside** the handler function to reuse connections across warm invocations
* Consider [Prisma Postgres](/postgres) for built-in connection pooling or external poolers like PgBouncer
Preventing N+1 queries [#preventing-n1-queries]
The N+1 problem occurs when you run 1 query to fetch a list, then 1 additional query per item in that list. This creates many unnecessary round-trips to the database instead of a few efficient queries.
```ts title="n-plus-one.ts"
// ❌ Bad: N+1 queries (1 + N queries)
const users = await prisma.user.findMany()
for (const user of users) {
const posts = await prisma.post.findMany({
where: { authorId: user.id }
})
}
// ✅ Good: Single query with include
const users = await prisma.user.findMany({
include: { posts: true }
})
// ✅ Good: Batch with IN filter
const users = await prisma.user.findMany()
const posts = await prisma.post.findMany({
where: { authorId: { in: users.map(u => u.id) } }
})
```
Select only needed fields [#select-only-needed-fields]
By default, Prisma ORM returns all scalar fields. Use `select` to whitelist specific fields you want returned:
```ts title="select.ts"
const user = await prisma.user.findFirst({
select: {
id: true,
email: true,
role: true
}
})
```
Use `omit` to blacklist fields you want excluded (useful for sensitive data):
```ts title="omit.ts"
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,
omit: {
user: { secretValue: true }
}
})
```
You cannot combine `select` and `omit` in the same query.
Pagination [#pagination]
Use **offset pagination** for small datasets where jumping to arbitrary pages is needed:
```ts title="offset-pagination.ts"
const posts = await prisma.post.findMany({
skip: 40,
take: 10,
where: { email: { contains: 'prisma.io' } },
})
```
Use **cursor-based pagination** for large datasets or infinite scroll. Cursor-based pagination scales better because it uses indexed columns to find the starting position instead of traversing skipped rows:
```ts title="cursor-pagination.ts"
const posts = await prisma.post.findMany({
take: 10,
skip: 1,
cursor: {
id: lastPost.id,
},
orderBy: {
id: 'asc',
},
})
```
Batch operations [#batch-operations]
Use bulk methods when operating on multiple records:
```ts title="batch-operations.ts"
await prisma.user.createMany({
data: [
{ email: 'alice@prisma.io' },
{ email: 'bob@prisma.io' }
]
})
await prisma.post.updateMany({
where: { published: false },
data: { published: true }
})
```
Bulk operations (`createMany`, `createManyAndReturn`, `updateMany`, `updateManyAndReturn`, and `deleteMany`) [automatically run as transactions](/orm/prisma-client/queries/transactions#batch-operations), so all writes either succeed together or are rolled back if something fails.
Raw queries [#raw-queries]
Prefer Prisma ORM's query API. Use raw SQL only when you need features not supported by Prisma ORM or heavily optimized queries:
```ts title="raw-query.ts"
const email = 'user@example.com'
const users = await prisma.$queryRaw`
SELECT * FROM "User" WHERE email = ${email}
`
```
Never concatenate user input into SQL strings. Always use parameterized queries or tagged templates to prevent SQL injection.
Type safety and validation [#type-safety-and-validation]
Leverage generated types [#leverage-generated-types]
Use Prisma ORM's generated types instead of duplicating interfaces:
```ts title="generated-types.ts"
import type { User } from '../generated/prisma/client'
async function getAdminEmails(): Promise {
const admins: User[] = await prisma.user.findMany({
where: { role: 'ADMIN' }
})
return admins.map(a => a.email)
}
```
Input validation [#input-validation]
Always validate and sanitize user input before database operations:
```ts title="input-validation.ts"
import { z } from 'zod'
const createUserSchema = z.object({
email: z.string().email(),
name: z.string().min(1).max(100)
})
async function createUser(input: unknown) {
const data = createUserSchema.parse(input)
return prisma.user.create({ data })
}
```
Security [#security]
SQL injection prevention [#sql-injection-prevention]
Prisma ORM's API is safe by default. For raw queries, always use parameterized queries. String concatenation with untrusted input allows attackers to inject arbitrary SQL into your queries.
```ts title="sql-injection-prevention.ts"
// ✅ Safe: tagged template
const result = await prisma.$queryRaw`
SELECT * FROM "User" WHERE email = ${email}
`
// ✅ Safe: parameterized
const result = await prisma.$queryRawUnsafe(
'SELECT * FROM "User" WHERE email = $1',
email
)
// ❌ Unsafe: string concatenation
const query = `SELECT * FROM "User" WHERE email = '${email}'`
const result = await prisma.$queryRawUnsafe(query)
```
Sensitive data handling [#sensitive-data-handling]
Exclude sensitive fields from query results:
```ts title="sensitive-data.ts"
import { PrismaClient } from '../generated/prisma/client'
import { PrismaPg } from '@prisma/adapter-pg'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL
})
// Global exclusion
const prisma = new PrismaClient({
adapter,
omit: {
user: { secretValue: true }
}
})
// Per-query exclusion
const user = await prisma.user.findUnique({
where: { id: 1 },
omit: { secretValue: true }
})
```
Testing [#testing]
Database setup [#database-setup]
Use a dedicated test database that can be reset freely:
1. Start test database (often in Docker)
2. Apply schema via migrations
3. Seed test data
4. Run tests
5. Clean up or reset database
Unit tests with mocking [#unit-tests-with-mocking]
Mock Prisma ORM using `jest-mock-extended`:
```ts title="unit-test.ts"
import { PrismaClient } from '../generated/prisma/client'
import { mockDeep } from 'jest-mock-extended'
const prismaMock = mockDeep()
test('finds user by email', async () => {
prismaMock.user.findUnique.mockResolvedValue({
id: 1,
email: 'test@example.com',
name: 'Test User'
})
const user = await prismaMock.user.findUnique({
where: { email: 'test@example.com' }
})
expect(user).toBeDefined()
})
```
Integration tests with real database [#integration-tests-with-real-database]
Use a real database with Prisma Migrate:
```ts title="integration-test.ts"
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 })
beforeEach(async () => {
await prisma.user.create({
data: { email: 'test@example.com', name: 'Test' }
})
})
afterEach(async () => {
await prisma.user.deleteMany()
})
test('creates user', async () => {
const user = await prisma.user.create({
data: { email: 'new@example.com', name: 'New User' }
})
expect(user.email).toBe('new@example.com')
})
```
Production deployment [#production-deployment]
Migration strategies [#migration-strategies]
**Development:**
* Use `prisma migrate dev` to create and apply migrations
* Use `prisma db push` only for quick prototyping (may reset data)
**Production:**
* Use **only** `prisma migrate deploy` with committed migrations
* Never use `migrate dev` (can prompt to reset DB) or `db push` (can be destructive and locks you into a migrationless workflow)
`prisma migrate deploy` applies existing migrations in a non-interactive way, uses advisory locking to prevent concurrent runs, and is safe for production data.
Example CI/CD workflow:
```yaml title=".github/workflows/deploy.yml"
- name: Apply migrations
run: npx prisma migrate deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
```
Serverless considerations [#serverless-considerations]
For AWS Lambda, Vercel, Cloudflare Workers, or similar platforms:
1. Instantiate `PrismaClient` **outside** the handler function to reuse connections across warm invocations
2. Do **not** call `$disconnect()` at the end of each invocation (the container may be reused)
3. Consider external connection poolers (like PgBouncer) for high-concurrency workloads
```ts title="serverless-handler.ts"
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 })
export async function handler(event) {
const users = await prisma.user.findMany()
return {
statusCode: 200,
body: JSON.stringify(users)
}
}
```
Creating a new client inside the handler on every invocation risks exhausting database connections. Each concurrent function creates its own connection pool, quickly multiplying connection counts.
Next steps [#next-steps]
* [Query optimization](/query-insights)
* [Raw queries](/orm/prisma-client/using-raw-sql/raw-queries)
* [Prisma Migrate workflows](/orm/prisma-migrate/workflows/development-and-production)
# ORM releases and maturity levels (/docs/orm/more/releases)
This page explains the release process of Prisma ORM, how it's versioned and how to deal with breaking changes that might happen throughout releases.
Releases [#releases]
Prisma ORM releases typically happen every two weeks. Note that this is *not* a hard rule – releases might be postponed for internal reasons.
[Check out all the releases notes in GitHub](https://github.com/prisma/prisma/releases).
Product maturity levels [#product-maturity-levels]
A release can include products or features at different maturity levels. Maturity level describes a product or feature's completeness and what users can expect in terms of breaking changes.
> **Note**: As of version [2.13.0](https://github.com/prisma/prisma/releases/2.13.0), 'Experimental' is no longer part of the product maturity scale.
Early Access [#early-access]
If a feature or product is **Early Access**:
* We have validated a problem and are considering a solution to it but are not certain whether that solution is complete or a perfect fit.
* We want to gather more feedback and adjust the solution as necessary, knowing that users are prepared for significant breaking changes
We don't recommend using Early Access features or products in production.
Preview [#preview]
If a feature or product is a **Preview**:
* We have validated the feature or product in terms of direction and surface.
* Users can count on the feature or product and associated API to be mostly stable unless stated otherwise in the release notes and documentation.
* There are no significant known issues, although minor bugs may exist.
* We welcome feedback on these to make the solution stable as quickly as possible.
Previews are typically available behind a feature flag or require some form of opt-in (for example, by providing a `--preview-feature` flag in the CLI or [adding them to a `previewFeatures` property in the `generator` block](/orm/reference/preview-features/cli-preview-features) for Prisma Client in your Prisma schema).
We don't recommend using Preview features or products in production.
See also: [All currently available Preview features](/orm/reference/preview-features/client-preview-features).
Generally Available (GA) [#generally-available-ga]
If a feature or product is **Generally Available**:
* The solution has been tested for some time and we received enough feedback to consider it stable and ready for production use.
* There should be no bugs in 99% of cases (completely bug-free software cannot be guaranteed)
Versioning [#versioning]
Prisma ORM's release scheme adheres to Semantic Versioning ([SemVer](https://semver.org/)) starting with version `3.x.x`.
Prisma ORM and Semantic Versioning (SemVer) [#prisma-orm-and-semantic-versioning-semver]
How does SemVer versioning work? [#how-does-semver-versioning-work]
Semantic Versioning (SemVer) uses the following rules for version upgrade (quoted from the [SemVer](https://semver.org/) spec):
*Given a version number `MAJOR.MINOR.PATCH`, increment the:*
1. *`MAJOR` version when you make incompatible API changes,*
2. *`MINOR` version when you add functionality in a backward compatible manner, and*
3. *`PATCH` version when you make backward compatible bug fixes.*
How does Prisma ORM versioning follow SemVer? [#how-does-prisma-orm-versioning-follow-semver]
Beginning with version `3.x.x`, Prisma ORM adheres strictly to the [SemVer](https://semver.org/) versioning scheme.
Here is a brief overview of how Prisma ORM's follows SemVer:
* Breaking changes in stable surface (i.e. [General Availability](#generally-available-ga)) will only be introduced in new `MAJOR` releases.
* Breaking changes can still be rolled out in `MINOR` but only for opt-in Preview and Early Access features that are not active by default (e.g. via a Preview feature flag or a specific opt-in option or new CLI command).
* Opt-in breaking changes, i.e. Preview and Early Access, released in `MINOR`, will only be promoted to General Availability (no requirement for opt-in) in new `MAJOR` releases.
Given a version number `MAJOR.MINOR.PATCH`, Prisma ORM's version number is incremented as follows:
1. `MAJOR` version is incremented when major product updates **with breaking changes** are released to General Availability.
2. `MINOR` version is incremented when product updates adding backward compatible new functionality are released. Features with breaking changes may only be introduced if they are **opt-in**, i.e. Early Access and Preview.
3. `PATCH` version is incremented when functionality bugs are fixed and are always **backward compatible**.
> **Note:** Up until version `2.28.0`, Prisma ORM did not follow SemVer versioning strictly. This means that releases in the `2.MINOR.PATCH` range, `MINOR` versions may have included breaking changes. To learn more about Prisma ORM's adoption of SemVer, check out the [blog post](https://www.prisma.io/blog/prisma-adopts-semver-strictly).
# Getting started with Prisma Migrate (/docs/orm/prisma-migrate/getting-started)
Adding to a new project [#adding-to-a-new-project]
To get started with Prisma Migrate, start by adding some models to your `schema.prisma`
```prisma title="schema.prisma"
datasource db {
provider = "postgresql"
}
model User { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
name String // [!code ++]
posts Post[] // [!code ++]
}
model Post { // [!code ++]
id Int @id @default(autoincrement()) // [!code ++]
title String // [!code ++]
published Boolean @default(true) // [!code ++]
authorId Int // [!code ++]
author User @relation(fields: [authorId], references: [id]) // [!code ++]
} // [!code ++]
```
You can use [native type mapping attributes](/orm/prisma-migrate/workflows/native-database-types) in your schema to decide which exact database type to create (for example, `String` can map to `varchar(100)` or `text`).
Create an initial migration [#create-an-initial-migration]
Create an initial migration using the `prisma migrate` command:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name init
```
```bash
pnpm dlx prisma migrate dev --name init
```
```bash
yarn dlx prisma migrate dev --name init
```
```bash
bunx --bun prisma migrate dev --name init
```
This will generate a migration with the appropriate commands for your database.
```sql no-copy title="migration.sql"
CREATE TABLE "User" (
"id" SERIAL,
"name" TEXT NOT NULL,
PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Post" (
"id" SERIAL,
"title" TEXT NOT NULL,
"published" BOOLEAN NOT NULL DEFAULT true,
"authorId" INTEGER NOT NULL,
PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE
"Post"
ADD
FOREIGN KEY("authorId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
```
Your Prisma schema is now in sync with your database schema and you have initialized a migration history:
```text
migrations/
└─ 20210313140442_init/
└─ migration.sql
```
> **Note**: The folder name will be different for you. Folder naming is in the format of YYYYMMDDHHMMSS\_your\_text\_from\_name\_flag.
Additional migrations [#additional-migrations]
Now say you add additional fields to your model
```prisma title="schema.prisma"
model User {
id Int @id @default(autoincrement())
jobTitle String // [!code ++]
name String
posts Post[]
}
```
You can run `prisma migrate` again to update your migrations
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --name added_job_title
```
```bash
pnpm dlx prisma migrate dev --name added_job_title
```
```bash
yarn dlx prisma migrate dev --name added_job_title
```
```bash
bunx --bun prisma migrate dev --name added_job_title
```
```sql no-copy title="migration.sql"
-- AlterTable
ALTER TABLE
"User"
ADD
COLUMN "jobTitle" TEXT NOT NULL;
```
Your Prisma schema is once again in sync with your database schema, and your migration history contains two migrations:
```
migrations/
└─ 20210313140442_init/
└─ migration.sql
└─ 20210313140442_added_job_title/
└─ migration.sql
```
Committing to versions control [#committing-to-versions-control]
Your migration history can be [committed to version control](/orm/prisma-migrate/understanding-prisma-migrate/migration-histories#committing-the-migration-history-to-source-control) and use to [deploy changes to test environments and production](/orm/prisma-migrate/workflows/development-and-production#production-and-testing-environments).
Adding to an existing project [#adding-to-an-existing-project]
It's possible to integrate Prisma migrations to an existing project.
Introspect to create or update your Prisma schema [#introspect-to-create-or-update-your-prisma-schema]
Make sure your Prisma schema is in sync with your database schema. This should already be true if you are using a previous version of Prisma Migrate.
npm
pnpm
yarn
bun
```bash
npx prisma db pull
```
```bash
pnpm dlx prisma db pull
```
```bash
yarn dlx prisma db pull
```
```bash
bunx --bun prisma db pull
```
Create a baseline migration [#create-a-baseline-migration]
Create a baseline migration that creates an initial history of the database before using Prisma migrate. This migrations contains the data the must be maintained, which means the database cannot be reset. This tells Prisma migrate to assume that one or more migrations have **already been applied**. This prevents generated migrations from failing when they try to create tables and fields that already exist.
To create a baseline migration:
* If you already have a `prisma/migrations` folder, delete, move, rename, or archive this folder.
* Create a new `prisma/migrations` directory.
* Then create another new directory with your preferred name. What's important is to use a prefix of `0_` so that Prisma migrate applies migrations in a [lexicographic order](https://en.wikipedia.org/wiki/Lexicographic_order). You can use a different value such as the current timestamp.
* Generate a migration and save it to a file using `prisma migrate diff`:
npm
pnpm
yarn
bun
```bash
npx prisma migrate diff \
--from-empty \
--to-schema prisma/schema.prisma \
--script > prisma/migrations/0_init/migration.sql
```
```bash
pnpm dlx prisma migrate diff \
--from-empty \
--to-schema prisma/schema.prisma \
--script > prisma/migrations/0_init/migration.sql
```
```bash
yarn dlx prisma migrate diff \
--from-empty \
--to-schema prisma/schema.prisma \
--script > prisma/migrations/0_init/migration.sql
```
```bash
bunx --bun prisma migrate diff \
--from-empty \
--to-schema prisma/schema.prisma \
--script > prisma/migrations/0_init/migration.sql
```
* Review the generated migration.
Work around features not supported by Prisma Schema Language [#work-around-features-not-supported-by-prisma-schema-language]
To include [unsupported database features](/orm/prisma-migrate/workflows/unsupported-database-features) that already exist in the database, you must replace or modify the initial migration SQL:
* Open the `migration.sql` file generated in the [Create a baseline migration](#create-a-baseline-migration) section.
* Modify the generated SQL. For example:
* If the changes are minor, you can append additional custom SQL to the generated migration. The following example creates a trigger function:
```sql title="migration.sql"
/* Generated migration SQL */
CREATE OR REPLACE FUNCTION notify_on_insert() -- [!code ++]
RETURNS TRIGGER AS $$ -- [!code ++]
BEGIN -- [!code ++]
PERFORM pg_notify('new_record', NEW.id::text); -- [!code ++]
RETURN NEW; -- [!code ++]
END; -- [!code ++]
$$ LANGUAGE plpgsql; -- [!code ++]
```
* If the changes are significant, it can be easier to replace the entire migration file with the result of a database dump:
* [`mysqldump`](https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html)
* [`pg_dump`](https://www.postgresql.org/docs/12/app-pgdump.html).
When using `pg_dump` for this, you'll need to update the `search_path` as follows with this command: `SELECT pg_catalog.set_config('search_path', '', false);`, otherwise you'll run into the following error: `The underlying table for model '_prisma_migrations' does not exist.`
Note that the order of the tables matters when creating all of them at once, since foreign keys are created at the same step. Therefore, either re-order them or move constraint creation to the last step after all tables are created, so you won't face `can't create constraint` errors
Apply the initial migrations [#apply-the-initial-migrations]
To apply your initial migration(s):
* Run the following command against your database:
npm
pnpm
yarn
bun
```bash
npx prisma migrate resolve --applied 0_init
```
```bash
pnpm dlx prisma migrate resolve --applied 0_init
```
```bash
yarn dlx prisma migrate resolve --applied 0_init
```
```bash
bunx --bun prisma migrate resolve --applied 0_init
```
* Review the database schema to ensure the migration leads to the desired end-state (for example, by comparing the schema to the production database).
The new migration history and the database schema should now be in sync with your Prisma schema.
Commit the migration history and Prisma schema [#commit-the-migration-history-and-prisma-schema]
Commit the following to source control:
* The entire migration history folder
* The `schema.prisma` file
Going further [#going-further]
* Refer to the [Deploying database changes with Prisma Migrate](/orm/prisma-client/deployment/deploy-database-changes-with-prisma-migrate) guide for more on deploying migrations to production.
* Refer to the [Production Troubleshooting](/orm/prisma-migrate/workflows/patching-and-hotfixing#fixing-failed-migrations-with-migrate-diff-and-db-execute) guide to learn how to debug and resolve failed migrations in production using `prisma migrate diff`, `prisma db execute` and/ or `prisma migrate resolve`.
# Overview of Prisma Migrate (/docs/orm/prisma-migrate)
Prisma Migrate enables you to:
* Keep your database schema in sync with your [Prisma schema](/orm/prisma-schema/overview) as it evolves
* Maintain existing data in your database
Prisma Migrate generates [a history of `.sql` migration files](/orm/prisma-migrate/understanding-prisma-migrate/migration-histories), and plays a role in both [development and production](/orm/prisma-migrate/workflows/development-and-production).
Prisma Migrate can be considered a *hybrid* database schema migration tool, meaning it has both of *declarative* and *imperative* elements:
* Declarative: The data model is described in a declarative way in the [Prisma schema](/orm/prisma-schema/overview). Prisma Migrate generates SQL migration files from that data model.
* Imperative: All generated SQL migration files are fully customizable. Prisma Migrate hence provides the flexibility of an imperative migration tool by enabling you to modify what and how migrations are executed (and allows you to run custom SQL to e.g. make use of native database feature, perform data migrations, ...).
If you are prototyping, consider using the [`db push`](/orm/reference/prisma-cli-reference#db-push) command - see [Schema prototyping with `db push`](/orm/prisma-migrate/workflows/prototyping-your-schema) for examples.
See the [Prisma Migrate reference](/orm/reference/prisma-cli-reference#prisma-migrate) for detailed information about the Prisma Migrate CLI commands.
Does not apply for MongoDB
Instead of `migrate dev` and related commands, use [`db push`](/orm/prisma-migrate/workflows/prototyping-your-schema) for [MongoDB](/orm/core-concepts/supported-databases/mongodb).
# What is introspection? (/docs/orm/prisma-schema/introspection)
You can introspect your database using the Prisma CLI in order to generate the [data model](/orm/prisma-schema/data-model/models) in your [Prisma schema](/orm/prisma-schema/overview). The data model is needed to [generate Prisma Client](/orm/prisma-client/setup-and-configuration/custom-model-and-field-names).
Introspection is often used to generate an *initial* version of the data model when [adding Prisma ORM to an existing project](/prisma-orm/add-to-existing-project/postgresql).
However, it can also be [used *repeatedly* in an application](#introspection-with-an-existing-schema). This is most commonly the case when you're *not* using [Prisma Migrate](/orm/prisma-migrate) but perform schema migrations using plain SQL or another migration tool. In that case, you also need to re-introspect your database and subsequently re-generate Prisma Client to reflect the schema changes in your [Prisma Client API](/orm/prisma-client/setup-and-configuration/introduction).
What does introspection do? [#what-does-introspection-do]
Introspection has one main function: Populate your Prisma schema with a data model that reflects the current database schema.
Here's an overview of its main functions on SQL databases:
* Map *tables* in the database to [Prisma models](/orm/prisma-schema/data-model/models#defining-models)
* Map *columns* in the database to the [fields](/orm/prisma-schema/data-model/models#defining-fields) of Prisma models
* Map *indexes* in the database to [indexes](/orm/prisma-schema/data-model/models#defining-an-index) in the Prisma schema
* Map *database constraints* to [attributes](/orm/prisma-schema/data-model/models#defining-attributes) or [type modifiers](/orm/prisma-schema/data-model/models#type-modifiers) in the Prisma schema
On MongoDB, the main functions are the following:
* Map *collections* in the database to [Prisma models](/orm/prisma-schema/data-model/models#defining-models). Because a *collection* in MongoDB doesn't have a predefined structure, Prisma ORM *samples* the *documents* in the collection and derives the model structure accordingly (i.e. it maps the fields of the *document* to the [fields](/orm/prisma-schema/data-model/models#defining-fields) of the Prisma model). If *embedded types* are detected in a collection, these will be mapped to [composite types](/orm/prisma-schema/data-model/models) in the Prisma schema.
* Map *indexes* in the database to [indexes](/orm/prisma-schema/data-model/models#defining-an-index) in the Prisma schema, if the collection contains at least one document contains a field included in the index
You can learn more about how Prisma ORM maps types from the database to the types available in the Prisma schema on the respective docs page for the data source connector:
* [PostgreSQL](/orm/core-concepts/supported-databases/postgresql#prisma-to-postgresql)
* [MySQL](/orm/core-concepts/supported-databases/mysql#type-mapping-between-mysql-and-prisma-schema)
* [SQLite](/orm/core-concepts/supported-databases/sqlite#type-mappings)
* [Microsoft SQL Server](/orm/core-concepts/supported-databases/sql-server#type-mappings)
The prisma db pull command [#the-prisma-db-pull-command]
You can introspect your database using the `prisma db pull` command of the [Prisma CLI](/orm/reference/prisma-cli-reference). Note that using this command requires your [connection URL](/orm/reference/connection-urls) to be set in your Prisma config [`datasource`](/orm/reference/prisma-config-reference#datasourceurl).
Here's a high-level overview of the steps that `prisma db pull` performs internally:
1. Read the [connection URL](/orm/reference/connection-urls) from the `datasource` configuration in the Prisma config
2. Open a connection to the database
3. Introspect database schema (i.e. read tables, columns and other structures ...)
4. Transform database schema into Prisma schema data model
5. Write data model into Prisma schema or [update existing schema](#introspection-with-an-existing-schema)
Introspection workflow [#introspection-workflow]
The typical workflow for projects that are not using Prisma Migrate, but instead use plain SQL or another migration tool looks as follows:
1. Change the database schema (e.g. using plain SQL)
2. Run `prisma db pull` to update the Prisma schema
3. Run `prisma generate` to update Prisma Client
4. Use the updated Prisma Client in your application
Note that as you evolve the application, [this process can be repeated for an indefinite number of times](#introspection-with-an-existing-schema).
Rules and conventions [#rules-and-conventions]
Prisma ORM employs a number of conventions for translating a database schema into a data model in the Prisma schema:
Model, field and enum names [#model-field-and-enum-names]
Field, model and enum names (identifiers) must start with a letter and generally must only contain underscores, letters and digits. You can find the naming rules and conventions for each of these identifiers on the respective docs page:
* [Naming models](/orm/reference/prisma-schema-reference#naming-conventions)
* [Naming fields](/orm/reference/prisma-schema-reference)
* [Naming enums](/orm/reference/prisma-schema-reference)
The general rule for identifiers is that they need to adhere to this regular expression:
```
[A-Za-z][A-Za-z0-9_]*
```
Sanitization of invalid characters [#sanitization-of-invalid-characters]
**Invalid characters** are being sanitized during introspection:
* If they appear *before* a letter in an identifier, they get dropped.
* If they appear *after* the first letter, they get replaced by an underscore.
Additionally, the transformed name is mapped to the database using `@map` or `@@map` to retain the original name.
Consider the following table as an example:
```sql
CREATE TABLE "42User" (
_id SERIAL PRIMARY KEY,
_name VARCHAR(255),
two$two INTEGER
);
```
Because the leading `42` in the table name as well as the leading underscores and the `$` on the columns are forbidden in Prisma ORM, introspection adds the `@map` and `@@map` attributes so that these names adhere to Prisma ORM's naming conventions:
```prisma
model User {
id Int @id @default(autoincrement()) @map("_id")
name String? @map("_name")
two_two Int? @map("two$two")
@@map("42User")
}
```
Duplicate Identifiers after Sanitization [#duplicate-identifiers-after-sanitization]
If sanitization results in duplicate identifiers, no immediate error handling is in place. You get the error later and can manually fix it.
Consider the case of the following two tables:
```sql
CREATE TABLE "42User" (
_id SERIAL PRIMARY KEY
);
CREATE TABLE "24User" (
_id SERIAL PRIMARY KEY
);
```
This would result in the following introspection result:
```prisma
model User {
id Int @id @default(autoincrement()) @map("_id")
@@map("42User")
}
model User {
id Int @id @default(autoincrement()) @map("_id")
@@map("24User")
}
```
Trying to generate your Prisma Client with `prisma generate` you would get the following error:
npm
pnpm
yarn
bun
```bash
npx prisma generate
```
```bash
pnpm dlx prisma generate
```
```bash
yarn dlx prisma generate
```
```bash
bunx --bun prisma generate
```
```text no-copy
$ npx prisma generate
Error: Schema parsing
error: The model "User" cannot be defined because a model with that name already exists.
*/} schema.prisma:17
|
16 | }
17 | model User {
|
Validation Error Count: 1
```
In this case, you must manually change the name of one of the two generated `User` models because duplicate model names are not allowed in the Prisma schema.
Order of fields [#order-of-fields]
Introspection lists model fields in the same order as the corresponding table columns in the database.
Order of attributes [#order-of-attributes]
Introspection adds attributes in the following order (this order is mirrored by `prisma format`):
* Block level: `@@id`, `@@unique`, `@@index`, `@@map`
* Field level : `@id`, `@unique`, `@default`, `@updatedAt`, `@map`, `@relation`
Relations [#relations]
Prisma ORM translates foreign keys that are defined on your database tables into [relations](/orm/prisma-schema/data-model/relations).
One-to-one relations [#one-to-one-relations]
Prisma ORM adds a [one-to-one](/orm/prisma-schema/data-model/relations/one-to-one-relations) relation to your data model when the foreign key on a table has a `UNIQUE` constraint, e.g.:
```sql
CREATE TABLE "User" (
id SERIAL PRIMARY KEY
);
CREATE TABLE "Profile" (
id SERIAL PRIMARY KEY,
"user" integer NOT NULL UNIQUE,
FOREIGN KEY ("user") REFERENCES "User"(id)
);
```
Prisma ORM translates this into the following data model:
```prisma
model User {
id Int @id @default(autoincrement())
Profile Profile?
}
model Profile {
id Int @id @default(autoincrement())
user Int @unique
User User @relation(fields: [user], references: [id])
}
```
One-to-many relations [#one-to-many-relations]
By default, Prisma ORM adds a [one-to-many](/orm/prisma-schema/data-model/relations/one-to-many-relations) relation to your data model for a foreign key it finds in your database schema:
```sql
CREATE TABLE "User" (
id SERIAL PRIMARY KEY
);
CREATE TABLE "Post" (
id SERIAL PRIMARY KEY,
"author" integer NOT NULL,
FOREIGN KEY ("author") REFERENCES "User"(id)
);
```
These tables are transformed into the following models:
```prisma
model User {
id Int @id @default(autoincrement())
Post Post[]
}
model Post {
id Int @id @default(autoincrement())
author Int
User User @relation(fields: [author], references: [id])
}
```
Many-to-many relations [#many-to-many-relations]
[Many-to-many](/orm/prisma-schema/data-model/relations/many-to-many-relations) relations are commonly represented as [relation tables](/orm/prisma-schema/data-model/relations/many-to-many-relations#relation-table-conventions) in relational databases.
Prisma ORM supports two ways for defining many-to-many relations in the Prisma schema:
* [Implicit many-to-many relations](/orm/prisma-schema/data-model/relations/many-to-many-relations#implicit-many-to-many-relations) (Prisma ORM manages the relation table under the hood)
* [Explicit many-to-many relations](/orm/prisma-schema/data-model/relations/many-to-many-relations#explicit-many-to-many-relations) (the relation table is present as a [model](/orm/prisma-schema/data-model/models#defining-models))
*Implicit* many-to-many relations are recognized if they adhere to Prisma ORM's [conventions for relation tables](/orm/prisma-schema/data-model/relations/many-to-many-relations#relation-table-conventions). Otherwise the relation table is rendered in the Prisma schema as a model (therefore making it an *explicit* many-to-many relation).
This topic is covered extensively on the docs page about [Relations](/orm/prisma-schema/data-model/relations).
Disambiguating relations [#disambiguating-relations]
Prisma ORM generally omits the `name` argument on the [`@relation`](/orm/prisma-schema/data-model/relations#the-relation-attribute) attribute if it's not needed. Consider the `User` ↔ `Post` example from the previous section. The `@relation` attribute only has the `references` argument, `name` is omitted because it's not needed in this case:
```prisma
model Post {
id Int @id @default(autoincrement())
author Int
User User @relation(fields: [author], references: [id])
}
```
It would be needed if there were *two* foreign keys defined on the `Post` table:
```sql
CREATE TABLE "User" (
id SERIAL PRIMARY KEY
);
CREATE TABLE "Post" (
id SERIAL PRIMARY KEY,
"author" integer NOT NULL,
"favoritedBy" INTEGER,
FOREIGN KEY ("author") REFERENCES "User"(id),
FOREIGN KEY ("favoritedBy") REFERENCES "User"(id)
);
```
In this case, Prisma ORM needs to [disambiguate the relation](/orm/prisma-schema/data-model/relations#disambiguating-relations) using a dedicated relation name:
```prisma
model Post {
id Int @id @default(autoincrement())
author Int
favoritedBy Int?
User_Post_authorToUser User @relation("Post_authorToUser", fields: [author], references: [id])
User_Post_favoritedByToUser User? @relation("Post_favoritedByToUser", fields: [favoritedBy], references: [id])
}
model User {
id Int @id @default(autoincrement())
Post_Post_authorToUser Post[] @relation("Post_authorToUser")
Post_Post_favoritedByToUser Post[] @relation("Post_favoritedByToUser")
}
```
Note that you can rename the [Prisma-ORM level](/orm/prisma-schema/data-model/relations#relation-fields) relation field to anything you like so that it looks friendlier in the generated Prisma Client API.
Introspection with an existing schema [#introspection-with-an-existing-schema]
Running `prisma db pull` for relational databases with an existing Prisma Schema merges manual changes made to the schema, with changes made in the database. For MongoDB, Introspection for now is meant to be done only once for the initial data model. Running it repeatedly will lead to loss of custom changes, as the ones listed below.
Introspection for relational databases maintains the following manual changes:
* Order of `model` blocks
* Order of `enum` blocks
* Comments
* `@map` and `@@map` attributes
* `@updatedAt`
* `@default(cuid())` (`cuid()` is a Prisma-ORM level function)
* `@default(uuid())` (`uuid()` is a Prisma-ORM level function)
* Custom `@relation` names
> **Note**: Only relations between models on the database level will be picked up. This means that there **must be a foreign key set**.
The following properties of the schema are determined by the database:
* Order of fields within `model` blocks
* Order of values within `enum` blocks
> **Note**: All `enum` blocks are listed below `model` blocks.
Force overwrite [#force-overwrite]
To overwrite manual changes, and generate a schema based solely on the introspected database and ignore any existing Prisma Schema, add the `--force` flag to the `db pull` command:
npm
pnpm
yarn
bun
```bash
npx prisma db pull --force
```
```bash
pnpm dlx prisma db pull --force
```
```bash
yarn dlx prisma db pull --force
```
```bash
bunx --bun prisma db pull --force
```
Use cases include:
* You want to start from scratch with a schema generated from the underlying database
* You have an invalid schema and must use `--force` to make introspection succeed
Introspecting only a subset of your database schema [#introspecting-only-a-subset-of-your-database-schema]
Introspecting only a subset of your database schema is [not yet officially supported](https://github.com/prisma/prisma/issues/807) by Prisma ORM.
However, you can achieve this by creating a new database user that only has access to the tables which you'd like to see represented in your Prisma schema, and then perform the introspection using that user. The introspection will then only include the tables the new user has access to.
If your goal is to exclude certain models from the [Prisma Client generation](/orm/prisma-client/setup-and-configuration/introduction), you can add the [`@@ignore` attribute](/orm/reference/prisma-schema-reference) to the model definition in your Prisma schema. Ignored models are excluded from the generated Prisma Client.
Introspection warnings for unsupported features [#introspection-warnings-for-unsupported-features]
The Prisma Schema Language (PSL) can express a majority of the database features of the [target databases](/orm/reference/supported-databases) Prisma ORM supports. However, there are features and functionality the Prisma Schema Language still needs to express.
For these features, the Prisma CLI will surface detect usage of the feature in your database and return a warning. The Prisma CLI will also add a comment in the models and fields the features are in use in the Prisma schema. The warnings will also contain a workaround suggestion.
The `prisma db pull` command will surface the following unsupported features:
* [Partitioned tables](https://github.com/prisma/prisma/issues/1708)
* [PostgreSQL Row Level Security](https://github.com/prisma/prisma/issues/12735)
* [Index sort order, `NULLS FIRST` / `NULLS LAST`](https://github.com/prisma/prisma/issues/15466)
* [CockroachDB row-level TTL](https://github.com/prisma/prisma/issues/13982)
* [Comments](https://github.com/prisma/prisma/issues/8703)
* [PostgreSQL deferred constraints](https://github.com/prisma/prisma/issues/8807)
* [Check Constraints](https://github.com/prisma/prisma/issues/3388) (MySQL + PostgreSQL)
* [Exclusion Constraints](https://github.com/prisma/prisma/issues/17514)
* [MongoDB $jsonSchema](https://github.com/prisma/prisma/issues/8135)
* [Expression indexes](https://github.com/prisma/prisma/issues/2504)
You can find the list of features we intend to support on [GitHub (labeled with `topic:database-functionality`)](https://github.com/prisma/prisma/issues?q=is%3Aopen+label%3A%22topic%3A+database-functionality%22+label%3Ateam%2Fschema+sort%3Aupdated-desc+).
Workaround for introspection warnings for unsupported features [#workaround-for-introspection-warnings-for-unsupported-features]
If you are using a relational database and either one of the above features listed in the previous section:
1. Create a draft migration:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --create-only
```
```bash
pnpm dlx prisma migrate dev --create-only
```
```bash
yarn dlx prisma migrate dev --create-only
```
```bash
bunx --bun prisma migrate dev --create-only
```
2. Add the SQL that adds the feature surfaced in the warnings.
3. Apply the draft migration to your database:
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev
```
```bash
pnpm dlx prisma migrate dev
```
```bash
yarn dlx prisma migrate dev
```
```bash
bunx --bun prisma migrate dev
```
# PostgreSQL extensions (/docs/orm/prisma-schema/postgresql-extensions)
This page is about [PostgreSQL extensions](https://www.postgresql.org/docs/current/external-extensions.html) and explains how to use them with Prisma ORM.
What are PostgreSQL extensions? [#what-are-postgresql-extensions]
PostgreSQL allows you to extend your database functionality by installing and activating packages known as *extensions*. For example, the `citext` extension adds a case-insensitive string data type. Some extensions, such as `citext`, are supplied directly by PostgreSQL, while other extensions are developed externally. For more information on extensions, see [the PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-createextension.html).
To use an extension, it must first be *installed* on the local file system of your database server. You then need to *activate* the extension, which runs a script file that adds the new functionality.
Using a PostgreSQL extension with Prisma ORM [#using-a-postgresql-extension-with-prisma-orm]
Let's walk through an example of installing the `citext` extension.
1. Create an empty migration [#1-create-an-empty-migration]
Run the following command to create an empty migration that you can [customize](/orm/prisma-migrate/workflows/customizing-migrations):
npm
pnpm
yarn
bun
```bash
npx prisma migrate dev --create-only
```
```bash
pnpm dlx prisma migrate dev --create-only
```
```bash
yarn dlx prisma migrate dev --create-only
```
```bash
bunx --bun prisma migrate dev --create-only
```
2. Add a SQL statement to install the extension [#2-add-a-sql-statement-to-install-the-extension]
In the new migration file that was created in the `migrations` directory, add the following statement:
```sql
CREATE EXTENSION IF NOT EXISTS citext;
```
3. Deploy the migration [#3-deploy-the-migration]
Run the following command to deploy the migration and apply to your database:
npm
pnpm
yarn
bun
```bash
npx prisma migrate deploy
```
```bash
pnpm dlx prisma migrate deploy
```
```bash
yarn dlx prisma migrate deploy
```
```bash
bunx --bun prisma migrate deploy
```
4. Use the extension [#4-use-the-extension]
You can now use the extension in your queries with Prisma Client. If the extension has special data types that currently can't be natively represented in the Prisma schema, you can still define fields of that type on your models using the [`Unsupported`](/orm/prisma-schema/data-model/models#unsupported-types) fallback type.
# Connection URLs (/docs/orm/reference/connection-urls)
Prisma ORM needs a connection URL to be able to connect to your database, e.g. when sending queries with [Prisma Client](/orm/prisma-client/setup-and-configuration/introduction) or when changing the database schema with [Prisma Migrate](/orm/prisma-migrate).
The connection URL is provided via the `url` field of a `datasource` block in your Prisma config (or Prisma schema if on version 6). It usually consists of the following components (except for SQLite and [Prisma Postgres](/postgres)):
* **User**: The name of your database user
* **Password**: The password for your database user
* **Host**: The IP or domain name of the machine where your database server is running
* **Port**: The port on which your database server is running
* **Database name**: The name of the database you want to use
Make sure you have this information at hand when getting started with Prisma ORM. If you don't have a database server running yet, you can either use a local SQLite database file (see the [Quickstart](/prisma-orm/quickstart/sqlite)) or [setup a free PostgreSQL database with Prisma Postgres](/postgres).
Format [#format]
The format of the connection URL depends on the *database connector* you're using. Prisma ORM generally supports the standard formats for each database. You can find out more about the connection URL of your database on the dedicated docs page:
* [PostgreSQL](/orm/core-concepts/supported-databases/postgresql)
* [MySQL](/orm/core-concepts/supported-databases/mysql)
* [SQLite](/orm/core-concepts/supported-databases/sqlite)
* [MongoDB](/orm/core-concepts/supported-databases/mongodb)
* [Microsoft SQL Server](/orm/core-concepts/supported-databases/sql-server)
* [CockroachDB](/orm/core-concepts/supported-databases/postgresql#cockroachdb)
Special characters [#special-characters]
For MySQL, PostgreSQL and CockroachDB you must [percentage-encode special characters](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding) in any part of your connection URL - including passwords. For example, `p@$$w0rd` becomes `p%40%24%24w0rd`.
For Microsoft SQL Server, you must [escape special characters](/orm/core-concepts/supported-databases/sql-server#connection-details) in any part of your connection string.
Examples [#examples]
Here are examples for the connection URLs of the databases Prisma ORM supports:
Prisma Postgres [#prisma-postgres]
[Prisma Postgres](/postgres) is a managed PostgreSQL service running on unikernels. There are several ways to connect to Prisma Postgres:
* via direct TCP connections (lets you connect via any ORM or database tool)
* via pooled TCP connections (recommended for serverless and high-concurrency workloads)
* via [Prisma Accelerate](/accelerate) (only supported with Prisma ORM)
* locally
The connection string formats of these are covered below.
Direct TCP [#direct-tcp]
When you connect to Prisma Postgres via direct TCP, your connection string looks as follows:
```bash
DATABASE_URL="postgres://USER:PASSWORD@db.prisma.io:5432/?sslmode=require"
```
The `USER` and `PASSWORD` values are provided when you generate credentials for your Prisma Postgres instance in the [Prisma Console](https://console.prisma.io). Here is an example with sample values:
```bash
DATABASE_URL="postgres://2f9881cc7eef46f094ac913df34c1fb441502fe66cbe28cc48998d4e6b20336b:sk_QZ3u8fMPFfBzOID4ol-mV@db.prisma.io:5432/?sslmode=require"
```
Pooled TCP [#pooled-tcp]
When you connect to Prisma Postgres via pooled TCP, your connection string looks as follows:
```bash
DATABASE_URL="postgres://USER:PASSWORD@pooled.db.prisma.io:5432/?sslmode=require"
```
Use a pooled TCP connection string for serverless, bursty, or high-concurrency workloads. Learn more in [Connection pooling](/postgres/database/connection-pooling).
Via Prisma Accelerate (HTTP) [#via-prisma-accelerate-http]
When connecting via Prisma Accelerate, the connection string doesn't require a user/password like a conventional connection string does. Instead, authentication works via an API key:
```ts title="prisma.config.ts"
export default defineConfig({
datasource: {
url: "prisma+postgres://accelerate.prisma-data.net/?api_key=API_KEY"
},
});
```
In this snippet, `API_KEY` is a placeholder for the API key you are receiving when setting up a new Prismas Postgres instance via the [Prisma Console](https://console.prisma.io). Here is an example for what a real connection URL to Prisma Postgres may look like:
```ts title="prisma.config.ts"
export default defineConfig({
datasource: {
url: "prisma+postgres://accelerate.prisma-data.net/?api_key=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcGlfa2V5IjoiMGNkZTFlMjQtNzhiYi00NTY4LTkyM2EtNWUwOTEzZWUyNjU1IiwidGVuYW50X2lkIjoiNzEyZWRlZTc1Y2U2MDk2ZjI4NDg3YjE4NWMyYzA2OTNhNGMxNzJkMjhhOWFlNGUwZTYxNWE4NWIxZWY1YjBkMCIsImludGVybmFsX3NlY3JldCI6IjA4MzQ2Y2RlLWI5ZjktNDQ4Yy04NThmLTMxNjg4ODEzNmEzZCJ9.N1Za6q6NfInzHvRkud6Ojt_-RFg18a0601vdYWGKOrk"
},
});
```
Local Prisma Postgres [#local-prisma-postgres]
The connection string for connecting to a [local Prisma Postgres](/postgres/database/local-development) instance mirrors the structure of a remote instance via Accelerate:
```ts title="prisma.config.ts"
export default defineConfig({
datasource: {
url: "prisma+postgres://accelerate.prisma-data.net/?api_key=API_KEY"
},
});
```
However, in this case the `API_KEY` doesn't provide authentication details. Instead, it encodes information about the local Prisma Postgres instance. You can obtain a local connection string via the [`prisma dev`](/orm/reference/prisma-cli-reference#dev) command.
PostgreSQL [#postgresql]
```ts title="prisma.config.ts"
export default defineConfig({
datasource: {
url: "postgresql://janedoe:mypassword@localhost:5432/mydb?schema=sample"
},
});
```
MySQL [#mysql]
```ts title="prisma.config.ts"
export default defineConfig({
datasource: {
url: "mysql://janedoe:mypassword@localhost:3306/mydb"
},
});
```
Microsoft SQL Server [#microsoft-sql-server]
```ts title="prisma.config.ts"
export default defineConfig({
datasource: {
url: "sqlserver://localhost:1433;initial catalog=sample;user=sa;password=mypassword;"
},
});
```
SQLite [#sqlite]
```ts title="prisma.config.ts"
export default defineConfig({
datasource: {
url: "file:./dev.db"
},
});
```
CockroachDB [#cockroachdb]
```ts title="prisma.config.ts"
export default defineConfig({
datasource: {
url: "postgresql://janedoe:mypassword@localhost:26257/mydb?schema=public"
},
});
```
MongoDB [#mongodb]
*Support for MongoDB is limited to [Prisma 6](/v6/orm/reference/connection-urls#mongodb) as of now. We're working on support for MongoDB in Prisma v7*
.env [#env]
You can also provide the connection URL as an environment variable:
```prisma title="schema.prisma"
datasource db {
provider = "postgresql"
}
```
You can then either set the environment variable in your terminal or by providing a [dotenv](https://github.com/motdotla/dotenv) file named `.env`. This will automatically be picked up by the Prisma CLI.
Prisma ORM reads the connection URL from the dotenv file in the following situations:
* When it updates the schema during build time
* When it connects to the database during run time
```
DATABASE_URL=postgresql://janedoe:mypassword@localhost:5432/mydb
```
# Database Features (/docs/orm/reference/database-features)
This page gives an overview of the features which are provided by the databases that Prisma ORM supports. Additionally, it explains how each of these features can be used in Prisma ORM with pointers to further documentation.
Relational database features [#relational-database-features]
This section describes which database features exist on the relational databases that are currently supported by Prisma ORM. The **Prisma schema** column indicates how a certain feature can be represented in the [Prisma schema](/orm/prisma-schema/overview) and links to its documentation. Note that database features can be used in **Prisma Client** even though they might not yet be representable in the Prisma schema.
These features are *only* for relational databases. Supported features for NoSQL databases, like MongoDB, can [be found below](#nosql-database-features).
Constraints [#constraints]
| Constraint | Supported | Prisma schema | Prisma Client | Prisma Migrate |
| ------------- | :-------: | :--------------------------------------------------------------------------------------: | :-----------: | :------------: |
| `PRIMARY KEY` | ✔️ | [`@id` and `@@id`](/orm/prisma-schema/data-model/models#defining-an-id-field) | ✔️ | ✔️ |
| `FOREIGN KEY` | ✔️ | [Relation fields](/orm/prisma-schema/data-model/relations#relation-fields) | ✔️ | ✔️ |
| `UNIQUE` | ✔️\* | [`@unique` and `@@unique`](/orm/prisma-schema/data-model/models#defining-a-unique-field) | ✔️ | ✔️ |
| `CHECK` | ✔️† | Not yet | ✔️ | Not yet |
| `NOT NULL` | ✔️ | [`?`](/orm/prisma-schema/data-model/models#type-modifiers) | ✔️ | ✔️ |
| `DEFAULT` | ✔️ | [`@default`](/orm/prisma-schema/data-model/models#defining-a-default-value) | ✔️ | ✔️ |
| `EXCLUDE` | ✔️‡ | Not yet | ✔️ | Not yet |
> \* [Caveats apply when using the `UNIQUE` constraint with Microsoft SQL Server](/orm/core-concepts/supported-databases/sql-server#common-considerations)
> † Only supported in MySQL in [version 8 and higher](https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html).
> ‡ Only supported in PostgreSQL.
Referential Actions (Delete and Update behaviors for foreign key references) [#referential-actions-delete-and-update-behaviors-for-foreign-key-references]
| Deletion behavior | Supported | Prisma schema | Prisma Client | Prisma Migrate |
| ----------------- | :-------: | :-----------: | :-----------: | :------------: |
| `CASCADE` | ✔️ | ✔️ | ✔️ | ✔️ |
| `RESTRICT` | ✔️\* | ✔️ | ✔️ | ✔️ |
| `NO ACTION` | ✔️ | ✔️ | ✔️ | ✔️ |
| `SET DEFAULT` | ✔️ | ✔️ | ✔️ | ✔️ |
| `SET NULL` | ✔️ | ✔️ | ✔️ | ✔️ |
> \* `RESTRICT` is not supported in Microsoft SQL Server.
Indexes [#indexes]
| Index | Supported | Prisma schema | Prisma Client | Prisma Migrate |
| -------------- | :--------------------------------------: | :---------------------------------------------------------------------------------------------------------: | :-----------: | :------------: |
| `UNIQUE` | ✔️ | [`@unique` and `@@unique`](/orm/prisma-schema/data-model/models#defining-a-unique-field) | ✔️ | ✔️ |
| `USING` | PostgreSQL only | [`type`](/orm/prisma-schema/data-model/indexes#configuring-the-access-type-of-indexes-with-type-postgresql) | ✔️ | ✔️ |
| `WHERE` | ✔️ | [`where`](/orm/prisma-schema/data-model/indexes#configuring-partial-indexes-with-where) (Preview) | ✔️ | ✔️ |
| `(expression)` | ✔️ | Not yet | ✔️ | Not yet |
| `INCLUDE` | PostgreSQL and Microsoft SQL Server only | Not yet | ✔️ | Not yet |
Algorithm specified via `USING`:
| Index type (Algorithm) | Supported | Prisma schema | Prisma Client | Prisma Migrate |
| ---------------------- | :-------: | :-----------: | :-----------: | :------------: |
| B-tree | ✔️ | ✔️† | ✔️ | Not yet |
| Hash | ✔️ | ✔️† | ✔️ | Not yet |
| GiST | ✔️\* | ✔️† | ✔️\* | Not yet |
| GIN | ✔️\* | ✔️† | ✔️\* | Not yet |
| BRIN | ✔️\* | ✔️† | ✔️\* | Not yet |
| SP-GiST | ✔️\* | ✔️† | ✔️\* | Not yet |
* \* Not supported for MySQL and SQLite
* † Available with the PostgreSQL connector only in Prisma ORM versions `4.0.0` and later.
Misc [#misc]
| Feature | Supported | Prisma schema | Prisma Client | Prisma Migrate |
| --------------------------------- | :--------------------------------------: | :--------------------------------------------------------------------------------: | :-----------: | :------------: |
| Autoincrementing IDs | ✔️ | [`autoincrement()`](/orm/prisma-schema/data-model/models#defining-a-default-value) | ✔️ | ✔️ |
| Arrays | PostgreSQL only | [`[]`](/orm/prisma-schema/data-model/models#type-modifiers) | ✔️ | ✔️ |
| Enums | ✔️\*† | [`enum`](/orm/prisma-schema/data-model/models#defining-enums) | ✔️ | ✔️ |
| Native database types | ✔️ | ✔️ | ✔️ | Not yet |
| SQL Views | ✔️ | Not yet | Not yet | Not yet |
| JSON support | ✔️† | ✔️ | ✔️ | ✔️ |
| Fuzzy/Phrase full text search | ✔️‡ | Not yet | Not yet | Not yet |
| Table inheritance | PostgreSQL and Microsoft SQL Server only | Not yet | ✔️ | Not yet |
| Authorization and user management | ✔️‡ | Not yet | Not yet | Not yet |
* \* Not supported by Microsoft SQL Server
* † JSON and Enum types are supported in SQLite as of Prisma ORM 6.2.0.
* ‡ Not supported by SQLite
NoSQL database features [#nosql-database-features]
This section describes which database features exist on the NoSQL databases that are currently supported by Prisma ORM.
MongoDB [#mongodb]
The following table lists common MongoDB features and describes the level of support offered by Prisma ORM:
| Feature | Supported by Prisma ORM | Notes |
| ----------------------------------------- | :---------------------: | :---------------------------------------------------------------------------------------------: |
| Embedded documents | ✔️ | |
| Transactions | ✔️ | |
| Indexes | ✔️ with caveats | Indexes can only be introspected if the field they refer to includes at least some data. |
| Autoincrementing IDs | No | |
| Compound IDs | No | MongoDB does not support composite IDs (`@@id`) |
| Generated `ObjectId` | ✔️ | See: [Defining IDs for MongoDB](/orm/prisma-schema/data-model/models#defining-ids-in-mongodb) |
| Arrays | ✔️ | |
| Enums | ✔️ | Implemented at Prisma ORM level |
| Native database types | ✔️ | See: [Field mapping reference](/orm/reference/prisma-schema-reference#model-field-scalar-types) |
| JSON support | ✔️ | Advanced `Json` field filtering is not yet supported. |
| DBrefs | No | |
| Change streams | No | |
| Direct access to the aggregation pipeline | No | |
# Environment Variables (/docs/orm/reference/environment-variables-reference)
This document describes different environment variables and their use cases.
Prisma Client [#prisma-client]
DEBUG [#debug]
`DEBUG` is used to enable debugging output in Prisma Client.
Example setting Prisma Client level debugging output:
```bash
# enable only `prisma:client`-level debugging output
export DEBUG="prisma:client"
```
See [Debugging](/orm/prisma-client/debugging-and-troubleshooting/debugging) for more information.
NO_COLOR [#no_color]
`NO_COLOR` if [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) will activate the `colorless` setting for error formatting and strip colors from error messages.
See [Formatting via environment variables](/orm/prisma-client/setup-and-configuration/error-formatting#formatting-via-environment-variables) for more information.
Prisma Studio [#prisma-studio]
BROWSER [#browser]
`BROWSER` is for Prisma Studio to force which browser it should be open in, if not set it will open in the default browser.
```bash
BROWSER=firefox prisma studio --port 5555
```
Alternatively you can set this when starting Studio from the CLI as well:
```bash
prisma studio --browser firefox
```
See [Studio](/orm/reference/prisma-cli-reference#studio) documentation for more information.
Prisma CLI [#prisma-cli]
PRISMA_HIDE_PREVIEW_FLAG_WARNINGS [#prisma_hide_preview_flag_warnings]
`PRISMA_HIDE_PREVIEW_FLAG_WARNINGS` hides the warning message that states that a preview feature flag can be removed. It is a truthy value.
PRISMA_HIDE_UPDATE_MESSAGE [#prisma_hide_update_message]
`PRISMA_HIDE_UPDATE_MESSAGE` is used to hide the update notification message that is shown when a newer Prisma CLI version is available. It's a truthy value.
PRISMA_DISABLE_WARNINGS [#prisma_disable_warnings]
Disables all CLI warnings generated by `logger.warn`.
PRISMA_SCHEMA_DISABLE_ADVISORY_LOCK [#prisma_schema_disable_advisory_lock]
Disables the [advisory locking](/orm/prisma-migrate/workflows/development-and-production#advisory-locking) used by Prisma Migrate. Useful for certain database configurations like Percona-XtraDB-Cluster or MariaDB Galera Cluster.
Proxy environment variables [#proxy-environment-variables]
The Prisma CLI supports custom HTTP(S) proxies to download the Prisma engines. These can be helpful to use when working behind a corporate firewall. See [Using a HTTP proxy for the CLI](/orm/reference/prisma-cli-reference#using-a-http-proxy-for-the-cli) for more information.
NO_PROXY [#no_proxy]
`NO_PROXY` is a comma-separated list of hostnames or IP addresses that do not require a proxy.
```bash
NO_PROXY=myhostname.com,10.11.12.0/16,172.30.0.0/16
```
HTTP_PROXY [#http_proxy]
`HTTP_PROXY` is set with the hostname or IP address of a proxy server.
```bash
HTTP_PROXY=http://proxy.example.com
```
HTTPS_PROXY [#https_proxy]
`HTTPS_PROXY` is set with the hostname or IP address of a proxy server.
```bash
HTTPS_PROXY=https://proxy.example.com
```
# Error Reference (/docs/orm/reference/error-reference)
For more information about how to work with exceptions and error codes, see [Handling exceptions and errors](/orm/prisma-client/debugging-and-troubleshooting/handling-exceptions-and-errors).
Prisma Client error types [#prisma-client-error-types]
Prisma Client throws different kinds of errors. The following lists the exception types, and their documented data fields:
PrismaClientKnownRequestError [#prismaclientknownrequesterror]
Prisma Client throws a `PrismaClientKnownRequestError` exception if the query engine returns a known error related to the request - for example, a unique constraint violation.
| **Property** | **Description** |
| :-------------- | :--------------------------------------------------------------------------------------------------------------- |
| `code` | A Prisma-specific [error code](#error-codes). |
| `meta` | Additional information about the error - for example, the field that caused the error: `{ target: [ 'email' ] }` |
| `message` | Error message associated with [error code](#error-codes). |
| `clientVersion` | Version of Prisma Client (for example, `2.19.0`) |
PrismaClientUnknownRequestError [#prismaclientunknownrequesterror]
Prisma Client throws a `PrismaClientUnknownRequestError` exception if the query engine returns an error related to a request that does not have an error code.
| **Property** | **Description** |
| :-------------- | :-------------------------------------------------------- |
| `message` | Error message associated with [error code](#error-codes). |
| `clientVersion` | Version of Prisma Client (for example, `2.19.0`) |
PrismaClientRustPanicError [#prismaclientrustpanicerror]
Prisma Client throws a `PrismaClientRustPanicError` exception if the underlying engine crashes and exits with a non-zero exit code. In this case, Prisma Client or the whole Node process must be restarted.
| **Property** | **Description** |
| :-------------- | :-------------------------------------------------------- |
| `message` | Error message associated with [error code](#error-codes). |
| `clientVersion` | Version of Prisma Client (for example, `2.19.0`) |
PrismaClientInitializationError [#prismaclientinitializationerror]
Prisma Client throws a `PrismaClientInitializationError` exception if something goes wrong when the query engine is started and the connection to the database is created. This happens either:
* When `prisma.$connect()` is called OR
* When the first query is executed
Errors that can occur include:
* The provided credentials for the database are invalid
* There is no database server running under the provided hostname and port
* The port that the query engine HTTP server wants to bind to is already taken
* A missing or inaccessible environment variable
* The query engine binary for the current platform could not be found (`generator` block)
| **Property** | **Description** |
| :-------------- | :-------------------------------------------------------- |
| `errorCode` | A Prisma-specific error code. |
| `message` | Error message associated with [error code](#error-codes). |
| `clientVersion` | Version of Prisma Client (for example, `2.19.0`) |
PrismaClientValidationError [#prismaclientvalidationerror]
Prisma Client throws a `PrismaClientValidationError` exception if validation fails - for example:
* Missing field - for example, an empty `data: {}` property when creating a new record
* Incorrect field type provided (for example, setting a `Boolean` field to `"Hello, I like cheese and gold!"`)
| **Property** | **Description** |
| :-------------- | :----------------------------------------------- |
| `message` | Error message. |
| `clientVersion` | Version of Prisma Client (for example, `2.19.0`) |
Error codes [#error-codes]
Common [#common]
P1000 [#p1000]
"Authentication failed against database server at `{database_host}`, the provided database credentials for `{database_user}` are not valid. Please make sure to provide valid database credentials for the database server at `{database_host}`."
P1001 [#p1001]
"Can't reach database server at `{database_host}`:`{database_port}` Please make sure your database server is running at `{database_host}`:`{database_port}`."
P1002 [#p1002]
"The database server at `{database_host}`:`{database_port}` was reached but timed out. Please try again. Please make sure your database server is running at `{database_host}`:`{database_port}`. "
P1003 [#p1003]
"Database \{database\_file\_name} does not exist at \{database\_file\_path}"
"Database `{database_name}.{database_schema_name}` does not exist on the database server at `{database_host}:{database_port}`."
"Database `{database_name}` does not exist on the database server at `{database_host}:{database_port}`."
P1008 [#p1008]
"Operations timed out after `{time}`"
P1009 [#p1009]
"Database `{database_name}` already exists on the database server at `{database_host}:{database_port}`"
P1010 [#p1010]
"User `{database_user}` was denied access on the database `{database_name}`"
P1011 [#p1011]
"Error opening a TLS connection: \{message}"
P1012 [#p1012]
If you get error code P1012 after you upgrade Prisma ORM to version 4.0.0 or later, see the [version 4.0.0 upgrade guide](/guides/upgrade-prisma-orm/v4#update-schema). A schema that was valid before version 4.0.0 might be invalid in version 4.0.0 and later. The upgrade guide explains how to update your schema to make it valid.
"\{full\_error}"
Possible P1012 error messages:
* "Argument `{}` is missing."
* "Function `{}` takes {} arguments, but received {}."
* "Argument `{}` is missing in attribute `@{}`."
* "Argument `{}` is missing in data source block `{}`."
* "Argument `{}` is missing in generator block `{}`."
* "Error parsing attribute `@{}`: {}"
* "Attribute `@{}` is defined twice."
* "The model with database name `{}` could not be defined because another model with this name exists: `{}`"
* "`{}` is a reserved scalar type name and can not be used."
* "The {} `{}` cannot be defined because a {} with that name already exists."
* "Key `{}` is already defined in {}."
* "Argument `{}` is already specified as unnamed argument."
* "Argument `{}` is already specified."
* "No such argument.""
* "Field `{}` is already defined on model `{}`."
* "Field `{}` in model `{}` can't be a list. The current connector does not support lists of primitive types."
* "The index name `{}` is declared multiple times. With the current connector index names have to be globally unique."
* "Value `{}` is already defined on enum `{}`."
* "Attribute not known: `@{}`."
* "Function not known: `{}`."
* "Datasource provider not known: `{}`."
* "shadowDatabaseUrl is the same as url for datasource `{}`. Please specify a different database as shadow database."
* "The preview feature `{}` is not known. Expected one of: {}"
* "`{}` is not a valid value for {}."
* "Type `{}` is neither a built-in type, nor refers to another model, custom type, or enum."
* "Type `{}` is not a built-in type."
* "Unexpected token. Expected one of: {}"
* "Environment variable not found: {}."
* "Expected a {} value, but received {} value `{}`."
* "Expected a {} value, but failed while parsing `{}`: {}."
* "Error validating model `{}`: {}"
* "Error validating field `{}` in model `{}`: {}"
* "Error validating datasource `{datasource}`: \{message}"
* "Error validating enum `{}`: {}"
* "Error validating: {}"
P1013 [#p1013]
"The provided database string is invalid. \{details}"
P1014 [#p1014]
"The underlying \{kind} for model `{model}` does not exist."
P1015 [#p1015]
"Your Prisma schema is using features that are not supported for the version of the database. Database version: \{database\_version} Errors: \{errors}"
P1016 [#p1016]
"Your raw query had an incorrect number of parameters. Expected: `{expected}`, actual: `{actual}`."
P1017 [#p1017]
"Server has closed the connection."
Prisma Client (Query Engine) [#prisma-client-query-engine]
P2000 [#p2000]
"The provided value for the column is too long for the column's type. Column: \{column\_name}"
P2001 [#p2001]
"The record searched for in the where condition (`{model_name}.{argument_name} = {argument_value}`) does not exist"
P2002 [#p2002]
"Unique constraint failed on the \{constraint}"
P2003 [#p2003]
"Foreign key constraint failed on the field: `{field_name}`"
P2004 [#p2004]
"A constraint failed on the database: `{database_error}`"
P2005 [#p2005]
"The value `{field_value}` stored in the database for the field `{field_name}` is invalid for the field's type"
P2006 [#p2006]
"The provided value `{field_value}` for `{model_name}` field `{field_name}` is not valid"
P2007 [#p2007]
"Data validation error `{database_error}`"
P2008 [#p2008]
"Failed to parse the query `{query_parsing_error}` at `{query_position}`"
P2009 [#p2009]
"Failed to validate the query: `{query_validation_error}` at `{query_position}`"
P2010 [#p2010]
"Raw query failed. Code: `{code}`. Message: `{message}`"
P2011 [#p2011]
"Null constraint violation on the \{constraint}"
P2012 [#p2012]
"Missing a required value at `{path}`"
P2013 [#p2013]
"Missing the required argument `{argument_name}` for field `{field_name}` on `{object_name}`."
P2014 [#p2014]
"The change you are trying to make would violate the required relation '\{relation\_name}' between the `{model_a_name}` and `{model_b_name}` models."
P2015 [#p2015]
"A related record could not be found. \{details}"
P2016 [#p2016]
"Query interpretation error. \{details}"
P2017 [#p2017]
"The records for relation `{relation_name}` between the `{parent_name}` and `{child_name}` models are not connected."
P2018 [#p2018]
"The required connected records were not found. \{details}"
P2019 [#p2019]
"Input error. \{details}"
P2020 [#p2020]
"Value out of range for the type. \{details}"
P2021 [#p2021]
"The table `{table}` does not exist in the current database."
P2022 [#p2022]
"The column `{column}` does not exist in the current database."
P2023 [#p2023]
"Inconsistent column data: \{message}"
P2024 [#p2024]
"Timed out fetching a new connection from the connection pool. (More info: [http://pris.ly/d/connection-pool](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) (Current connection pool timeout: \{timeout}, connection limit: \{connection\_limit})"
In Prisma ORM v7, pool size and timeout are configured per [driver adapter](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool)—see the connection pool reference for your adapter.
P2025 [#p2025]
"An operation failed because it depends on one or more records that were required but not found. \{cause}"
P2026 [#p2026]
"The current database provider doesn't support a feature that the query used: \{feature}"
P2027 [#p2027]
"Multiple errors occurred on the database during query execution: \{errors}"
P2028 [#p2028]
"Transaction API error: \{error}"
P2029 [#p2029]
"Query parameter limit exceeded error: \{message}"
P2030 [#p2030]
"Cannot find a fulltext index to use for the search, try adding a @@fulltext(\[Fields...]) to your schema"
P2031 [#p2031]
"Prisma needs to perform transactions, which requires your MongoDB server to be run as a replica set. See details: [https://pris.ly/d/mongodb-replica-set](/orm/core-concepts/supported-databases/mongodb#replica-set-configuration)"
P2033 [#p2033]
"A number used in the query does not fit into a 64 bit signed integer. Consider using `BigInt` as field type if you're trying to store large integers"
P2034 [#p2034]
"Transaction failed due to a write conflict or a deadlock. Please retry your transaction"
P2035 [#p2035]
"Assertion violation on the database: \{database\_error}"
P2036 [#p2036]
"Error in external connector (id \{id})"
P2037 [#p2037]
"Too many database connections opened: \{message}"
Prisma Migrate (Schema Engine) [#prisma-migrate-schema-engine]
The Schema Engine was previously called Migration Engine. This change was introduced in version [5.0.0](https://github.com/prisma/prisma/releases/tag/5.0.0).
P3000 [#p3000]
"Failed to create database: \{database\_error}"
P3001 [#p3001]
"Migration possible with destructive changes and possible data loss: \{migration\_engine\_destructive\_details}"
P3002 [#p3002]
"The attempted migration was rolled back: \{database\_error}"
P3003 [#p3003]
"The format of migrations changed, the saved migrations are no longer valid. To solve this problem, please follow the steps at: [https://pris.ly/d/migrate](/orm/prisma-migrate)"
P3004 [#p3004]
"The `{database_name}` database is a system database, it should not be altered with prisma migrate. Please connect to another database."
P3005 [#p3005]
"The database schema is not empty. Read more about how to baseline an existing production database: [https://pris.ly/d/migrate-baseline](/orm/prisma-migrate/workflows/baselining)"
P3006 [#p3006]
"Migration `{migration_name}` failed to apply cleanly to the shadow database. \{error\_code}Error: \{inner\_error}"
P3007 [#p3007]
"Some of the requested preview features are not yet allowed in schema engine. Please remove them from your data model before using migrations. (blocked: \{list\_of\_blocked\_features})"
P3008 [#p3008]
"The migration `{migration_name}` is already recorded as applied in the database."
P3009 [#p3009]
"migrate found failed migrations in the target database, new migrations will not be applied. Read more about how to resolve migration issues in a production database: [https://pris.ly/d/migrate-resolve](/orm/prisma-migrate/workflows/troubleshooting) \{details}"
P3010 [#p3010]
"The name of the migration is too long. It must not be longer than 200 characters (bytes)."
P3011 [#p3011]
"Migration `{migration_name}` cannot be rolled back because it was never applied to the database. Hint: did you pass in the whole migration name? (example: "20201207184859\_initial\_migration")"
P3012 [#p3012]
"Migration `{migration_name}` cannot be rolled back because it is not in a failed state."
P3013 [#p3013]
"Datasource provider arrays are no longer supported in migrate. Please change your datasource to use a single provider. Read more at [https://pris.ly/multi-provider-deprecation](https://pris.ly/multi-provider-deprecation)"
P3014 [#p3014]
"Prisma Migrate could not create the shadow database. Please make sure the database user has permission to create databases. Read more about the shadow database (and workarounds) at [https://pris.ly/d/migrate-shadow](/orm/prisma-migrate/understanding-prisma-migrate/shadow-database).
Original error: \{error\_code} \{inner\_error}"
P3015 [#p3015]
"Could not find the migration file at \{migration\_file\_path}. Please delete the directory or restore the migration file."
P3016 [#p3016]
"The fallback method for database resets failed, meaning Migrate could not clean up the database entirely. Original error: \{error\_code} \{inner\_error}"
P3017 [#p3017]
"The migration \{migration\_name} could not be found. Please make sure that the migration exists, and that you included the whole name of the directory. (example: "20201207184859\_initial\_migration")"
P3018 [#p3018]
"A migration failed to apply. New migrations cannot be applied before the error is recovered from. Read more about how to resolve migration issues in a production database: [https://pris.ly/d/migrate-resolve](/orm/prisma-migrate/workflows/troubleshooting)"
Migration name: \{migration\_name}
Database error code: \{database\_error\_code}
Database error: \{database\_error} "
P3019 [#p3019]
"The datasource provider `{provider}` specified in your schema does not match the one specified in the migration\_lock.toml, `{expected_provider}`. Please remove your current migration directory and start a new migration history with prisma migrate dev. Read more: [https://pris.ly/d/migrate-provider-switch](/orm/prisma-migrate/workflows/troubleshooting)"
P3020 [#p3020]
"The automatic creation of shadow databases is disabled on Azure SQL. Please set up a shadow database using the `shadowDatabaseUrl` datasource attribute. Read the docs page for more details: [https://pris.ly/d/migrate-shadow](/orm/prisma-migrate/understanding-prisma-migrate/shadow-database)"
P3021 [#p3021]
"Foreign keys cannot be created on this database. Learn more how to handle this: [https://pris.ly/d/migrate-no-foreign-keys](/orm/core-concepts/supported-databases/mysql#planetscale)"
P3022 [#p3022]
"Direct execution of DDL (Data Definition Language) SQL statements is disabled on this database. Please read more here about how to handle this: [https://pris.ly/d/migrate-no-direct-ddl](/orm/core-concepts/supported-databases/mysql#planetscale)"
P3023 [#p3023]
"For the current database, `externalTables` & `externalEnums` in your prisma config must contain only fully qualified identifiers (e.g. `schema_name.table_name`)."
P3024 [#p3024]
"For the current database, `externalTables` & `externalEnums` in your prisma config must contain only simple identifiers without a schema name."
prisma db pull [#prisma-db-pull]
P4000 [#p4000]
"Introspection operation failed to produce a schema file: \{introspection\_error}"
P4001 [#p4001]
"The introspected database was empty."
P4002 [#p4002]
"The schema of the introspected database was inconsistent: \{explanation}"
{/* Error codes generated by https://github.com/mhwelander/doc-tools/blob/master/error_code_parser.py */}
Prisma Accelerate [#prisma-accelerate]
Prisma Accelerate-related errors start with `P6xxx` except for [`P5011`](/orm/reference/error-reference#p5011-too-many-requests).
P6000 (ServerError) [#p6000-servererror]
Generic error to catch all other errors.
P6001 (InvalidDataSource) [#p6001-invaliddatasource]
The URL is malformed; for instance, it does not use the `prisma://` protocol.
P6002 (Unauthorized) [#p6002-unauthorized]
The API Key in the connection string is invalid.
P6003 (PlanLimitReached) [#p6003-planlimitreached]
The included usage of the current plan has been exceeded. This can only occur on the [free plan](https://www.prisma.io/pricing).
P6004 (QueryTimeout) [#p6004-querytimeout]
The global timeout of Accelerate has been exceeded.
> Also see the [troubleshooting guide](/accelerate/more/troubleshoot#p6004-querytimeout) for more information.
P6005 (InvalidParameters) [#p6005-invalidparameters]
The user supplied invalid parameters. Currently only relevant for transaction methods. For example, setting a timeout that is too high.
P6006 (VersionNotSupported) [#p6006-versionnotsupported]
The chosen Prisma version is not compatible with Accelerate. This may occur when a user uses an unstable development version that we occasionally prune.
P6008 (ConnectionError|EngineStartError) [#p6008-connectionerrorenginestarterror]
The engine failed to start. For example, it couldn't establish a connection to the database.
> Also see the [troubleshooting guide](/accelerate/more/troubleshoot#p6008-connectionerrorenginestarterror) for more information.
P6009 (ResponseSizeLimitExceeded) [#p6009-responsesizelimitexceeded]
The global response size limit of Accelerate has been exceeded.
> Also see the [troubleshooting guide](/accelerate/more/troubleshoot#p6009-responsesizelimitexceeded) for more information.
P6010 (ProjectDisabledError) [#p6010-projectdisablederror]
Your accelerate project is disabled. Please [enable](/accelerate/getting-started#1-enable-accelerate) it again to use it.
P5011 (Too Many Requests) [#p5011-too-many-requests]
This error indicates that the request volume exceeded. Implement a back-off strategy and try again later. For assistance with expected high workloads, contact [support](/console/more/support).
# Prisma CLI reference (/docs/orm/reference/prisma-cli-reference)
This document describes the Prisma CLI commands, arguments, and options.
Commands [#commands]
version (-v) [#version--v]
The `version` command outputs information about your current `prisma` version, platform, and engine binaries.
Options [#options]
The `version` command recognizes the following options to modify its behavior:
| Option | Required | Description |
| -------- | -------- | ------------------------------------------- |
| `--json` | No | Outputs version information in JSON format. |
Examples [#examples]
Output version information [#output-version-information]
```bash
prisma version
```
```text no-copy
Environment variables loaded from .env
prisma : 2.21.0-dev.4
@prisma/client : 2.21.0-dev.4
Current platform : windows
Query Engine : query-engine 2fb8f444d9cdf7c0beee7b041194b42d7a9ce1e6 (at C:\Users\veroh\AppData\Roaming\npm\node_modules\@prisma\cli\query-engine-windows.exe)
Migration Engine : migration-engine-cli 2fb8f444d9cdf7c0beee7b041194b42d7a9ce1e6 (at C:\Users\veroh\AppData\Roaming\npm\node_modules\@prisma\cli\migration-engine-windows.exe)
Format Binary : prisma-fmt 60ba6551f29b17d7d6ce479e5733c70d9c00860e (at node_modules\@prisma\engines\prisma-fmt-windows.exe)
Default Engines Hash : 60ba6551f29b17d7d6ce479e5733c70d9c00860e
Studio : 0.365.0
```
Output version information (-v) [#output-version-information--v]
```bash
prisma -v
```
```text no-copy
Environment variables loaded from .env
prisma : 2.21.0-dev.4
@prisma/client : 2.21.0-dev.4
Current platform : windows
Query Engine : query-engine 2fb8f444d9cdf7c0beee7b041194b42d7a9ce1e6 (at C:\Users\veroh\AppData\Roaming\npm\node_modules\@prisma\cli\query-engine-windows.exe)
Migration Engine : migration-engine-cli 2fb8f444d9cdf7c0beee7b041194b42d7a9ce1e6 (at C:\Users\veroh\AppData\Roaming\npm\node_modules\@prisma\cli\migration-engine-windows.exe)
Format Binary : prisma-fmt 60ba6551f29b17d7d6ce479e5733c70d9c00860e (at node_modules\@prisma\engines\prisma-fmt-windows.exe)
Default Engines Hash : 60ba6551f29b17d7d6ce479e5733c70d9c00860e
Studio : 0.365.0
```
Output version information as JSON [#output-version-information-as-json]
```bash
prisma version --json
```
```text no-copy
Environment variables loaded from .env
{
"prisma": "2.21.0-dev.4",
"@prisma/client": "2.21.0-dev.4",
"current-platform": "windows",
"query-engine": "query-engine 60ba6551f29b17d7d6ce479e5733c70d9c00860e (at node_modules\\@prisma\\engines\\query-engine-windows.exe)",
"migration-engine": "migration-engine-cli 60ba6551f29b17d7d6ce479e5733c70d9c00860e (at node_modules\\@prisma\\engines\\migration-engine-windows.exe)",
"format-binary": "prisma-fmt 60ba6551f29b17d7d6ce479e5733c70d9c00860e (at node_modules\\@prisma\\engines\\prisma-fmt-windows.exe)",
"default-engines-hash": "60ba6551f29b17d7d6ce479e5733c70d9c00860e",
"studio": "0.365.0"
}
```
init [#init]
Bootstraps a fresh Prisma ORM project within the current directory.
The `init` command does not interpret any existing files. Instead, it creates a `prisma` directory containing a bare-bones `schema.prisma` file within your current directory.
By default, the project sets up a [local Prisma Postgres](/postgres/database/local-development) instance but you can choose a different database using the `--datasource-provider` option.
Arguments [#arguments]
| Argument | Required | Description | Default |
| ------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| `--datasource-provider` | No | Specifies the value for the `provider` field in the `datasource` block. Options are `prisma+postgres`, `sqlite`, `postgresql`, `mysql`, `sqlserver`, `mongodb` and `cockroachdb`. | `postgresql` |
| `--db` | No | Shorthand syntax for `--datasource-provider prisma+postgres`; creates a new [Prisma Postgres](/postgres) instance. Requires authentication in the [PDP Console](https://console.prisma.io). | |
| `--prompt` (or `--vibe`) | No | Scaffolds a Prisma schema based on the prompt and deploys it to a fresh Prisma Postgres instance. Requires authentication in the [PDP Console](https://console.prisma.io). | |
| `--url` | No | Define a custom `datasource` url. | |
| `--generator-provider` | No | Define the generator provider to use. | `prisma-client` |
| `--preview-feature` | No | Define the [Preview features](/orm/reference/preview-features/cli-preview-features) to use. To define multiple Preview features, you have to provide the flag multiple times for each Preview feature. See examples. | |
| `--output` | No | Specifies the [output location for the generated client](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider). | `../generated/prisma` |
| `--with-model` | No | Adds a simple `User` model to the initial Prisma schema. Available since version `5.14.0`. | |
Examples [#examples-1]
**Run `prisma init`**
```bash
prisma init
```
```text no-copy wrap
npx prisma init
Initialized Prisma in your project
prisma/
schema.prisma
prisma.config.ts
Next, choose how you want to set up your database:
CONNECT EXISTING DATABASE:
1. Configure your DATABASE_URL in `prisma.config.ts`
2. Run `npx prisma db pull` to introspect your database.
CREATE NEW DATABASE:
Local: npx prisma dev (runs Postgres locally in your terminal)
Cloud: npx create-db (creates a free Prisma Postgres database)
Then, define your models in `prisma/schema.prisma` and run `npx prisma migrate dev` to apply your schema.
Learn more: https://pris.ly/getting-started
```
Next, run the `prisma dev` command to interact with your local Prisma Postgres instance (e.g. to run migrations or execute queries).
**Run `prisma init --datasource-provider sqlite`**
```bash
prisma init --datasource-provider sqlite
```
The command output contains helpful information on how to use the generated files and begin using Prisma ORM with your project.
**Run `prisma init --db`**
```bash
prisma init --db
```
```text no-copy wrap
✓ Select an authentication method Google
Authenticating to Prisma Platform via browser.
Visit the following URL in your browser to authenticate:
https://console.prisma.io/auth/cli?state=eyJjb6ll...
Successfully authenticated as amanyoyoyo@gmail.com.
Let's set up your Prisma Postgres database!
✓ Select your region: ap-southeast-1 - Asia Pacific (Singapore)
✓ Enter a project name: My Prisma Project
✓ Success! Your Prisma Postgres database is ready ✅
We found an existing schema.prisma file in your current project directory.
--- Database URL ---
Connect Prisma ORM to your Prisma Postgres database with this URL:
--- Next steps ---
Go to https://pris.ly/ppg-init for detailed instructions.
1. Install the Postgres adapter
npm install @prisma/adapter-pg
...and add it to your Prisma Client instance:
import { PrismaClient } from "./generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
const connectionString = `${process.env.DATABASE_URL}`;
const adapter = new PrismaPg({ connectionString });
const prisma = new PrismaClient({ adapter });
2. Apply migrations
Run the following command to create and apply a migration:
npx prisma migrate dev
3. Manage your data
View and edit your data locally by running this command:
npx prisma studio
...or online in Console:
https://console.prisma.io/cmhyn0uwl0q6903foel16ff31/cmhyn143t074tyLfoezs684ag/cmhyn143t074uylfon8hfre5z/studio
4. Send queries from your app
If you already have an existing app with Prisma ORM, you can now run it and it will send queries against your newly created Prisma Postgres instance.
5. Learn more
For more info, visit the Prisma Postgres docs: https://pris.ly/ppg-docs
```
The command creates a new [Prisma Postgres](https://www.prisma.io/postgres) instance. Note that it requires you to be authenticated with the [PDP Console](https://console.prisma.io), If you run it for the first time without being authenticated, the command will open the browser for you to log into Console.
**Run `prisma init --prompt "Simple habit tracker application"`**
```bash
prisma init --prompt "Simple habit tracker application"
```
The command scaffolds a Prisma schema and deploys it to a fresh [Prisma Postgres](https://www.prisma.io/postgres) instance. Note that it requires you to be authenticated with the [PDP Console](https://console.prisma.io), If you run it for the first time without being authenticated, the command will open the browser for you to log into Console.
**Run `prisma init --preview-feature`**
```bash
prisma init --preview-feature metrics
```
```prisma
datasource db {
provider = "postgresql"
}
generator client {
provider = "prisma-client"
previewFeatures = ["metrics"]
}
```
```bash
prisma init --preview-feature view --preview-feature metrics
```
```prisma
datasource db {
provider = "postgresql"
}
generator client {
provider = "prisma-client"
previewFeatures = ["views", "metrics"]
}
```
Generated Assets [#generated-assets]
**`prisma/schema.prisma`**
An initial `schema.prisma` file to define your schema in:
```prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
}
```
**`prisma.config.ts`**
A TypeScript configuration file for Prisma that defines your datasource URL and other settings:
```typescript
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
See the [Prisma Config reference](/orm/reference/prisma-config-reference) for more details.
**`.env`**
A file to define environment variables for your project:
```bash
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#using-environment-variables
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
```
**`.gitignore`**
A file to specify what folders/files git should ignore in your project.
```bash
node_modules
# Keep environment variables out of version control
.env
/generated/prisma
```
**Run `prisma init --url mysql://user:password@localhost:3306/mydb`**
The `init` command with the `--url` argument allows you to specify a custom datasource URL during Prisma initialization, instead of relying on a placeholder database URL:
```bash
prisma init --url mysql://user:password@localhost:3306/mydb
```
Generated Assets [#generated-assets-1]
**`prisma/schema.prisma`**
A minimal `schema.prisma` file to define your schema in:
```prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
datasource db {
provider = "mysql"
}
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
```
**`prisma.config.ts`**
A TypeScript configuration file for Prisma with the custom URL:
```typescript
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
**`.env`**
A file to define environment variables for your project:
```
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#using-environment-variables
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
DATABASE_URL="mysql://user:password@localhost:3306/mydb"
```
generate [#generate]
The `generate` command generates assets like Prisma Client based on the [`generator`](/orm/prisma-schema/overview/generators) and [`data model`](/orm/prisma-schema/data-model/models) blocks defined in your `prisma/schema.prisma` file.
The `generate` command is most often used to generate Prisma Client with the `prisma-client` generator. This does the following:
1. Inspects the current directory to find a Prisma Schema to process.
2. Generates a customized Prisma Client based on your schema into the output directory specified in the generator block.
Prerequisites [#prerequisites]
To use the `generate` command, you must add a generator definition in your `schema.prisma` file. The `prisma-client` generator, used to generate Prisma Client, can be added by including the following in your `schema.prisma` file:
```prisma
generator client {
provider = "prisma-client"
output = "./generated"
}
```
Options [#options-1]
| Option | Required | Description | Default |
| ------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `--data-proxy` | No | The `generate` command will generate Prisma Client for use with [Prisma Accelerate](/accelerate) prior to Prisma 5.0.0. Mutually exclusive with `--accelerate` and `--no-engine`. | |
| `--accelerate` | No | The `generate` command will generate Prisma Client for use with [Prisma Accelerate](/accelerate). Mutually exclusive with `--data-proxy` and `--no-engine`. Available in Prisma 5.1.0 and later. | |
| `--no-engine` | No | The `generate` command will generate Prisma Client without an accompanied engine for use with [Prisma Accelerate](/accelerate). Mutually exclusive with `--data-proxy` and `--accelerate`. Available in Prisma ORM 5.2.0 and later. | |
| `--no-hints` | No | The `generate` command will generate Prisma Client without usage hints, surveys or info banners being printed to the terminal. Available in Prisma ORM 5.16.0 and later. | |
| `--allow-no-models` | No | The `generate` command will generate Prisma Client without generating any models. | |
| `--watch` | No | The `generate` command will continue to watch the `schema.prisma` file and re-generate Prisma Client on file changes. | |
**Deprecation Warning**
As of Prisma 5.2.0, `--data-proxy` and `--accelerate` are deprecated in favor of `--no-engine` as Prisma Client no longer requires an option to work with Prisma Accelerate. All options are available and work similarly, but we recommend `--no-engine` as it prevents an engine from being downloaded which will greatly impact the size of apps deployed to serverless and edge functions.
Arguments [#arguments-1]
| Argument | Required | Description | Default | |
| ------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | - |
| `--schema` | No | Specifies the path to the desired `schema.prisma` file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma`, `./prisma/schema.prisma` | |
| `--generator` | No | Specifies which generator to use to generate assets. This option may be provided multiple times to include multiple generators. By default, all generators in the target schema will be run. | | |
Examples [#examples-2]
Generate Prisma Client using the default schema.prisma path [#generate-prisma-client-using-the-default-schemaprisma-path]
```bash
prisma generate
```
```text no-copy
✔ Generated Prisma Client to ./node_modules/.prisma/client in 61ms
You can now start using Prisma Client in your code:
import { PrismaClient } from '../prisma/generated/client'
// or const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
Explore the full API: https://pris.ly/d/client
```
Generate Prisma Client using a non-default schema.prisma path [#generate-prisma-client-using-a-non-default-schemaprisma-path]
```bash
prisma generate --schema=./alternative/schema.prisma
```
Continue watching the schema.prisma file for changes to automatically re-generate Prisma Client [#continue-watching-the-schemaprisma-file-for-changes-to-automatically-re-generate-prisma-client]
```bash
prisma generate --watch
```
```text no-copy
Watching... /home/prismauser/prisma/prisma-play/prisma/schema.prisma
✔ Generated Prisma Client to ./node_modules/.prisma/client in 45ms
```
Run the generate command with only a specific generator [#run-the-generate-command-with-only-a-specific-generator]
```bash
prisma generate --generator client
```
Run the generate command with multiple specific generators [#run-the-generate-command-with-multiple-specific-generators]
```bash
prisma generate --generator client --generator zod_schemas
```
Generated Assets [#generated-assets-2]
The `prisma-client` generator creates a customized client for working with your database in a custom output directory specified by the `output` field - you can [customize the output folder](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider).
validate [#validate]
Validates the [Prisma Schema Language](/orm/prisma-schema/overview) of the Prisma schema file.
Arguments [#arguments-2]
| Argument | Required | Description | Default |
| ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `--schema` | No | Specifies the path to the desired `schema.prisma` file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma`, `./prisma/schema.prisma` |
Examples [#examples-3]
Validate a schema without errors [#validate-a-schema-without-errors]
```bash
prisma validate
```
```text no-copy
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
The schema at /absolute/path/prisma/schema.prisma is valid 🚀
```
Validate a schema with validation errors [#validate-a-schema-with-validation-errors]
```bash
prisma validate
```
```text no-copy
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Error: Schema validation error - Error (query-engine-node-api library)
Error code: P1012
error: The preview feature "unknownFeatureFlag" is not known. Expected one of: [...]
*/} schema.prisma:3
|
2 | provider = "prisma-client"
3 | previewFeatures = ["unknownFeatureFlag"]
|
Validation Error Count: 1
[Context: getDmmf]
Prisma CLI Version : 4.5.0
```
format [#format]
Formats the Prisma schema file, which includes validating, formatting, and persisting the schema.
Arguments [#arguments-3]
| Argument | Required | Description | Default |
| ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `--schema` | No | Specifies the path to the desired `schema.prisma` file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma`, `./prisma/schema.prisma` |
| `--check` | No | Fails if any files are unformatted. This can be used in CI to detect if the schema is formatted correctly | |
Examples [#examples-4]
Validate a schema without errors [#validate-a-schema-without-errors-1]
```bash
prisma format
```
```text no-copy
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Formatted prisma/schema.prisma in 116ms �
```
Formatting a schema with validation errors [#formatting-a-schema-with-validation-errors]
```bash
prisma format
```
```text no-copy
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Error: Schema validation error - Error (query-engine-node-api library)
Error code: P1012
error: The preview feature "unknownFeatureFlag" is not known. Expected one of: [...]
*/} schema.prisma:3
|
2 | provider = "prisma-client"
3 | previewFeatures = ["unknownFeatureFlag"]
|
Validation Error Count: 1
[Context: getDmmf]
Prisma CLI Version : 4.5.0
```
debug [#debug]
Prints information for debugging and bug reports.
This is available from version 5.6.0 and newer.
Arguments [#arguments-4]
| Argument | Required | Description | Default |
| ---------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `--schema` | No | Specifies the path to the desired `schema.prisma` file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma`, `./prisma/schema.prisma` |
| `--help` / `--h` | No | Displays the help message | |
Example [#example]
```bash
prisma debug
```
```text no-copy
-- Prisma schema --
Path: /prisma/schema.prisma
-- Local cache directory for engines files --
Path: /.cache/prisma
-- Environment variables --
When not set, the line is dimmed and no value is displayed.
When set, the line is bold and the value is inside the `` backticks.
For general debugging
- CI:
- DEBUG:
- NODE_ENV:
- RUST_LOG:
- RUST_BACKTRACE:
- NO_COLOR:
- TERM: `xterm-256color`
- NODE_TLS_REJECT_UNAUTHORIZED:
- NO_PROXY:
- http_proxy:
- HTTP_PROXY:
- https_proxy:
- HTTPS_PROXY:
For more information see our [environment variable documentation](/orm/reference/environment-variables-reference)
For hiding messages
- PRISMA_DISABLE_WARNINGS:
- PRISMA_HIDE_PREVIEW_FLAG_WARNINGS:
- PRISMA_HIDE_UPDATE_MESSAGE:
For downloading engines
- PRISMA_ENGINES_MIRROR:
- PRISMA_BINARIES_MIRROR (deprecated):
- PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING:
- BINARY_DOWNLOAD_VERSION:
For configuring the Query Engine Type
- PRISMA_CLI_QUERY_ENGINE_TYPE: (Not supported in Prisma ORM v7)
- PRISMA_CLIENT_ENGINE_TYPE: (Not supported in Prisma ORM v7)
For custom engines
- PRISMA_QUERY_ENGINE_BINARY: (Not supported in Prisma ORM v7)
- PRISMA_QUERY_ENGINE_LIBRARY: (Not supported in Prisma ORM v7)
- PRISMA_SCHEMA_ENGINE_BINARY:
- PRISMA_MIGRATION_ENGINE_BINARY:
For the "postinstall" npm hook
- PRISMA_GENERATE_SKIP_AUTOINSTALL: (Not supported in Prisma ORM v7)
- PRISMA_SKIP_POSTINSTALL_GENERATE: (Not supported in Prisma ORM v7)
- PRISMA_GENERATE_IN_POSTINSTALL: (Not supported in Prisma ORM v7)
For "prisma generate"
- PRISMA_GENERATE_DATAPROXY: (Not supported in Prisma ORM v7)
- PRISMA_GENERATE_NO_ENGINE: (Not supported in Prisma ORM v7)
For Prisma Client
- PRISMA_SHOW_ALL_TRACES:
- PRISMA_CLIENT_NO_RETRY (Binary engine only): (Not supported in Prisma ORM v7)
For Prisma Migrate
- PRISMA_SCHEMA_DISABLE_ADVISORY_LOCK:
- PRISMA_MIGRATE_SKIP_GENERATE: (Not supported in Prisma ORM v7)
- PRISMA_MIGRATE_SKIP_SEED: (Not supported in Prisma ORM v7)
For Prisma Studio
- BROWSER:
-- Terminal is interactive? --
true
-- CI detected? --
false
```
If you're using an older version of Prisma, you can use this command by running:
npm
pnpm
yarn
bun
```bash
npx prisma@latest debug
```
```bash
pnpm dlx prisma@latest debug
```
```bash
yarn dlx prisma@latest debug
```
```bash
bunx --bun prisma@latest debug
```
dev [#dev]
The `dev` command starts a [local Prisma Postgres](/postgres/database/local-development) database that you can run Prisma ORM commands against. It is useful for development and testing purposes and also allows you to switch to [Prisma Postgres](/postgres) in production easily.
Arguments [#arguments-5]
| Argument | Required | Description | Default |
| --------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
| `--name` (or `-n`) | No | Enables targeting a specific database instance. [Learn more](/postgres/database/local-development#using-different-local-prisma-postgres-instances). | `default` |
| `--port` (or `-p`) | No | Main port number the local Prisma Postgres HTTP server will listen on. | `51213` |
| `--db-port` (or `-P`) | No | Port number the local Prisma Postgres database server will listen on. | `51214` |
| `--shadow-db-port` | No | Port number the shadow database server will listen on. | `51215` |
| `--detach` (or `-d`) | No | Run the server in the background. | `false` |
| `--debug` | No | Enable debug logging. | `false` |
Examples [#examples-5]
**Run `prisma dev`**
```bash
prisma dev
```
```bash no-copy wrap
$ npx prisma dev
Fetching latest updates for this subcommand...
✔ Great Success! 😉👍
Your prisma dev server default is ready and listening on ports 63567-63569.
╭──────────────────────────────╮
│[q]uit [h]ttp url [t]cp urls│
╰──────────────────────────────╯
```
**Run `prisma dev` with a specific name**
npm
pnpm
yarn
bun
```bash
npx prisma dev --name="mydbname"
```
```bash
pnpm dlx prisma dev --name="mydbname"
```
```bash
yarn dlx prisma dev --name="mydbname"
```
```bash
bunx --bun prisma dev --name="mydbname"
```
This creates a named instance called `mydbname` that you can later start, stop, or manage using the instance management commands.
**Run `prisma dev` in detached mode**
npm
pnpm
yarn
bun
```bash
npx prisma dev --detach
```
```bash
pnpm dlx prisma dev --detach
```
```bash
yarn dlx prisma dev --detach
```
```bash
bunx --bun prisma dev --detach
```
This runs the server in the background, freeing up your terminal for other commands. Use `prisma dev ls` to see running servers and `prisma dev stop` to stop them.
dev start [#dev-start]
Starts existing [local Prisma Postgres](/postgres/database/local-development) instances in the background.
This command only works with instances that already exist.
npm
pnpm
yarn
bun
```bash
npx prisma dev start
```
```bash
pnpm dlx prisma dev start
```
```bash
yarn dlx prisma dev start
```
```bash
bunx --bun prisma dev start
```
`` is a placeholder for a glob pattern to specify which local Prisma Postgres instances should be started, for example:
npm
pnpm
yarn
bun
```bash
npx prisma dev start mydb # starts a DB called `mydb` in the background (only if it already exists)
```
```bash
pnpm dlx prisma dev start mydb # starts a DB called `mydb` in the background (only if it already exists)
```
```bash
yarn dlx prisma dev start mydb # starts a DB called `mydb` in the background (only if it already exists)
```
```bash
bunx --bun prisma dev start mydb # starts a DB called `mydb` in the background (only if it already exists)
```
To start all databases that begin with `mydb` (e.g. `mydb-dev` and `mydb-prod`), you can use a glob:
npm
pnpm
yarn
bun
```bash
npx prisma dev start mydb* # starts all existing DBs starting with `mydb`
```
```bash
pnpm dlx prisma dev start mydb* # starts all existing DBs starting with `mydb`
```
```bash
yarn dlx prisma dev start mydb* # starts all existing DBs starting with `mydb`
```
```bash
bunx --bun prisma dev start mydb* # starts all existing DBs starting with `mydb`
```
This enables background instance management outside of the VS Code extension.
dev ls [#dev-ls]
Lists all available [local Prisma Postgres](/postgres/database/local-development) instances:
npm
pnpm
yarn
bun
```bash
npx prisma dev ls
```
```bash
pnpm dlx prisma dev ls
```
```bash
yarn dlx prisma dev ls
```
```bash
bunx --bun prisma dev ls
```
This command shows all instances on your system with their current status and configuration.
dev stop [#dev-stop]
Stops one or more [local Prisma Postgres](/postgres/database/local-development) databases:
npm
pnpm
yarn
bun
```bash
npx prisma dev stop
```
```bash
pnpm dlx prisma dev stop
```
```bash
yarn dlx prisma dev stop
```
```bash
bunx --bun prisma dev stop
```
`` is a placeholder for a glob pattern to specify which local Prisma Postgres instances should be stopped, for example:
npm
pnpm
yarn
bun
```bash
npx prisma dev stop mydb # stops a DB called `mydb`
```
```bash
pnpm dlx prisma dev stop mydb # stops a DB called `mydb`
```
```bash
yarn dlx prisma dev stop mydb # stops a DB called `mydb`
```
```bash
bunx --bun prisma dev stop mydb # stops a DB called `mydb`
```
To stop all databases that begin with `mydb` (e.g. `mydb-dev` and `mydb-prod`), you can use a glob:
npm
pnpm
yarn
bun
```bash
npx prisma dev stop mydb* # stops all DBs starting with `mydb`
```
```bash
pnpm dlx prisma dev stop mydb* # stops all DBs starting with `mydb`
```
```bash
yarn dlx prisma dev stop mydb* # stops all DBs starting with `mydb`
```
```bash
bunx --bun prisma dev stop mydb* # stops all DBs starting with `mydb`
```
The `stop` command is interactive and includes safety prompts to prevent accidental operations.
dev rm [#dev-rm]
Removes the data of one or more [local Prisma Postgres](/postgres/database/local-development) databases from your file system:
npm
pnpm
yarn
bun
```bash
npx prisma dev rm
```
```bash
pnpm dlx prisma dev rm
```
```bash
yarn dlx prisma dev rm
```
```bash
bunx --bun prisma dev rm
```
`` is a placeholder for a glob pattern to specify which local Prisma Postgres instances should be removed, for example:
npm
pnpm
yarn
bun
```bash
npx prisma dev rm mydb # removes a DB called `mydb`
```
```bash
pnpm dlx prisma dev rm mydb # removes a DB called `mydb`
```
```bash
yarn dlx prisma dev rm mydb # removes a DB called `mydb`
```
```bash
bunx --bun prisma dev rm mydb # removes a DB called `mydb`
```
To remove all databases that begin with `mydb` (e.g. `mydb-dev` and `mydb-prod`), you can use a glob:
npm
pnpm
yarn
bun
```bash
npx prisma dev rm mydb* # removes all DBs starting with `mydb`
```
```bash
pnpm dlx prisma dev rm mydb* # removes all DBs starting with `mydb`
```
```bash
yarn dlx prisma dev rm mydb* # removes all DBs starting with `mydb`
```
```bash
bunx --bun prisma dev rm mydb* # removes all DBs starting with `mydb`
```
Arguments [#arguments-6]
| Argument | Required | Description | Default |
| --------- | -------- | ------------------------------------------------------------------------------------------------------------------ | ------- |
| `--force` | No | Stops any running servers before removing them. Without this flag, the command will fail if any server is running. | `false` |
The `rm` command is interactive and includes safety prompts to prevent accidental data loss.
db [#db]
db pull [#db-pull]
The `db pull` command connects to your database and adds Prisma models to your Prisma schema that reflect the current database schema.
**Warning**: The command will overwrite the current `schema.prisma` file with the new schema. Some manual changes or customization can be lost. Be sure to back up your current `schema.prisma` file (or commit your current state to version control to be able to revert any changes) before running `db pull` if it contains important modifications.
Introspection with the `db pull` command on the [MongoDB connector](/orm/core-concepts/supported-databases/mongodb) samples the data instead of reading a schema.
Prerequisites [#prerequisites-1]
Before using the `db pull` command, you must configure your database connection in your `prisma.config.ts` file.
For example:
```prisma title="schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "sqlite"
}
```
```typescript title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Options [#options-2]
| Option | Required | Description | Default |
| --------- | -------- | --------------------------------------------------------------------------------------------------------------------- | ------- |
| `--force` | No | Force overwrite of manual changes made to schema. The generated schema will be based on the introspected schema only. | |
| `--print` | No | Prints the created `schema.prisma` to the screen instead of writing it to the filesystem. | |
Arguments [#arguments-7]
| Argument | Required | Description | Default |
| ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `--schema` | No | Specifies the path to the desired `schema.prisma` file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma`, `./prisma/schema.prisma` |
Examples [#examples-6]
Analyze the database and write its schema to the schema.prisma file [#analyze-the-database-and-write-its-schema-to-the-schemaprisma-file]
```bash
prisma db pull
```
```text no-copy
Introspecting based on datasource defined in schema.prisma …
✔ Introspected 2 models and wrote them into schema.prisma in 38ms
Run prisma generate to generate Prisma Client.
```
Specify an alternative schema.prisma file to read and write to [#specify-an-alternative-schemaprisma-file-to-read-and-write-to]
```bash
prisma db pull --schema=./alternative/schema.prisma
```
```text no-copy
Introspecting based on datasource defined in alternative/schema.prisma …
✔ Introspected 2 models and wrote them into alternative/schema.prisma in 60ms
Run prisma generate to generate Prisma Client.
```
Display the generated schema.prisma file instead of writing it to the filesystem [#display-the-generated-schemaprisma-file-instead-of-writing-it-to-the-filesystem]
```bash
prisma db pull --print
```
```prisma no-copy
generator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "sqlite"
url = "file:./hello-prisma.db"
}
model User {
email String @unique
name String?
user_id Int @id @default(autoincrement())
post Post[]
profile Profile[]
}
model Post {
content String?
post_id Int @id @default(autoincrement())
title String
author User? @relation(fields: [author_id], references: [user_id])
author_id Int?
}
model Profile {
bio String?
profile_id Int @id @default(autoincrement())
user User @relation(fields: [user_id], references: [user_id])
user_id Int @unique
}
```
db push [#db-push]
The `db push` command pushes the state of your Prisma schema to the database without using migrations. It creates the database if the database does not exist.
This command is a good choice when you do not need to version schema changes, such as during prototyping and local development.
See also:
* [Conceptual overview of `db push` and when to use it over Prisma Migrate](/orm/prisma-migrate/workflows/prototyping-your-schema)
* [Schema prototyping with `db push`](/orm/prisma-migrate/workflows/prototyping-your-schema)
Prerequisites [#prerequisites-2]
Before using the `db push` command, you must configure your database connection in your `prisma.config.ts` file.
For example:
```prisma title="schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "sqlite"
}
```
```typescript title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Options [#options-3]
| Options | Required | Description |
| :------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------- |
| `--force-reset` | No | Resets the database and then updates the schema - useful if you need to start from scratch due to unexecutable migrations. |
| `--accept-data-loss` | No | Ignore data loss warnings. This option is required if as a result of making the schema changes, data may be lost. |
| `--help` / `--h` | No | Displays the help message |
The `--skip-generate` flag was removed in Prisma v7. `db push` no longer runs `prisma generate` automatically. Run it explicitly if needed.
Arguments [#arguments-8]
| Argument | Required | Description | Default |
| :--------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------- |
| `--schema` | No | Specifies the path to the desired schema.prisma file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma` `./prisma/schema.prisma` |
Examples [#examples-7]
Push the schema:
```bash
prisma db push
```
Push the schema, accepting data loss:
```bash
prisma db push --accept-data-loss
```
Push the schema with a custom schema location:
```bash
prisma db push --schema=/tmp/schema.prisma
```
db seed [#db-seed]
`db seed` changed from Preview to Generally Available (GA) in 3.0.1.
See [Seeding your database](/orm/prisma-migrate/workflows/seeding)
Options [#options-4]
| Options | Required | Description |
| :--------------- | :------- | :-------------------------------------------------------- |
| `--help` / `--h` | No | Displays the help message |
| `--` | No | Allows the use of custom arguments defined in a seed file |
The `--` argument/ [delimiter](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02)/ double-dash is available from version 4.15.0 or later.
Examples [#examples-8]
```bash
prisma db seed
```
db execute [#db-execute]
The `db execute` command is Generally Available in versions 3.13.0 and later. If you're using a version between 3.9.0 and 3.13.0, it is available behind a `--preview-feature` CLI flag.
This command is currently not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb).
This command applies a SQL script to the database without interacting with the Prisma migrations table. The datasource URL configuration is read from the Prisma config file (e.g., `prisma.config.ts`).
The output of the command is connector-specific, and is not meant for returning data, but only to report success or failure.
See also:
* [Migration troubleshooting in production](/orm/prisma-migrate/workflows/patching-and-hotfixing#fixing-failed-migrations-with-migrate-diff-and-db-execute)
Prerequisites [#prerequisites-3]
Before using the `db execute` command, you must configure your database connection in your `prisma.config.ts` file.
For example:
```prisma title="schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "sqlite"
}
```
This how your `prisma.config.ts` file should look like:
```typescript title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Options [#options-5]
| Options | Required | Description |
| :--------- | :------- | :-------------------------------------------------------------------- |
| `--file` | Yes\* | Path to a file. The content will be sent as the script to be executed |
| `--stdin` | No | Use the terminal standard input as the script to be executed |
| `--config` | No | Custom path to your Prisma config file |
| `--help` | No | Displays the help message |
\* Either `--file` or `--stdin` is required to provide the script input.
**Prisma v7 breaking change**: The `--schema` and `--url` options have been removed. Configure your database connection in `prisma.config.ts` instead.
Examples [#examples-9]
* Execute the content of a SQL script file using the datasource configured in `prisma.config.ts`:
```bash
prisma db execute --file ./script.sql
```
* Execute the SQL script from stdin using the configured datasource:
```bash wrap
echo 'TRUNCATE TABLE dev;' | prisma db execute --stdin
```
Prisma Migrate [#prisma-migrate]
Prisma Migrate changed from Preview to Generally Available (GA) in 2.19.0.
**Does not apply for MongoDB**
Instead of `migrate dev` and related commands, [`db push`](/orm/prisma-migrate/workflows/prototyping-your-schema) is used for [MongoDB](/orm/core-concepts/supported-databases/mongodb).
migrate dev [#migrate-dev]
**For use in development environments only, requires shadow database**
The `migrate dev` command:
1. Reruns the existing migration history in the [shadow database](/orm/prisma-migrate/understanding-prisma-migrate/shadow-database) in order to detect schema drift (edited or deleted migration file, or a manual changes to the database schema)
2. Applies pending migrations to the shadow database (for example, new migrations created by colleagues)
3. Generates a new migration from any changes you made to the Prisma schema before running `migrate dev`
4. Applies all unapplied migrations to the development database and updates the `_prisma_migrations` table
This command is not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb). Use [`db push`](/orm/prisma-migrate/workflows/prototyping-your-schema) instead.
**Prisma v7**: `migrate dev` no longer automatically triggers `prisma generate` or seed scripts. Run `prisma generate` explicitly if needed.
See also:
* [Conceptual overview of Prisma Migrate](/orm/prisma-migrate)
* [Developing with Prisma Migrate](/orm/prisma-migrate)
Options [#options-6]
| Option | Required | Description | Default |
| :-------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------ |
| `--create-only` | No | Creates a new migration but does not apply it. This also works if you haven't made any changes to your schema (in that case, an empty migration is created). Run `migrate dev` to apply migration. | |
| `--name` / `-n` | No | Name the migration (e.g. `prisma migrate dev --name added_job_title`) | |
| `--help` / `-h` | No | Displays the help message | |
The `--skip-generate` and `--skip-seed` flags were removed in Prisma v7. `migrate dev` no longer runs `prisma generate` or seeds automatically. Run them explicitly if needed.
If a [schema drift](/orm/prisma-migrate/understanding-prisma-migrate/shadow-database#detecting-schema-drift) is detected while running `prisma migrate dev` using `--create-only`, you will be prompted to reset your database.
Arguments [#arguments-9]
| Argument | Required | Description | Default |
| :--------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------- |
| `--name` | No | The name of the migration. If no name is provided, the CLI will prompt you. | |
| `--schema` | No | Specifies the path to the desired schema.prisma file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma` `./prisma/schema.prisma` |
Examples [#examples-10]
Apply all migrations, then create and apply any new migrations:
```bash
prisma migrate dev
```
Apply all migrations and create a new migration if there are schema changes, but do not apply it:
```bash
prisma migrate dev --create-only
```
migrate reset [#migrate-reset]
**For use in development environments only**
This command:
1. Drops the database/schema if possible, or performs a soft reset if the environment does not allow deleting databases/schemas
2. Creates a new database/schema with the same name if the database/schema was dropped
3. Applies all migrations
4. Runs seed scripts
This command is not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb). Use [`db push`](/orm/prisma-migrate/workflows/prototyping-your-schema) instead.
Options [#options-7]
| Option | Required | Description | Default |
| :---------------- | :------- | :------------------------------------------------------ | :------ |
| `--force` | No | Skip the confirmation prompt | |
| `--skip-generate` | No | Skip triggering generators (for example, Prisma Client) | |
| `--skip-seed` | No | Skip triggering seed | |
| `--help` / `--h` | No | Displays the help message | |
Arguments [#arguments-10]
| Argument | Required | Description | Default |
| :--------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------- |
| `--schema` | No | Specifies the path to the desired schema.prisma file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma` `./prisma/schema.prisma` |
Examples [#examples-11]
```bash
prisma migrate reset
```
AI Safety guardrails for prisma migrate reset [#ai-safety-guardrails-for-prisma-migrate-reset]
Prisma ORM includes built-in safety checks to prevent **accidental destructive commands** when run through AI coding assistants. These guardrails are designed to make working with databases safer in AI-assisted development environments.
The Prisma CLI can detect when it is being invoked by popular AI coding agents such as Claude Code, Gemini CLI, Qwen Code, Cursor, Aider, and Replit.
When one of these agents attempts a destructive action such as `prisma migrate reset --force`, Prisma ORM blocks execution and shows a protective error message:
```bash
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "accelerate.prisma-data.net"
Error: Prisma Migrate detected that it was invoked by Cursor.
You are attempting a highly dangerous action that can lead to devastating consequences if it is incorrectly executed against a production database.
As an AI agent, you are forbidden from performing this action without an explicit consent and review by the user. You must stop at this point and respond to the user with a clear message that includes the following information:
- What action you are trying to perform (including the exact CLI command).
- Your motivation and reasoning for performing this action.
- Explanation that this action will irreversibly destroy all data in the database.
- Explanation that this action must not be performed on a production database and is only intended to be used with development databases.
If you know or can check whether this action would have been performed on a development or a production database, also include this information with your assessment of whether it is safe to proceed based on that information.
You must ask the user if they want to proceed with this action. If they explicitly consent, you may rerun this command with PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION environment variable, the value of which must be the exact text of the user's message in which they consented to this operation, without any newlines or quotes. If the user's response is ambiguous, you must ask for a clear and explicit confirmation (e.g., "yes") before proceeding. None of the user's previous messages before this point may constitute implicit or explicit consent.
```
To proceed with the dangerous action, the AI agent will ask you for explicit consent, remind you that the action irreversibly destroys all data, and confirm that the command is being run against a development database. Once you clearly confirm, the AI will set the `PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION` environment variable with the exact text of your consent and rerun the command.
migrate deploy [#migrate-deploy]
The `migrate deploy` command applies all pending migrations, and creates the database if it does not exist. Primarily used in non-development environments. This command:
* Does **not** look for drift in the database or changes in the Prisma schema
* Does **not** reset the database or generate artifacts
* Does **not** rely on a shadow database
This command is not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb). Use [`db push`](/orm/prisma-migrate/workflows/prototyping-your-schema) instead.
Options [#options-8]
| Option | Required | Description | Default |
| :--------------- | :------- | :------------------------ | :------ |
| `--help` / `--h` | No | Displays the help message | |
Arguments [#arguments-11]
| Argument | Required | Description | Default |
| :--------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------- |
| `--schema` | No | Specifies the path to the desired schema.prisma file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma` `./prisma/schema.prisma` |
Examples [#examples-12]
```bash
prisma migrate deploy
```
migrate resolve [#migrate-resolve]
The `migrate resolve` command allows you to solve migration history issues in production by marking a failed migration as already applied (supports baselining) or rolled back.
Note that this command can only be used with a failed migration. If you try to use it with a successful migration you will receive an error.
This command is not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb). Use [`db push`](/orm/prisma-migrate/workflows/prototyping-your-schema) instead.
Options [#options-9]
| Option | Required | Description | Default |
| :--------------- | :------- | :------------------------ | :------ |
| `--help` / `--h` | No | Displays the help message | |
Arguments [#arguments-12]
| Argument | Required | Description | Default |
| :-------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------- |
| `--applied` | No\* | Record a specific migration as applied - for example `--applied "20201231000000_add_users_table"` | |
| `--rolled-back` | No\* | Record a specific migration as rolled back - for example `--rolled-back "20201231000000_add_users_table"` | `./schema.prisma` `./prisma/schema.prisma` |
| `--schema` | No | Specifies the path to the desired schema.prisma file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma` `./prisma/schema.prisma` |
You must specify either `--rolled-back` *or* `--applied`.
Examples [#examples-13]
```bash
prisma migrate resolve --applied 20201231000000_add_users_table
```
```bash
prisma migrate resolve --rolled-back 20201231000000_add_users_table
```
migrate status [#migrate-status]
The `prisma migrate status` command looks up the migrations in `./prisma/migrations/*` folder and the entries in the `_prisma_migrations` table and compiles information about the state of the migrations in your database.
This command is not supported on [MongoDB](/orm/core-concepts/supported-databases/mongodb). Use [`db push`](/orm/prisma-migrate/workflows/prototyping-your-schema) instead.
For example:
```
Status
3 migrations found in prisma/migrations
Your local migration history and the migrations table from your database are different:
The last common migration is: 20201127134938_new_migration
The migration have not yet been applied:
20201208100950_test_migration
The migrations from the database are not found locally in prisma/migrations:
20201208100950_new_migration
```
In versions 4.3.0 and later, `prisma migrate status` exits with exit code 1 in the following cases:
* a database connection error occurs
* there are migration files in the `migrations` directory that have not been applied to the database
* the migration history in the `migrations` directory has diverged from the state of the database
* no migration table is found
* failed migrations are found
Options [#options-10]
| Option | Required | Description | Default |
| :--------------- | :------- | :------------------------ | :------ |
| `--help` / `--h` | No | Displays the help message | |
Arguments [#arguments-13]
| Argument | Required | Description | Default |
| :--------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------- |
| `--schema` | No | Specifies the path to the desired schema.prisma file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma` `./prisma/schema.prisma` |
Examples [#examples-14]
```bash
prisma migrate status
```
migrate diff [#migrate-diff]
This command is only partially supported for [MongoDB](/orm/core-concepts/supported-databases/mongodb). See the command options below for details.
This command compares two database schema sources and outputs a description of a migration taking the first to the state of the second.
The output can be given either as a human-readable summary (the default) or an executable script.
The `migrate diff` command can only compare database features that are [supported by Prisma](/orm/reference/database-features). If two databases differ only in unsupported features, such as views or triggers, then `migrate diff` will not show any difference between them.
The format of the command is:
```bash
prisma migrate diff --from-... --to-...
```
where the `--from-...` and `--to-...` options are selected based on the type of database schema source. The supported types of sources are:
* live databases
* migration histories
* Prisma schema data models
* an empty schema
Both schema sources must use the same database provider. For example, a diff comparing a PostgreSQL data source with a SQLite data source is not supported.
See also:
* [Migration troubleshooting in production](/orm/prisma-migrate/workflows/patching-and-hotfixing#fixing-failed-migrations-with-migrate-diff-and-db-execute)
Prerequisites [#prerequisites-4]
Before using the `migrate diff` command, if you are using `--from-config-datasource` or `--to-config-datasource`, you must configure your database connection in your `prisma.config.ts` file.
For example:
```prisma title="schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "sqlite"
}
```
```typescript title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Options [#options-11]
**Prisma v7 breaking change**: The `--from-url`, `--to-url`, `--from-schema-datasource`, `--to-schema-datasource`, and `--shadow-database-url` options have been removed. Use `--from-config-datasource` and `--to-config-datasource` instead, which read the database URL from `prisma.config.ts`.
One of the following `--from-...` options is required:
| Options | Description | Notes |
| :------------------------- | :------------------------------------------------------------- | :----------------------- |
| `--from-empty` | Assume that the data model you are migrating from is empty | |
| `--from-schema` | Path to a Prisma schema file, uses the data model for the diff | |
| `--from-migrations` | Path to the Prisma Migrate migrations directory | Not supported in MongoDB |
| `--from-config-datasource` | Use the datasource from the Prisma config file | Prisma v7+ |
One of the following `--to-...` options is required:
| Options | Description | Notes |
| :----------------------- | :------------------------------------------------------------- | :----------------------- |
| `--to-empty` | Assume that the data model you are migrating to is empty | |
| `--to-schema` | Path to a Prisma schema file, uses the data model for the diff | |
| `--to-migrations` | Path to the Prisma Migrate migrations directory | Not supported in MongoDB |
| `--to-config-datasource` | Use the datasource from the Prisma config file | Prisma v7+ |
Other options:
| Options | Required | Description | Notes |
| :--------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------- |
| `--script` | No | Outputs a SQL script instead of the default human-readable summary | Not supported in MongoDB |
| `-o`, `--output` | No | Writes to a file instead of stdout | Available since [5.12.1](https://github.com/prisma/prisma/releases/tag/5.12.1) |
| `--exit-code` | No | Change the exit code behavior to signal if the diff is empty or not (Empty: 0, Error: 1, Not empty: 2). Default behavior is Success: 0, Error: 1. | |
| `--config` | No | Custom path to your Prisma config file | |
| `--help` | No | Displays the help message | |
Examples [#examples-15]
* Compare the configured database to a Prisma schema (e.g., to roll forward after a migration failed):
```bash
prisma migrate diff \
--from-config-datasource \
--to-schema=next_datamodel.prisma \
--script
```
* Compare a Prisma schema to the configured database:
```bash
prisma migrate diff \
--from-schema=schema.prisma \
--to-config-datasource \
--script
```
* Compare the migrations directory to the configured database (e.g., to generate a migration for a hotfix already applied on production):
```bash
prisma migrate diff \
--from-migrations ./migrations \
--to-config-datasource \
--script
```
* Pipe the output to `prisma db execute`:
```bash
prisma migrate diff \
--from-config-datasource \
--to-schema=schema.prisma \
--script | prisma db execute --stdin
```
* Detect if both sources are in sync (exits with code 2 if changes are detected):
```bash
prisma migrate diff \
--exit-code \
--from-config-datasource \
--to-schema=schema.prisma
```
Prisma Data Platform [#prisma-data-platform]
platform (Early Access) [#platform-early-access]
The `platform` command provides access to the Prisma Data Platform through the Prisma CLI starting in version `5.10.0` or later.
* **Authentication**:
* `platform auth login`: Opens a browser window for login or account creation.
* `platform auth logout`: Logs out of the platform.
* `platform auth show`: Displays information about the currently authenticated user.
* **Workspace Management**:
* `platform workspace show`: Lists all workspaces available to your account.
* **Project Management**:
* `platform project show`: Lists all projects within the specified workspace.
* `platform project create`: Creates a new project within the specified workspace.
* `platform project delete`: Deletes the specified project.
* **Environment Management**:
* `platform environment show`: Lists all environments for the specified project.
* `platform environment create`: Creates a new environment within the specified project.
* `platform environment delete`: Deletes the specified environment.
* **API Key Management**:
* `platform apikey show`: Lists all API keys for the specified environment.
* `platform apikey create`: Creates a new API key for the specified environment.
* `platform apikey delete`: Deletes the specified API key.
* **Prisma Accelerate**:
* `platform accelerate enable`: Enables Prisma Accelerate for the specified environment.
* `platform accelerate disable`: Disables Prisma Accelerate for the specified environment.
You can find the complete list of available commands with the arguments [here](/cli/console).
mcp [#mcp]
Starts the [Prisma MCP server](/ai/tools/mcp-server).
Studio [#studio]
studio [#studio-1]
The `studio` command allows you to interact with and manage your data interactively. It does this by starting a local web server with a web app configured with your project's data schema and records.
Prisma ORM v7 introduces a more stable version of Prisma Studio with improved performance and a modernized architecture.
Supported databases
Prisma Studio currently supports PostgreSQL, MySQL, and SQLite. Support for CockroachDB and MongoDB is not available yet but may be added in future releases.
For detailed database support information, including SQLite requirements, see [Databases supported by Prisma Studio](/studio#getting-started).
Prerequisites [#prerequisites-5]
Before using the `studio` command, you must configure your database connection in your `prisma.config.ts` file.
For example:
```prisma title="schema.prisma"
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "sqlite"
}
```
```typescript title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Options [#options-12]
The `studio` command recognizes the following options:
| Option | Required | Description | Default |
| ----------------- | -------- | -------------------------------------------------------------------- | ------------------------ |
| `-b`, `--browser` | No | The browser to auto-open Studio in. | `` |
| `-h`, `--help` | No | Show all available options and exit | |
| `-p`, `--port` | No | The port number to start Studio on. | 5555 |
| `--config` | No | Custom path to your Prisma config file | |
| `--url` | No | Database connection string (overrides the one in your Prisma config) | |
Arguments [#arguments-14]
| Argument | Required | Description | Default |
| :--------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------- |
| `--schema` | No | Specifies the path to the desired schema.prisma file to be processed instead of the default path. Both absolute and relative paths are supported. | `./schema.prisma` `./prisma/schema.prisma` |
Examples [#examples-16]
Start Studio on the default port and open a new browser tab to it [#start-studio-on-the-default-port-and-open-a-new-browser-tab-to-it]
```bash
prisma studio
```
Start Studio on a different port and open a new browser tab to it [#start-studio-on-a-different-port-and-open-a-new-browser-tab-to-it]
```bash
prisma studio --port 7777
```
Start Studio and open a Firefox tab to it [#start-studio-and-open-a-firefox-tab-to-it]
```bash
prisma studio --browser firefox
```
Start Studio without opening a new browser tab to it [#start-studio-without-opening-a-new-browser-tab-to-it]
```bash
prisma studio --browser none
```
Start Studio with a custom Prisma config file [#start-studio-with-a-custom-prisma-config-file]
```bash
prisma studio --config=./prisma.config.ts
```
Start Studio with a direct database connection string [#start-studio-with-a-direct-database-connection-string]
```bash
prisma studio --url="postgresql://user:password@localhost:5432/dbname"
```
Using a HTTP proxy for the CLI [#using-a-http-proxy-for-the-cli]
Prisma CLI supports [custom HTTP proxies](https://github.com/prisma/prisma/issues/506). This is particularly relevant when being behind a corporate firewall.
To activate usage of the proxy, provide either of the following environment variables:
* [`HTTP_PROXY`](/orm/reference/environment-variables-reference#http_proxy) or `http_proxy`: Proxy URL for http traffic, for example `http://localhost:8080`
* [`HTTPS_PROXY`](/orm/reference/environment-variables-reference#https_proxy) or `https_proxy`: Proxy URL for https traffic, for example `https://localhost:8080`
npx create-db [#npx-create-db]
The [`create-db`](https://create-db.prisma.io/) command provisions a temporary [Prisma Postgres](/postgres) database with a single command. This is a standalone utility that can be invoked using `npx`. It's ideal for quickly testing, prototyping, or integrating with Prisma Postgres.
You can run the following variants:
| Command | Description |
| ---------------------------- | --------------------------------------------- |
| `npx create-db@latest` | Creates a temporary Prisma Postgres database. |
| `npx create-pg@latest` | Alias for `npx create-db`. |
| `npx create-postgres@latest` | Alias for `npx create-db`. |
Each database created with these commands:
* Is available for **24 hours** by default.
* Can be **claimed for free** to make it permanent using the URL displayed in the CLI output.
For full usage details, options (such as `--region` and `--interactive`), and examples, see the [documentation](/postgres/npx-create-db).
# Prisma Client API (/docs/orm/reference/prisma-client-reference)
The Prisma Client API reference documentation is based on the following schema:
```prisma
model User {
id Int @id @default(autoincrement())
name String?
email String @unique
profileViews Int @default(0)
role Role @default(USER)
coinflips Boolean[]
posts Post[]
city String
country String
profile ExtendedProfile?
pets Json
}
model ExtendedProfile {
id Int @id @default(autoincrement())
userId Int? @unique
bio String?
User User? @relation(fields: [userId], references: [id])
}
model Post {
id Int @id @default(autoincrement())
title String
published Boolean @default(true)
author User @relation(fields: [authorId], references: [id])
authorId Int
comments Json
views Int @default(0)
likes Int @default(0)
}
enum Role {
USER
ADMIN
}
```
All example generated types (such as `UserSelect` and `UserWhereUniqueInput`) are based on the `User` model.
PrismaClient [#prismaclient]
This section describes the `PrismaClient` constructor and its parameters.
adapter [#adapter]
Specifies a [driver adapter](/orm/core-concepts/supported-databases/database-drivers#driver-adapters) for database connections. Required unless using [`accelerateUrl`](#accelerateurl).
Example [#example]
```ts
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "../prisma/generated/client";
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({ adapter });
```
accelerateUrl [#accelerateurl]
Specifies a [Prisma Accelerate](https://www.prisma.io/accelerate) URL for remote query execution. Required unless using [`adapter`](#adapter).
Example [#example-1]
```ts
import { PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({
accelerateUrl: process.env.ACCELERATE_URL,
});
```
log [#log]
Determines the type and level of logging. See also: [Logging](/orm/prisma-client/observability-and-logging/logging)
Options [#options]
| Option | Example |
| ------------------------ | ------------------------------------------------------------------------ |
| Array of log levels | `[ "info", "query" ]` |
| Array of log definitions | `[ { level: "info", emit: "event" }, { level: "warn", emit: "stdout" }]` |
Log levels [#log-levels]
| Name | Example |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `query` | Logs all queries run by Prisma.
For relational databases this logs all SQL queries. Example: `prisma:query SELECT "public"."User"."id", "public"."User"."email" FROM "public"."User" WHERE ("public"."User"."id") IN (SELECT "t0"."id" FROM "public"."User" AS "t0" INNER JOIN "public"."Post" AS "j0" ON ("j0"."authorId") = ("t0"."id") WHERE ("j0"."views" > $1 AND "t0"."id" IS NOT NULL)) OFFSET $2`
For MongoDB this logs queries using the [`mongosh` shell](https://www.mongodb.com/docs/mongodb-shell/#mongodb-binary-bin.mongosh) format. Example: `prisma:query db.User.deleteMany({ _id: ( $in: [ “6221ce49f756b0721fc00542”, ], }, })` |
| `info` | Example: `prisma:info Started http server on http://127.0.0.1:58471` |
| `warn` | Warnings. |
| `error` | Errors. |
Emit formats [#emit-formats]
| Name | Description |
| -------- | ------------------------------------------------------------- |
| `stdout` | See: [stdout](https://en.wikipedia.org/wiki/Standard_streams) |
| `event` | Raises an event that you can subscribe to. |
Event types [#event-types]
The `query` event type:
```ts title="index.d.ts"
export type QueryEvent = {
timestamp: Date;
query: string; // Query sent to the database
params: string; // Query parameters
duration: number; // Time elapsed (in milliseconds) between client issuing query and database responding - not only time taken to run query
target: string;
};
```
Note that for MongoDB, the `params` and `duration` fields will be undefined.
All other log level event types:
```ts title="index.d.ts"
export type LogEvent = {
timestamp: Date;
message: string;
target: string;
};
```
Examples [#examples]
Log query and info to stdout [#log-query-and-info-to-stdout]
```ts highlight=3;normal;
import { PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({ log: ["query", "info"] });
async function main() {
const countUsers = await prisma.user.count({});
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
```
```bash
prisma:info Starting a postgresql pool with 13 connections.
prisma:info Started http server
prisma:query SELECT COUNT(*) FROM (SELECT "public"."User"."id" FROM "public"."User" WHERE 1=1 ORDER BY "public"."User"."coinflips" ASC OFFSET $1) AS "sub"
```
Log a query event to console [#log-a-query-event-to-console]
```ts
import { PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({
log: [{ level: "query", emit: "event" }],
});
prisma.$on("query", (e) => {
console.log(e);
});
async function main() {
const countUsers = await prisma.user.count({});
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
```
```json
{
timestamp: 2020-11-17T10:32:10.898Z,
query: 'SELECT COUNT(*) FROM (SELECT "public"."User"."id" FROM "public"."User" WHERE 1=1 OFFSET $1) AS "sub"',
params: '[0]',
duration: 5,
target: 'quaint::connector::metrics'
}
```
Log info, warn, and error events to console [#log-info-warn-and-error-events-to-console]
```ts
import { PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({
log: [
{ level: "warn", emit: "event" },
{ level: "info", emit: "event" },
{ level: "error", emit: "event" },
],
});
prisma.$on("warn", (e) => {
console.log(e);
});
prisma.$on("info", (e) => {
console.log(e);
});
prisma.$on("error", (e) => {
console.log(e);
});
async function main() {
const countUsers = await prisma.user.count({});
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
```
```json
{
timestamp: 2020-11-17T10:33:24.592Z,
message: 'Starting a postgresql pool with 13 connections.',
target: 'quaint::pooled'
}
{
timestamp: 2020-11-17T10:33:24.637Z,
message: 'Started http server',
target: 'query_engine::server'
}
```
errorFormat [#errorformat]
Determines the level and formatting of errors returned by Prisma Client.
Error formats [#error-formats]
| Name | Description |
| --------------------- | ---------------------------------------------- |
| `undefined` | If it's not defined, the default is colorless. |
| `pretty` | Enables pretty error formatting. |
| `colorless` (default) | Enables colorless error formatting. |
| `minimal` | Enables minimal error formatting. |
Examples [#examples-1]
No error formatting [#no-error-formatting]
```ts
const prisma = new PrismaClient({
// Defaults to colorless
});
```
pretty error formatting [#pretty-error-formatting]
```ts
const prisma = new PrismaClient({
errorFormat: "pretty",
});
```
colorless error formatting [#colorless-error-formatting]
```ts
const prisma = new PrismaClient({
errorFormat: "colorless",
});
```
minimal error formatting [#minimal-error-formatting]
```ts
const prisma = new PrismaClient({
errorFormat: "minimal",
});
```
comments [#comments]
Defines an array of [SQL commenter plugins](/orm/prisma-client/observability-and-logging/sql-comments) that add metadata to your SQL queries as comments. This is useful for observability, debugging, and correlating queries with application traces.
Options [#options-1]
| Option | Description |
| ---------------------- | ----------------------------------------------------------------------------------------------------------- |
| `SqlCommenterPlugin[]` | An array of SQL commenter plugin functions. Each plugin receives query context and returns key-value pairs. |
First-party plugins [#first-party-plugins]
| Package | Description |
| ------------------------------------ | -------------------------------------------------------------------------------- |
| `@prisma/sqlcommenter-query-tags` | Adds arbitrary tags to queries within an async context using `AsyncLocalStorage` |
| `@prisma/sqlcommenter-trace-context` | Adds W3C Trace Context (`traceparent`) headers for distributed tracing |
Examples [#examples-2]
Using first-party plugins [#using-first-party-plugins]
```ts
import { PrismaClient } from "../prisma/generated/client";
import { PrismaPg } from "@prisma/adapter-pg";
import { queryTags } from "@prisma/sqlcommenter-query-tags";
import { traceContext } from "@prisma/sqlcommenter-trace-context";
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({
adapter,
comments: [queryTags(), traceContext()],
});
```
Creating a custom plugin [#creating-a-custom-plugin]
```ts
import { PrismaClient } from "../prisma/generated/client";
import { PrismaPg } from "@prisma/adapter-pg";
import type { SqlCommenterPlugin } from "@prisma/sqlcommenter";
const appPlugin: SqlCommenterPlugin = (context) => ({
application: "my-app",
environment: process.env.NODE_ENV ?? "development",
model: context.query.modelName,
action: context.query.action,
});
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });
const prisma = new PrismaClient({
adapter,
comments: [appPlugin],
});
```
This produces SQL queries with comments like:
```sql
SELECT "id", "name" FROM "User" /*action='findMany',application='my-app',environment='production',model='User'*/
```
For more details, see [SQL comments](/orm/prisma-client/observability-and-logging/sql-comments).
transactionOptions [#transactionoptions]
Sets default [transaction options](/orm/prisma-client/queries/transactions#transaction-isolation-level) globally.
Remarks [#remarks]
* The transaction levels can be overridden on a per-transaction level.
Options [#options-2]
| Option | Description |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `maxWait` | The maximum amount of time Prisma Client will wait to acquire a transaction from the database. The default value is 2 seconds. |
| `timeout` | The maximum amount of time the interactive transaction can run before being canceled and rolled back. The default value is 5 seconds. |
| `isolationLevel` | Sets the [transaction isolation level](/orm/prisma-client/queries/transactions#transaction-isolation-level). By default this is set to the value currently configured in your database. The available levels can vary depending on the database you use. |
Example [#example-2]
```ts
const prisma = new PrismaClient({
transactionOptions: {
isolationLevel: Prisma.TransactionIsolationLevel.Serializable,
maxWait: 5000, // default: 2000
timeout: 10000, // default: 5000
},
});
```
Model queries [#model-queries]
Use model queries to perform CRUD operations on your models. See also: [CRUD](/orm/prisma-client/queries/crud)
findUnique() [#findunique]
`findUnique()` query lets you retrieve a single database record:
* By *ID*
* By a *unique* attribute
Remarks [#remarks-1]
* Prisma Client's dataloader [automatically batches `findUnique()` queries](/orm/prisma-client/queries/advanced/query-optimization-performance#using-findunique-with-the-fluent-api) with the same `select` and `where` parameters.
* If you want the query to throw an error if the record is not found, then consider using [`findUniqueOrThrow`](#finduniqueorthrow) instead.
* You cannot use [filter conditions](#filter-conditions-and-operators) (e.g. `equals`, `contains`, `not`) to filter fields of the [JSON](/orm/reference/prisma-schema-reference#json) data type. Using filter conditions will likely result in a `null` response for that field.
Options [#options-3]
| Name | Example type (`User`) | Required | Description |
| ---------------------- | ------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `where` | `UserWhereUniqueInput` | **Yes** | Wraps all fields of a model so that a record can be selected ([learn more](#filter-on-non-unique-fields-with-userwhereuniqueinput)). |
| `select` | `XOR` | No | [Specifies which properties to include](/v6/orm/prisma-client/queries/select-fields) on the returned object. |
| `include` | `XOR` | No | [Specifies which relations should be eagerly loaded](/orm/prisma-client/queries/relation-queries) on the returned object. |
| `omit` | `XOR` | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result |
| `relationLoadStrategy` | `'join'` or `'query'` | No | **Default: `join`**. [Load strategy](/orm/prisma-client/queries/relation-queries#relation-load-strategies-preview) for relations. Requires `relationJoins` preview feature. |
Return type [#return-type]
| Return type | Example | Description |
| ------------------------- | -------------------------- | --------------------------------------------------------------- |
| JavaScript object (typed) | `User` | |
| JavaScript object (plain) | `{ title: "Hello world" }` | Use `select` and `include` to determine which fields to return. |
| `null` | `null` | Record not found |
Examples [#examples-3]
Get the User record with an id of 42 [#get-the-user-record-with-an-id-of-42]
```ts
const result = await prisma.user.findUnique({
where: {
id: 42,
},
});
```
Get the User record with an email of alice@prisma.io [#get-the-user-record-with-an-email-of-aliceprismaio]
```ts
const result = await prisma.user.findUnique({
where: {
email: "alice@prisma.io",
},
});
```
Get the User record with firstName of Alice and lastName of Smith (@@unique) [#get-the-user-record-with-firstname-of-alice-and-lastname-of-smith-unique]
Expand for example User model with a @@unique block
```prisma
model User {
firstName String
lastName String
@@unique(fields: [firstName, lastName], name: "fullname")
}
```
```ts
const result = await prisma.user.findUnique({
where: {
fullname: {
// name property of @@unique attribute - default is firstname_lastname
firstName: "Alice",
lastName: "Smith",
},
},
});
```
Get the User record with firstName of Alice and lastName of Smith (@@id) [#get-the-user-record-with-firstname-of-alice-and-lastname-of-smith-id]
Expand for example User model with an @@id block
```prisma
model User {
firstName String
lastName String
@@id([firstName, lastName])
}
```
```ts
const result = await prisma.user.findUnique({
where: {
firstName_lastName: {
firstName: "Alice",
lastName: "Smith",
},
},
});
```
findUniqueOrThrow() [#finduniqueorthrow]
`findUniqueOrThrow()` retrieves a single record in the same way as [`findUnique()`](#findunique). However, if the query does not find the requested record, it throws a `PrismaClientKnownRequestError`.
Here's an example of its usage:
```ts
await prisma.user.findUniqueOrThrow({
where: { id: 1 },
});
```
`findUniqueOrThrow()` differs from `findUnique()` as follows:
* Its return type is non-nullable. For example, `post.findUnique()` can return `post` or `null`, but `post.findUniqueOrThrow()` always returns `post`.
* It is not compatible with sequential operations in the [`$transaction` API](/orm/prisma-client/queries/transactions#the-transaction-api). If the query throws a `PrismaClientKnownRequestError`, then the API will not roll back any operations in the array of calls. As a workaround, you can use interactive transactions with the `$transaction` API, as follows:
```ts
$transaction(async (prisma) => {
await prisma.model.create({ data: { ... });
await prisma.model.findUniqueOrThrow();
})
```
findFirst() [#findfirst]
`findFirst` returns the first record in a list that matches your criteria.
Remarks [#remarks-2]
* If you want the query to throw an error if the record is not found, then consider using [`findFirstOrThrow`](#findfirstorthrow) instead.
Options [#options-4]
| Name | Example type (`User`) | Required | Description |
| ---------------------- | ----------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `select` | `XOR` | No | [Specifies which properties to include](/v6/orm/prisma-client/queries/select-fields) on the returned object. |
| `include` | `XOR` | No | [Specifies which relations should be eagerly loaded](/orm/prisma-client/queries/relation-queries) on the returned object. |
| `omit` | `XOR` | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result. |
| `relationLoadStrategy` | `'join'` or `'query'` | No | **Default: `join`**. [Load strategy](/orm/prisma-client/queries/relation-queries#relation-load-strategies-preview) for relations. Requires `relationJoins` preview feature. |
| `where` | `UserWhereInput` | No | Wraps *all* model fields in a type so that the list can be filtered by any property. |
| `orderBy` | `XOR, UserOrderByInput>` | No | Lets you order the returned list by any property. |
Return type [#return-type-1]
| Return type | Example | Description |
| ------------------------- | -------------------------- | --------------------------------------------------------------- |
| JavaScript object (typed) | `User` | Specifies which properties to include on the returned object. |
| JavaScript object (plain) | `{ title: "Hello world" }` | Use `select` and `include` to determine which fields to return. |
| `null` | `null` | Record not found |
Remarks [#remarks-3]
* `findFirst` calls `findMany` behind the scenes and accepts the same query options.
* Passing in a negative `take` value when you use a `findFirst` query reverses the order of the list.
Examples [#examples-4]
See [Filter conditions and operators](#filter-conditions-and-operators) for examples of how to filter results.
Get the first User record where the name is Alice [#get-the-first-user-record-where-the-name-is-alice]
```ts
const user = await prisma.user.findFirst({
where: { name: "Alice" },
});
```
Get the first Post record where the title starts with A test, reverse the list with take [#get-the-first-post-record-where-the-title-starts-with-a-test-reverse-the-list-with-take]
```ts
import { PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({});
async function main() {
const a = await prisma.post.create({
data: {
title: "A test 1",
},
});
const b = await prisma.post.create({
data: {
title: "A test 2",
},
});
const c = await prisma.post.findFirst({
where: {
title: {
startsWith: "A test",
},
},
orderBy: {
title: "asc",
},
take: -1, // Reverse the list
});
}
main();
```
findFirstOrThrow() [#findfirstorthrow]
`findFirstOrThrow()` retrieves a single data record in the same way as [`findFirst()`](#findfirst). However, if the query does not find a record, it throws a `PrismaClientKnownRequestError`.
`findFirstOrThrow()` differs from `findFirst()` as follows:
* Its return type is non-nullable. For example, `post.findFirst()` can return `post` or `null`, but `post.findFirstOrThrow` always returns `post`.
* It is not compatible with sequential operations in the [`$transaction` API](/orm/prisma-client/queries/transactions#the-transaction-api). If the query returns `PrismaClientKnownRequestError`, then the API will not roll back any operations in the array of calls. As a workaround, you can use interactive transactions with the `$transaction` API, as follows:
```ts
prisma.$transaction(async (tx) => {
await tx.model.create({ data: { ... });
await tx.model.findFirstOrThrow();
})
```
findMany() [#findmany]
`findMany` returns a list of records.
Options [#options-5]
| Name | Type | Required | Description |
| ---------------------- | ------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `select` | `XOR` | No | [Specifies which properties to include](/v6/orm/prisma-client/queries/select-fields) on the returned object. |
| `include` | `XOR` | No | [Specifies which relations should be eagerly loaded](/orm/prisma-client/queries/relation-queries) on the returned object. |
| `omit` | `XOR` | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result |
| `relationLoadStrategy` | `'join'` or `'query'` | No | **Default: `join`**. [Load strategy](/orm/prisma-client/queries/relation-queries#relation-load-strategies-preview) for relations. Requires `relationJoins` preview feature. |
| `where` | `UserWhereInput` | No | Wraps *all* model fields in a type so that the list can be filtered by any property. |
| `orderBy` | `XOR`ByInput>, PostOrderByInput>` | No | Lets you order the returned list by any property. |
| `cursor` | `UserWhereUniqueInput` | No | Specifies the position for the list (the value typically specifies an `id` or another unique value). |
| `take` | `number` | No | Specifies how many objects should be returned in the list (as seen from the *beginning* (positive value) or *end* (negative value) **either** of the list **or** from the `cursor` position if mentioned) |
| `skip` | `number` | No | Specifies how many of the returned objects in the list should be skipped. |
| `distinct` | `Enumerable` | No | Lets you filter out duplicate rows by a specific field - for example, return only distinct `Post` titles. |
Return type [#return-type-2]
| Return type | Example | Description |
| ------------------------------- | ---------------------------- | --------------------------------------------------------------- |
| JavaScript array object (typed) | `User[]` | |
| JavaScript array object (plain) | `[{ title: "Hello world" }]` | Use `select` and `include` to determine which fields to return. |
| Empty array | `[]` | No matching records found. |
Examples [#examples-5]
See [Filter conditions and operators](#filter-conditions-and-operators) for examples of how to filter results.
Get all User records where the name is Alice [#get-all-user-records-where-the-name-is-alice]
```ts
const user = await prisma.user.findMany({
where: { name: "Alice" },
});
```
create() [#create]
`create` creates a new database record.
Options [#options-6]
| Name | Type | Required | Description |
| ---------------------- | -------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `XOR`UserUncheckedCreateInput>` | **Yes** | Wraps all the model fields in a type so that they can be provided when creating new records. It also includes relation fields which lets you perform (transactional) nested inserts. Fields that are marked as optional or have default values in the datamodel are optional. |
| [`select`](#select) | `XOR` | No | [Specifies which properties to include](/v6/orm/prisma-client/queries/select-fields) on the returned object. |
| [`include`](#include) | `XOR` | No | [Specifies which relations should be eagerly loaded](/orm/prisma-client/queries/relation-queries) on the returned object. |
| [`omit`](#omit) | `XOR` | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result |
| `relationLoadStrategy` | `'join'` or `'query'` | No | **Default: `join`**. [Load strategy](/orm/prisma-client/queries/relation-queries#relation-load-strategies-preview) for relations. Requires `relationJoins` preview feature. |
Return type [#return-type-3]
| Return type | Example | Description |
| ------------------------- | ------------------------------ | --------------------------------------------------------------- |
| JavaScript object (typed) | `User` | |
| JavaScript object (plain) | `{ name: "Alice Wonderland" }` | Use `select` and `include` to determine which fields to return. |
Remarks [#remarks-4]
* You can also perform a nested [`create`](#create) - for example, add a `User` and two `Post` records at the same time.
Examples [#examples-6]
Create a single new record with the only required field email [#create-a-single-new-record-with-the-only-required-field-email]
```ts
const user = await prisma.user.create({
data: { email: "alice@prisma.io" },
});
```
Create multiple new records [#create-multiple-new-records]
In most cases, you can carry out batch inserts with the [`createMany()`](#createmany) or [`createManyAndReturn()`](#createmanyandreturn) queries. However, [there are scenarios where `create()` is the best option to insert multiple records](#remarks-11).
The following example results in **two** `INSERT` statements:
```ts
import { Prisma, PrismaClient } from "../prisma/generated/client";
const prisma = new PrismaClient({ log: ["query"] });
async function main() {
let users: Prisma.UserCreateInput[] = [
{
email: "ariana@prisma.io",
name: "Ari",
profileViews: 20,
coinflips: [true, false, false],
role: "ADMIN",
},
{
email: "elsa@prisma.io",
name: "Elsa",
profileViews: 20,
coinflips: [true, false, false],
role: "ADMIN",
},
];
await Promise.all(
users.map(async (user) => {
await prisma.user.create({
data: user,
});
}),
);
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
```
```sql
prisma:query BEGIN
prisma:query INSERT INTO "public"."User" ("name","email","profileViews","role","coinflips") VALUES ($1,$2,$3,$4,$5) RETURNING "public"."User"."id"
prisma:query SELECT "public"."User"."id", "public"."User"."name", "public"."User"."email", "public"."User"."profileViews", "public"."User"."role", "public"."User"."coinflips" FROM "public"."User" WHERE "public"."User"."id" = $1 LIMIT $2 OFFSET $3
prisma:query INSERT INTO "public"."User" ("name","email","profileViews","role","coinflips") VALUES ($1,$2,$3,$4,$5) RETURNING "public"."User"."id"
prisma:query COMMIT
prisma:query SELECT "public"."User"."id", "public"."User"."name", "public"."User"."email", "public"."User"."profileViews", "public"."User"."role", "public"."User"."coinflips" FROM "public"."User" WHERE "public"."User"."id" = $1 LIMIT $2 OFFSET $3
prisma:query COMMIT
```
update() [#update]
`update` updates an existing database record.
Options [#options-7]
| Name | Type | Required | Description |
| ---------------------- | ------------------------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `XOR`UserUncheckedUpdateInput>` | **Yes** | Wraps all the fields of the model so that they can be provided when updating an existing record. Fields that are marked as optional or have default values in the datamodel are optional. |
| `where` | `UserWhereUniqueInput` | **Yes** | Wraps all fields of a model so that a record can be selected ([learn more](#filter-on-non-unique-fields-with-userwhereuniqueinput)). |
| [`select`](#select) | `XOR` | No | [Specifies which properties to include](/v6/orm/prisma-client/queries/select-fields) on the returned object. |
| [`include`](#include) | `XOR` | No | [Specifies which relations should be eagerly loaded](/orm/prisma-client/queries/relation-queries) on the returned object. |
| [`omit`](#omit) | `XOR` | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result. |
| `relationLoadStrategy` | `'join'` or `'query'` | No | **Default: `join`**. [Load strategy](/orm/prisma-client/queries/relation-queries#relation-load-strategies-preview) for relations. Requires `relationJoins` preview feature. |
Return type [#return-type-4]
| Return type | Example | Description |
| ---------------------------------------------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| JavaScript object (typed) | `User` | |
| JavaScript object (plain) | `{ name: "Alice Wonderland" }` | Use `select` and `include` to determine which fields to return. |
| `PrismaClientKnownRequestError` (code `P2025`) | | Thrown if the record to update does not exist. See [Error reference](/orm/reference/error-reference#p2025) |
Remarks [#remarks-5]
* To perform arithmetic operations on update (add, subtract, multiply, divide), use [atomic updates](#atomic-number-operations) to prevent race conditions.
* You can also perform a nested [`update`](#update-1) - for example, update a user and that user's posts at the same time.
Examples [#examples-7]
Update the email of the User record with id of 1 to alice@prisma.io [#update-the-email-of-the-user-record-with-id-of-1-to-aliceprismaio]
```ts
const user = await prisma.user.update({
where: { id: 1 },
data: { email: "alice@prisma.io" },
});
```
upsert() [#upsert]
This section covers the usage of the `upsert()` operation. To learn about using [nested upsert queries](#upsert-1) within `update()`, reference the linked documentation.
`upsert` does the following:
* If an existing database record satisfies the `where` condition, it updates that record
* If no database record satisfies the `where` condition, it creates a new database record
Options [#options-8]
| Name | Type | Required | Description |
| ---------------------- | ------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `create` | `XOR`UserUncheckedCreateInput>` | **Yes** | Wraps all the fields of the model so that they can be provided when creating new records. It also includes relation fields which lets you perform (transactional) nested inserts. Fields that are marked as optional or have default values in the datamodel are optional. |
| `update` | `XOR`UserUncheckedUpdateInput>` | **Yes** | Wraps all the fields of the model so that they can be provided when updating an existing record. Fields that are marked as optional or have default values in the datamodel are optional. |
| `where` | `UserWhereUniqueInput` | **Yes** | Wraps all fields of a model so that a record can be selected ([learn more](#filter-on-non-unique-fields-with-userwhereuniqueinput)). |
| [`select`](#select) | `XOR` | No | [Specifies which properties to include](/v6/orm/prisma-client/queries/select-fields) on the returned object. |
| [`include`](#include) | `XOR` | No | [Specifies which relations should be eagerly loaded](/orm/prisma-client/queries/relation-queries) on the returned object. |
| [`omit`](#omit) | `XOR` | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result |
| `relationLoadStrategy` | `'join'` or `'query'` | No | **Default: `join`**. [Load strategy](/orm/prisma-client/queries/relation-queries#relation-load-strategies-preview) for relations. Requires `relationJoins` preview feature. |
Return type [#return-type-5]
| Return type | Example | Description |
| ------------------------- | ------------------------------ | --------------------------------------------------------------- |
| JavaScript object (typed) | `User` | |
| JavaScript object (plain) | `{ name: "Alice Wonderland" }` | Use `select` and `include` to determine which fields to return. |
Remarks [#remarks-6]
* To perform arithmetic operations on update (add, subtract, multiply, divide), use [atomic updates](#atomic-number-operations) to prevent race conditions.
* If two or more upsert operations happen at the same time and the record doesn't already exist, then a race condition might happen. As a result, one or more of the upsert operations might throw a unique key constraint error. Your application code can catch this error and retry the operation. [Learn more](#unique-key-constraint-errors-on-upserts).
* Prisma ORM hands over upsert queries to the database where possible. [Learn more](#database-upserts).
Examples [#examples-8]
Update (if exists) or create a new User record with an email of alice@prisma.io [#update-if-exists-or-create-a-new-user-record-with-an-email-of-aliceprismaio]
```ts
const user = await prisma.user.upsert({
where: { id: 1 },
update: { email: "alice@prisma.io" },
create: { email: "alice@prisma.io" },
});
```
Unique key constraint errors on upserts [#unique-key-constraint-errors-on-upserts]
Problem [#problem]
If multiple upsert operations happen at the same time and the record doesn't already exist, then one or more of the operations might return a [unique key constraint error](/orm/reference/error-reference#p2002).
Cause [#cause]
When Prisma Client does an upsert, it first checks whether that record already exists in the database. To make this check, Prisma Client performs a read operation with the `where` clause from the upsert operation. This has two possible outcomes, as follows:
* If the record does not exist, then Prisma Client creates that record.
* If the record exists, then Prisma Client updates it.
When your application tries to perform two or more concurrent upsert operations, then a race condition might happen where two or more operations do not find the record and therefore try to create that record. In this situation, one of the operations successfully creates the new record but the other operations fail and return a unique key constraint error.
Solution [#solution]
Handle the P2002 error in your application code. When it occurs, retry the upsert operation to update the row.
Database upserts [#database-upserts]
Where possible, Prisma Client hands over an `upsert` query to the database. This is called a *database upsert*.
Database upserts have the following advantages:
* They are faster than upserts handled by Prisma Client
* [Unique key constraint errors](#unique-key-constraint-errors-on-upserts) cannot happen
Prisma Client uses a database upsert automatically when [specific criteria](#database-upsert-query-criteria) are met. When these criteria are not met, Prisma Client handles the `upsert`.
To use a database upsert, Prisma Client sends the SQL construction [`INSERT ... ON CONFLICT SET .. WHERE`](https://www.prisma.io/dataguide/postgresql/inserting-and-modifying-data/insert-on-conflict) to the database.
Database upsert prerequisites [#database-upsert-prerequisites]
Prisma Client uses database upserts with CockroachDB, PostgreSQL, or SQLite data sources.
Database upsert query criteria [#database-upsert-query-criteria]
Prisma Client uses a database upsert for an `upsert` query when the query meets the following criteria:
* There are no nested queries in the `upsert`'s `create` and `update` [options](#options-7)
* The query does *not* include a selection that uses a [nested read](/orm/prisma-client/queries/relation-queries#nested-reads)
* The query modifies only one model
* There is only one unique field in the `upsert`'s `where` option
* The unique field in the `where` option and the unique field in the `create` option have the same value
If your query does not meet these criteria, then Prisma Client handles the upsert itself.
Database upsert examples [#database-upsert-examples]
The following examples use this schema:
```prisma
model User {
id Int @id
profileViews Int
userName String @unique
email String
@@unique([id, profileViews])
}
```
The following `upsert` query meets all of the criteria, so Prisma Client uses a database upsert.
```ts
prisma.user.upsert({
where: {
userName: "Alice",
},
create: {
id: 1,
profileViews: 1,
userName: "Alice",
email: "alice@prisma.io",
},
update: {
email: "updated@example.com",
},
});
```
In this situation, Prisma uses the following SQL query:
```sql
INSERT INTO "public"."User" ("id","profileViews","userName","email") VALUES ($1,$2,$3,$4)
ON CONFLICT ("userName") DO UPDATE
SET "email" = $5 WHERE ("public"."User"."userName" = $6 AND 1=1) RETURNING "public"."User"."id", "public"."User"."profileViews", "public"."User"."userName", "public"."User"."email"
```
The following query has multiple unique values in the `where` clause, so Prisma Client does *not* use a database upsert:
```ts
prisma.User.upsert({
where: {
userName: "Alice",
profileViews: 1,
id: 1,
},
create: {
id: 1,
profileViews: 1,
userName: "Alice",
email: "alice@prisma.io",
},
update: {
email: "updated@example.com",
},
});
```
In the following query, the values for `userName` in the `where` and `create` options are different, so Prisma Client does *not* use a database upsert.
```ts
prisma.User.upsert({
where: {
userName: "Alice",
},
create: {
id: 1,
profileViews: 1,
userName: "AliceS",
email: "alice@prisma.io",
},
update: {
email: "updated@example.com",
},
});
```
In the following query, the selection on the `title` field in `posts` is a nested read, so Prisma Client does *not* use a database upsert.
```ts
prisma.user.upsert({
select: {
email: true,
id: true,
posts: {
select: {
title: true,
},
},
},
where: {
userName: "Alice",
},
create: {
id: 1,
profileViews: 1,
userName: "Alice",
email: "alice@prisma.io",
},
update: {
email: "updated@example.com",
},
});
```
delete() [#delete]
`delete` deletes an existing database record. You can delete a record:
* By *ID*
* By a *unique* attribute
To delete records that match a certain criteria, use [`deleteMany`](#deletemany) with a filter.
Options [#options-9]
| Name | Type | Required | Description |
| ---------------------- | ------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `where` | `UserWhereUniqueInput` | **Yes** | Wraps all fields of a model so that a record can be selected ([learn more](#filter-on-non-unique-fields-with-userwhereuniqueinput)). |
| [`select`](#select) | `XOR` | No | [Specifies which properties to include](/v6/orm/prisma-client/queries/select-fields) on the returned object. |
| [`include`](#include) | `XOR` | No | [Specifies which relations should be eagerly loaded](/orm/prisma-client/queries/relation-queries) on the returned object. |
| [`omit`](#omit) | `XOR` | No | Specifies which properties to exclude on the returned object. Excludes specified fields from the result |
| `relationLoadStrategy` | `'join'` or `'query'` | No | **Default: `join`**. [Load strategy](/orm/prisma-client/queries/relation-queries#relation-load-strategies-preview) for relations. Requires `relationJoins` preview feature. |
Return type [#return-type-6]
| Return type | Example | Description |
| ---------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| JavaScript object (typed) | `User` | The `User` record that was deleted. |
| JavaScript object (plain) | `{ name: "Alice Wonderland" }` | Data from the `User` record that was deleted. Use `select` and `include` to determine which fields to return. |
| `PrismaClientKnownRequestError` (code `P2025`) | | Thrown if the record to delete does not exist. See [Error reference](/orm/reference/error-reference#p2025) |
Remarks [#remarks-7]
* To delete multiple records based on some criteria (for example, all `User` records with a `prisma.io` email address, use `deleteMany`)
Examples [#examples-9]
Delete the User record with an id of 1 [#delete-the-user-record-with-an-id-of-1]
```ts
const user = await prisma.user.delete({
where: { id: 1 },
});
```
Delete the User record where email equals elsa@prisma.io [#delete-the-user-record-where-email-equals-elsaprismaio]
The following query deletes a specific user record and uses `select` to return the `name` and `email` of the deleted user:
```ts
const deleteUser = await prisma.user.delete({
where: {
email: "elsa@prisma.io",
},
select: {
email: true,
name: true,
},
});
```
```json
{ "email": "elsa@prisma.io", "name": "Elsa" }
```
createMany() [#createmany]
`createMany` creates multiple records in a transaction.
Options [#options-10]
| Name | Type | Required | Description |
| ----------------- | --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Enumerable` | **Yes** | Wraps all the model fields in a type so that they can be provided when creating new records. Fields that are marked as optional or have default values in the datamodel are optional. |
| `skipDuplicates?` | `boolean` | No | Do not insert records with unique fields or ID fields that already exist. Only supported by databases that support [`ON CONFLICT DO NOTHING`](https://www.postgresql.org/docs/9.5/sql-insert.html#SQL-ON-CONFLICT). This excludes MongoDB and SQLServer |
Return type [#return-type-7]
| Return type | Example | Description |
| -------------- | -------------- | ----------------------------------------- |
| `BatchPayload` | `{ count: 3 }` | A count of the number of records created. |
Remarks [#remarks-8]
* `createMany()` is supported by SQLite.
* The `skipDuplicates` option is not supported by MongoDB, SQLServer, or SQLite.
* You **cannot** create or connect relations by using nested `create`, `createMany`, `connect`, `connectOrCreate` queries inside a top-level `createMany()` query. See here for a [workaround](/orm/prisma-client/queries/relation-queries#using-nested-createmany).
* You can use a nested [`createMany`](#createmany-1) query inside an [`update()`](#update) or [`create()`](#create) query - for example, add a `User` and two `Post` records with a nested `createMany` at the same time.
Examples [#examples-10]
Create several new users [#create-several-new-users]
```ts
const users = await prisma.user.createMany({
data: [
{ name: "Sonali", email: "sonali@prisma.io" },
{ name: "Alex", email: "alex@prisma.io" },
],
});
```
createManyAndReturn() [#createmanyandreturn]
`createManyAndReturn` creates multiple records and returns the resulting objects. Supported for PostgreSQL, CockroachDB, and SQLite.
Options [#options-11]
| Name | Type | Required | Description |
| --------------------- | --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Enumerable` | **Yes** | Wraps all the model fields in a type so that they can be provided when creating new records. Fields that are marked as optional or have default values in the datamodel are optional. |
| [`select`](#select) | `XOR` | No | [Specifies which properties to include](/v6/orm/prisma-client/queries/select-fields) on the returned objects. |
| [`omit`](#omit) | `XOR` | No | Specifies which properties to exclude on the returned objects. Excludes specified fields from the result. Mutually exclusive with `select`. |
| [`include`](#include) | `XOR` | No | [Specifies which relations should be eagerly loaded](/orm/prisma-client/queries/relation-queries) on the returned objects. |
| `skipDuplicates?` | `boolean` | No | Do not insert records with unique fields or ID fields that already exist. Only supported by databases that support [`ON CONFLICT DO NOTHING`](https://www.postgresql.org/docs/9.5/sql-insert.html#SQL-ON-CONFLICT). This excludes MongoDB and SQLServer |
Remarks [#remarks-9]
* The `skipDuplicates` option is not supported by SQLite.
* Note that the order of elements returned by `createManyAndReturn` is not guaranteed.
* You **cannot** create or connect relations by using nested `create`, `createMany`, `connect`, `connectOrCreate` queries inside a top-level `createManyAndReturn()` query. See here for a [workaround](/orm/prisma-client/queries/relation-queries#using-nested-createmany).
* When relations are included via `include`, a separate query is generated per relation.
* `relationLoadStrategy: join` is not supported.
Return type [#return-type-8]
| Return type | Example | Description |
| ------------------------------- | ---------------------- | ----------------------------------------------------------------------- |
| JavaScript array object (typed) | `User[]` | |
| JavaScript array object (plain) | `[{ name: "Sonali" }]` | Use `select`, `omit` and `include` to determine which fields to return. |
Examples [#examples-11]
Create and return several new users [#create-and-return-several-new-users]
```ts
const users = await prisma.user.createManyAndReturn({
data: [
{ name: "Sonali", email: "sonali@prisma.io" },
{ name: "Alex", email: "alex@prisma.io" },
],
});
```
```json
[
{ "id": 0, "name": "Sonali", "email": "sonali@prisma.io", "profileViews": 0 },
{ "id": 1, "name": "Alex", "email": "alex@prisma.io", "profileViews": 0 }
]
```
updateMany() [#updatemany]
`updateMany` updates a batch of existing database records in bulk and returns the number of updated records.
Options [#options-12]
| Name | Type | Required | Description |
| ------- | ----------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `XOR`UserUncheckedUpdateManyInput>` | **Yes** | Wraps all the fields of the model so that they can be provided when updating an existing record. Fields that are marked as optional or have default values in the datamodel are optional on `data`. |
| `where` | `UserWhereInput` | No | Wraps *all* fields of a model so that the list can be filtered by any property. If you do not filter the list, all records will be updated. |
| `limit` | `number` | No | Limits the number of records to update. |
Return type [#return-type-9]
| Return type | Example | Description |
| -------------- | -------------- | ----------------------------- |
| `BatchPayload` | `{ count: 4 }` | The count of updated records. |
```ts
export type BatchPayload = {
count: number;
};
```
Examples [#examples-12]
Update all User records where the name is Alice to ALICE [#update-all-user-records-where-the-name-is-alice-to-alice]
```ts
const updatedUserCount = await prisma.user.updateMany({
where: { name: "Alice" },
data: { name: "ALICE" },
});
```
Update all User records where the email contains prisma.io and at least one related Post has more than 10 likes [#update-all-user-records-where-the-email-contains-prismaio-and-at-least-one-related-post-has-more-than-10-likes]
```ts
const updatedUserCount = await prisma.user.updateMany({
where: {
email: {
contains: "prisma.io",
},
posts: {
some: {
likes: {
gt: 10,
},
},
},
},
data: {
role: "USER",
},
});
```
Update User records where the email contains prisma.io, but limit to 5 records updated. [#update-user-records-where-the-email-contains-prismaio-but-limit-to-5-records-updated]
```ts
const updatedUserCount = await prisma.user.updateMany({
where: {
email: {
contains: "prisma.io",
},
},
data: {
role: "USER",
},
limit: 5,
});
```
updateManyAndReturn() [#updatemanyandreturn]
`updateManyAndReturn` updates multiple records and returns the resulting objects. Supported for PostgreSQL, CockroachDB, and SQLite.
Options [#options-13]
| Name | Type | Required | Description |
| ------- | ----------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `XOR`UserUncheckedUpdateManyInput>` | **Yes** | Wraps all the fields of the model so that they can be provided when updating an existing record. Fields that are marked as optional or have default values in the datamodel are optional on `data`. |
| `where` | `UserWhereInput` | No | Wraps *all* fields of a model so that the list can be filtered by any property. If you do not filter the list, all records will be updated. |
Return type [#return-type-10]
| Return type | Example | Description |
| ------------------------------- | ---------------------- | ----------------------------------------------------------------------- |
| JavaScript array object (typed) | `User[]` | |
| JavaScript array object (plain) | `[{ name: "Sonali" }]` | Use `select`, `omit` and `include` to determine which fields to return. |
Examples [#examples-13]
Update and return multiple users [#update-and-return-multiple-users]
```ts
const users = await prisma.user.updateManyAndReturn({
where: {
email: {
contains: "prisma.io",
},
},
data: {
role: "ADMIN",
},
});
```
```json
[
{ "id": 0, "name": "Sonali", "email": "sonali@prisma.io", "role": "ADMIN", "profileViews": 0 },
{ "id": 1, "name": "Alex", "email": "alex@prisma.io", "role": "ADMIN", "profileViews": 0 }
]
```
deleteMany() [#deletemany]
`deleteMany` deletes multiple records in a transaction.
Options [#options-14]
| Name | Type | Required | Description |
| ------- | ---------------- | -------- | ---------------------------------------------------------------------------- |
| `where` | `UserWhereInput` | No | Wraps *all* fields of a model so that the list can be filtered by any field. |
| `limit` | `Int` | No | Limits the number of records deleted. |
Return type [#return-type-11]
| Return type | Example | Description |
| -------------- | -------------- | ----------------------------- |
| `BatchPayload` | `{ count: 4 }` | The count of deleted records. |
```ts
export type BatchPayload = {
count: number;
};
```
Examples [#examples-14]
Delete all User records [#delete-all-user-records]
```ts
const deletedUserCount = await prisma.user.deleteMany({});
```
Delete all User records where the name is Alice [#delete-all-user-records-where-the-name-is-alice]
```ts
const deletedUserCount = await prisma.user.deleteMany({
where: { name: "Alice" },
});
```
Delete all User records where the email contains prisma.io, but limit to 5 records deleted. [#delete-all-user-records-where-the-email-contains-prismaio-but-limit-to-5-records-deleted]
```ts
const deletedUserCount = await prisma.user.deleteMany({
where: {
email: {
contains: "prisma.io",
},
},
limit: 5,
});
```
See [Filter conditions and operators](#filter-conditions-and-operators) for examples of how to filter the records to delete.
count() [#count]
Options [#options-15]
| Name | Type | Required | Description |
| --------- | ------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `where` | `UserWhereInput` | No | Wraps *all* model fields in a type so that the list can be filtered by any property. |
| `orderBy` | `XOR`ByInput>, PostOrderByInput>` | No | Lets you order the returned list by any property. |
| `cursor` | `UserWhereUniqueInput` | No | Specifies the position for the list (the value typically specifies an `id` or another unique value). |
| `take` | `number` | No | Specifies how many objects should be returned in the list (as seen from the *beginning* (positive value) or *end* (negative value) **either** of the list **or** from the `cursor` position if mentioned) |
| `skip` | `number` | No | Specifies how many of the returned objects in the list should be skipped. |
Return type [#return-type-12]
| Return type | Example | Description |
| ------------------------------ | ------------------------ | ----------------------------- |
| `number` | `29` | The count of records. |
| `UserCountAggregateOutputType` | `{ _all: 27, name: 10 }` | Returned if `select` is used. |
Examples [#examples-15]
Count all User records [#count-all-user-records]
```ts
const result = await prisma.user.count();
```
Count all User records with at least one published Post [#count-all-user-records-with-at-least-one-published-post]
```ts
const result = await prisma.user.count({
where: {
post: {
some: {
published: true,
},
},
},
});
```
Use select to perform three separate counts [#use-select-to-perform-three-separate-counts]
The following query returns:
* A count of all records (`_all`)
* A count of all records with non-`null` `name` fields
* A count of all records with non-`null` `city` fields
```ts
const c = await prisma.user.count({
select: {
_all: true,
city: true,
name: true,
},
});
```
aggregate() [#aggregate]
See also: [Aggregation, grouping, and summarizing](/orm/prisma-client/queries/aggregation-grouping-summarizing#aggregate)
Options [#options-16]
| Name | Type | Required | Description |
| --------- | ------------------------------------------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `where` | `UserWhereInput` | No | Wraps *all* model fields in a type so that the list can be filtered by any property. |
| `orderBy` | `XOR,` `UserOrderByInput>` | No | Lets you order the returned list by any property. |
| `cursor` | `UserWhereUniqueInput` | No | Specifies the position for the list (the value typically specifies an `id` or another unique value). |
| `take` | `number` | No | Specifies how many objects should be returned in the list (as seen from the *beginning* (positive value) or *end* (negative value) **either** of the list **or** from the `cursor` position if mentioned) |
| `skip` | `number` | No | Specifies how many of the returned objects in the list should be skipped. |
| `_count` | `true` | No | Returns a count of matching records or non-`null` fields. |
| `_avg` | `UserAvgAggregateInputType` | No | Returns an average of all values of the specified field. |
| `_sum` | `UserSumAggregateInputType` | No | Returns the sum of all values of the specified field. |
| `_min` | `UserMinAggregateInputType` | No | Returns the smallest available value of the specified field. |
| `_max` | `UserMaxAggregateInputType` | No | Returns the largest available value of the specified field. |
Examples [#examples-16]
Return _min, _max, and _count of profileViews of all User records [#return-_min-_max-and-_count-of-profileviews-of-all-user-records]
```ts
const minMaxAge = await prisma.user.aggregate({
_count: {
_all: true,
},
_max: {
profileViews: true,
},
_min: {
profileViews: true,
},
});
```
```json
{
_count: { _all: 29 },
_max: { profileViews: 90 },
_min: { profileViews: 0 }
}
```
Return _sum of all profileViews for all User records [#return-_sum-of-all-profileviews-for-all-user-records]
```ts
const setValue = await prisma.user.aggregate({
_sum: {
profileViews: true,
},
});
```
```json
{
"_sum": {
"profileViews": 9493
}
}
```
groupBy() [#groupby]
See also: [Aggregation, grouping, and summarizing](/orm/prisma-client/queries/aggregation-grouping-summarizing#group-by)
Options [#options-17]
| Name | Type | Required | Description |
| --------- | ------------------------------------------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `where` | `UserWhereInput` | No | Wraps *all* model fields in a type so that the list can be filtered by any property. |
| `orderBy` | `XOR,` `UserOrderByInput>` | No | Lets you order the returned list by any property that is also present in `by`. |
| `by` | `Array` \| `string` | No | Specifies the field or combination of fields to group records by. |
| `having` | `UserScalarWhereWithAggregatesInput` | No | Allows you to filter groups by an aggregate value - for example, only return groups *having* an average age less than 50. |
| `take` | `number` | No | Specifies how many objects should be returned in the list (as seen from the *beginning* (positive value) or *end* (negative value) **either** of the list **or** from the `cursor` position if mentioned) |
| `skip` | `number` | No | Specifies how many of the returned objects in the list should be skipped. |
| `_count` | `true` \| `UserCountAggregateInputType` | No | Returns a count of matching records or non-`null` fields. |
| `_avg` | `UserAvgAggregateInputType` | No | Returns an average of all values of the specified field. |
| `_sum` | `UserSumAggregateInputType` | No | Returns the sum of all values of the specified field. |
| `_min` | `UserMinAggregateInputType` | No | Returns the smallest available value of the specified field. |
| `_max` | `UserMaxAggregateInputType` | No | Returns the largest available value of the specified field. |
Examples [#examples-17]
Group by country/city where the average profileViews is greater than 200, and return the _sum of profileViews for each group [#group-by-countrycity-where-the-average-profileviews-is-greater-than-200-and-return-the-_sum-of-profileviews-for-each-group]
The query also returns a count of `_all` records in each group, and all records with non-`null` `city` field values in each group.
```ts
const groupUsers = await prisma.user.groupBy({
by: ["country", "city"],
_count: {
_all: true,
city: true,
},
_sum: {
profileViews: true,
},
orderBy: {
country: "desc",
},
having: {
profileViews: {
_avg: {
gt: 200,
},
},
},
});
```
```json
[
{
country: "Denmark",
city: "Copenhagen",
_sum: { profileViews: 490 },
_count: {
_all: 70,
city: 8,
},
},
{
country: "Sweden",
city: "Stockholm",
_sum: { profileViews: 500 },
_count: {
_all: 50,
city: 3,
},
},
];
```
findRaw() [#findraw]
See: [Using Raw SQL (`findRaw()`)](/orm/prisma-client/using-raw-sql/raw-queries#findraw).
aggregateRaw() [#aggregateraw]
See: [Using Raw SQL (`aggregateRaw()`)](/orm/prisma-client/using-raw-sql/raw-queries#aggregateraw).
Model query options [#model-query-options]
select [#select]
`select` defines which fields are included in the object that Prisma Client returns. See: [Select fields and include relations](/v6/orm/prisma-client/queries/select-fields) .
Remarks [#remarks-10]
* You cannot combine `select` and `include` on the same level.
* You can [select a `_count` of relations](#select-a-_count-of-relations).
Examples [#examples-18]
Select the name and profileViews fields of a single User record [#select-the-name-and-profileviews-fields-of-a-single-user-record]
```ts
const result = await prisma.user.findUnique({
where: { id: 1 },
select: {
name: true,
profileViews: true,
},
});
```
```json
{
name: "Alice",
profileViews: 0
}
```
Select the email and role fields of a multiple User records [#select-the-email-and-role-fields-of-a-multiple-user-records]
```ts
const result = await prisma.user.findMany({
select: {
email: true,
role: true,
},
});
```
```json
[
{
email: "alice@prisma.io",
role: "ADMIN",
},
{
email: "bob@prisma.io",
role: "USER",
},
];
```
Select a _count of relations [#select-a-_count-of-relations]
```ts
const usersWithCount = await prisma.user.findMany({
select: {
_count: {
select: { posts: true },
},
},
});
```
```json
{
_count: {
posts: 3;
}
}
```
Select the 'id' and 'title' fields of related Post records [#select-the-id-and-title-fields-of-related-post-records]
```ts
const result = await prisma.user.findMany({
select: {
id: true,
name: true,
posts: {
select: {
id: true,
title: true,
},
},
},
});
```
```ts
[
{
id: 1,
name: "Alice",
posts: [
{ id: 1, title: "Hello World" },
{ id: 2, title: "Bye bye" },
],
},
{
id: 2,
name: "Bob",
posts: [],
},
];
```
include inside select [#include-inside-select]
```ts
const result = await prisma.user.findMany({
select: {
id: true,
name: true,
posts: {
include: {
author: true,
},
},
},
});
```
```json
[
{
id: 1,
name: "Alice",
posts: [
{
id: 1,
title: "Hello World",
published: true,
author: {
id: 1,
name: "Alice",
email: "alice@prisma.io",
role: "ADMIN",
coinflips: [true, false],
profileViews: 0,
},
},
{
id: 2,
title: "Bye bye",
published: false,
author: {
id: 1,
name: "Alice",
email: "alice@prisma.io",
role: "USER",
coinflips: [],
profileViews: 0,
},
},
],
},
];
```
include [#include]
`include` defines which relations are included in the result that Prisma Client returns. See: [Select fields and include relations](/v6/orm/prisma-client/queries/select-fields) .
Remarks [#remarks-11]
* You can [`include` a `_count` of relations](#include-a-_count-of-relations).
Examples [#examples-19]
Include the posts and profile relation when loading User records [#include-the-posts-and-profile-relation-when-loading-user-records]
```ts
const users = await prisma.user.findMany({
include: {
posts: true, // Returns all fields for all posts
profile: true, // Returns all Profile fields
},
});
```
Include the posts relation on the returned objects when creating a new User record with two Post records [#include-the-posts-relation-on-the-returned-objects-when-creating-a-new-user-record-with-two-post-records]
```ts
const user = await prisma.user.create({
data: {
email: "alice@prisma.io",
posts: {
create: [{ title: "This is my first post" }, { title: "Here comes a second post" }],
},
},
include: { posts: true }, // Returns all fields for all posts
});
```
Generated types for include [#generated-types-for-include]
The following example demonstrates how to use TypeScript's `satisfies` operator with `include`:
```ts
const includePosts = { posts: true } satisfies Prisma.UserInclude;
```
Include a _count of relations [#include-a-_count-of-relations]
```ts
const usersWithCount = await prisma.user.findMany({
include: {
_count: {
select: { posts: true },
},
},
});
```
```json
{ id: 1, name: "Bob", email: "bob@prisma.io", _count: { posts: 3 } },
{ id: 2, name: "Enya", email: "enya@prisma.io", _count: { posts: 2 } }
```
omit [#omit]
`omit` defines which fields are excluded in the object that Prisma Client returns.
Remarks [#remarks-12]
* You cannot combine `omit` and `select` since they serve opposite purposes.
Examples [#examples-20]
Omit the password field from all User records [#omit-the-password-field-from-all-user-records]
```ts
const result = await prisma.user.findMany({
omit: {
password: true,
},
});
```
```json
[
{
id: 1,
email: "jenny@prisma.io",
name: "Jenny",
},
{
id: 2,
email: "rose@prisma.io",
name: "Rose",
},
];
```
Omit the title fields from all User's posts relation [#omit-the-title-fields-from-all-users-posts-relation]
```ts
const results = await prisma.user.findMany({
omit: {
password: true,
},
include: {
posts: {
omit: {
title: true,
},
},
},
});
```
```json
[
{
id: 1,
email: "jenny@prisma.io",
name: "Jenny",
posts: [
{
id: 1,
author: {
id: 1,
email: "jenny@prisma.io",
name: "Jenny",
},
authorId: 1,
},
],
},
{
id: 2,
email: "rose@prisma.io",
name: "Rose",
posts: [
{
id: 2,
author: {
id: 2,
email: "rose@prisma.io",
name: "Rose",
},
authorId: 2,
},
],
},
];
```
Generated types for omit [#generated-types-for-omit]
The following example demonstrates how to use TypeScript's `satisfies` operator with `omit`:
```ts
const omitPassword = { password: true } satisfies Prisma.UserOmit;
```
relationLoadStrategy (Preview) [#relationloadstrategy-preview]
`relationLoadStrategy` specifies how a relation should be loaded from the database. It has two possible values:
* `join` (default): Uses a database-level `LATERAL JOIN` (PostgreSQL) or correlated subqueries (MySQL) and fetches all data with a single query to the database.
* `query`: Sends multiple queries to the database (one per table) and joins them on the application level.
> **Note**: Once `relationLoadStrategy` moves from [Preview](/orm/more/releases#preview) into [General Availability](/orm/more/releases#generally-available-ga), `join` will universally become the default for all relation queries.
You can learn more about join strategies [here](/orm/prisma-client/queries/relation-queries#relation-load-strategies-preview).
Because the `relationLoadStrategy` option is currently in Preview, you need to enable it via the `relationJoins` preview feature flag in your Prisma schema file:
```prisma
generator client {
provider = "prisma-client"
output = "./generated"
previewFeatures = ["relationJoins"]
}
```
After adding this flag, you need to run `prisma generate` again to re-generate Prisma Client. The `relationJoins` feature is currently available on PostgreSQL, CockroachDB and MySQL.
Remarks [#remarks-13]
* In most situations, the default `join` strategy will be more effective. Use `query` if you want to save resources on your database server or if you profiling shows that the application-level join is more performant.
* You can only specify the `relationLoadStrategy` on the top-level in your query. The top-level choice will affect all nested sub-queries.
Examples [#examples-21]
Load the posts relation via a database-level JOIN when using include [#load-the-posts-relation-via-a-database-level-join-when-using-include]
```ts
const users = await prisma.user.findMany({
relationLoadStrategy: "join",
include: {
posts: true,
},
});
```
Load the posts relation via a database-level JOIN when using select [#load-the-posts-relation-via-a-database-level-join-when-using-select]
```ts
const users = await prisma.user.findMany({
relationLoadStrategy: "join",
select: {
posts: true,
},
});
```
where [#where]
`where` defines one or more [filters](#filter-conditions-and-operators), and can be used to filter on record properties (like a user's email address) or related record properties (like a user's top 10 most recent post titles).
Examples [#examples-22]
```ts
const results = await prisma.user.findMany({
where: {
email: {
endsWith: "prisma.io",
},
},
});
```
Generated types for where [#generated-types-for-where]
The following examples demonstrate how to use TypeScript's `satisfies` operator with `where`:
* `UserWhereInput`
```ts
// UserWhereInput
const whereNameIs = { name: "Rich" } satisfies Prisma.UserWhereInput;
// It can be combined with conditional operators too
const whereNameIsWithAnd = {
name: "Rich",
AND: [
{
email: {
contains: "rich@boop.com",
},
},
],
} satisfies Prisma.UserWhereInput;
```
* `UserWhereUniqueInput` This type works by exposing any unique fields on the model. A field assigned `@id` is considered unique,
as is one assigned `@unique`.
This type exposes all fields on the model. This means that when you filter for a single record based on a unique field, you can check additional non-unique and unique fields at the same time. [Learn more](#filter-on-non-unique-fields-with-userwhereuniqueinput).
```ts
// UserWhereUniqueInput
const whereEmailIsUnique = { email: "rich@boop.com" } satisfies Prisma.UserWhereUniqueInput;
```
* `PostScalarWhereInput`
```ts
const whereScalarTitleIs = { title: "boop" } satisfies Prisma.PostScalarWhereInput;
```
* `PostUpdateWithWhereUniqueWithoutAuthorInput` - This type accepts a unique `where` field (an `@id` or another assigned `@unique`)
and updates any field on the `Post` model except the `Author`. The `Author` is the scalar field on the `Post` model.
```ts
const updatePostByIdWithoutAuthor = {
where: { id: 1 },
data: {
content: "This is some updated content",
published: true,
title: "This is a new title",
},
} satisfies Prisma.PostUpdateWithWhereUniqueWithoutAuthorInput;
```
* `PostUpsertWithWhereUniqueWithoutAuthorInput` - This type will update the `Post` records title field where the id matches, if it doesn't exist it will create it instead.
```ts
const updatePostTitleOrCreateIfNotExist = {
where: { id: 1 },
update: { title: "This is a new title" },
create: {
id: 1,
title: "If the title doesn't exist, then create one with this text",
},
} satisfies Prisma.PostUpsertWithWhereUniqueWithoutAuthorInput;
```
* `PostUpdateManyWithWhereWithoutAuthorInput` - This type will update all `Post` records where published is set to false.
```ts
const publishAllPosts = {
where: { published: { equals: false } },
data: { published: true },
} satisfies Prisma.PostUpdateManyWithWhereWithoutAuthorInput;
```
orderBy [#orderby]
Sorts a list of records. See also: [Sorting](/v6/orm/prisma-client/queries/filtering-and-sorting)
Remarks [#remarks-14]
* You can [order by relation fields](#sort-post-by-the-related-user-records-name) - for example, order posts by the author's name.
* In PostgreSQL you can [order by relevance](#sort-post-by-relevance-of-the-title). For details, see [Sort by relevance](/v6/orm/prisma-client/queries/filtering-and-sorting#sort-by-relevance-postgresql-and-mysql).
* You can [sort `null` records first or last](#sort-post-by-the-related-user-records-name-with-null-records-first). For details, see [Sort with nulls first or last](/v6/orm/prisma-client/queries/filtering-and-sorting#sort-with-null-records-first-or-last).
Inputs for sort argument [#inputs-for-sort-argument]
| Name | Description |
| ------ | ----------------------- |
| `asc` | Sort ascending (A → Z) |
| `desc` | Sort descending (Z → A) |
Inputs for nulls argument [#inputs-for-nulls-argument]
Note:
* This argument is optional.
* For use on optional [scalar](/orm/prisma-schema/data-model/models#scalar-fields) fields only. If you try to sort by nulls on a required or [relation](/orm/prisma-schema/data-model/models#relation-fields) field, Prisma Client throws a [P2009 error](/orm/reference/error-reference#p2009).
| Name | Description |
| ------- | ------------------------------ |
| `first` | Sort with `null` values first. |
| `last` | Sort with `null` values last. |
Examples [#examples-23]
Sort User by email field [#sort-user-by-email-field]
The following example returns all `User` records sorted by `email` ascending:
```ts
const users = await prisma.user.findMany({
orderBy: {
email: "asc",
},
});
```
The following example returns all `User` records sorted by `email` descending:
```ts
const users = await prisma.user.findMany({
orderBy: {
email: "desc",
},
});
```
Sort Post by the related User record's name [#sort-post-by-the-related-user-records-name]
The following query orders posts by user name:
```ts
const posts = await prisma.post.findMany({
orderBy: {
author: {
name: "asc",
},
},
});
```
Sort Post by the related User record's name, with null records first [#sort-post-by-the-related-user-records-name-with-null-records-first]
The following query orders posts by user name, with `null` records first:
```ts
const posts = await prisma.post.findMany({
orderBy: {
author: {
name: { sort: "asc", nulls: "first" },
},
},
});
```
Sort Post by relevance of the title [#sort-post-by-relevance-of-the-title]
For PostgreSQL, this feature is still in Preview. [Enable the `fullTextSearchPostgres` feature flag](/v6/orm/prisma-client/queries/full-text-search#enabling-full-text-search-for-postgresql) in order to use it.
The following query orders posts by relevance of the search term `'database'` to the title:
```ts
const posts = await prisma.post.findMany({
orderBy: {
_relevance: {
fields: ['title'],
search: 'database',
sort: 'asc'
},
})
```
Sort User by the posts count [#sort-user-by-the-posts-count]
The following query orders users by post count:
```ts
const getActiveusers = await prisma.user.findMany({
orderBy: {
posts: {
count: "desc",
},
},
});
```
Sort User by multiple fields - email and role [#sort-user-by-multiple-fields---email-and-role]
The following example sorts users by two fields - first `email`, then `role`:
```ts
const users = await prisma.user.findMany({
select: {
email: true,
role: true,
},
orderBy: [
{
email: "desc",
},
{
role: "desc",
},
],
});
```
```json
[
{
"email": "yuki@prisma.io",
"role": "USER"
},
{
"email": "nora@prisma.io",
"role": "USER"
},
{
"email": "mary@prisma.io",
"role": "MODERATOR"
},
{
"email": "elsa@prisma.io",
"role": "MODERATOR"
},
{
"email": "eloise@prisma.io",
"role": "USER"
},
{
"email": "coco@prisma.io",
"role": "ADMIN"
},
{
"email": "anna@prisma.io",
"role": "USER"
},
{
"email": "alice@prisma.io",
"role": "USER"
}
]
```
The order of sorting parameters matters - the following query sorts by `role`, then `email`. Note the difference in the results:
```ts
const users = await prisma.user.findMany({
select: {
email: true,
role: true,
},
orderBy: [
{
role: "desc",
},
{
email: "desc",
},
],
});
```
```json
[
{
"email": "mary@prisma.io",
"role": "MODERATOR"
},
{
"email": "elsa@prisma.io",
"role": "MODERATOR"
},
{
"email": "yuki@prisma.io",
"role": "USER"
},
{
"email": "nora@prisma.io",
"role": "USER"
},
{
"email": "eloise@prisma.io",
"role": "USER"
},
{
"email": "anna@prisma.io",
"role": "USER"
},
{
"email": "alice@prisma.io",
"role": "USER"
},
{
"email": "coco@prisma.io",
"role": "ADMIN"
}
]
```
Sort User by email, select name and email [#sort-user-by-email-select-name-and-email]
The following example returns all the `name` and `email` fields of all `User` records, sorted by `email`:
```ts
const users3 = await prisma.user.findMany({
orderBy: {
email: "asc",
},
select: {
name: true,
email: true,
},
});
```
```json
[
{
name: "Alice",
email: "alice@prisma.io",
},
{
name: "Ariadne",
email: "ariadne@prisma.io",
},
{
name: "Bob",
email: "bob@prisma.io",
},
];
```
Sort User records by email and sort nested Post records by title [#sort-user-records-by-email-and-sort-nested-post-records-by-title]
The following example:
* Returns all `User` records sorted by `email`
* For each `User` record, returns the `title` field of all nested `Post` records sorted by `title`
```ts
const usersWithPosts = await prisma.user.findMany({
orderBy: {
email: "asc",
},
include: {
posts: {
select: {
title: true,
},
orderBy: {
title: "asc",
},
},
},
});
```
```json
[
{
"id": 2,
"email": "alice@prisma.io",
"name": "Alice",
"posts": [
{
"title": "Watch the talks from Prisma Day 2019"
}
]
},
{
"id": 3,
"email": "ariadne@prisma.io",
"name": "Ariadne",
"posts": [
{
"title": "How to connect to a SQLite database"
},
{
"title": "My first day at Prisma"
}
]
},
{
"id": 1,
"email": "bob@prisma.io",
"name": "Bob",
"posts": [
{
"title": "Follow Prisma on Twitter"
},
{
"title": "Subscribe to GraphQL Weekly for community news "
}
]
}
]
```
Sort one user's nested list of Post records [#sort-one-users-nested-list-of-post-records]
The following example retrieves a single `User` record by ID, as well as a list of nested `Post` records sorted by `title`:
```ts
const userWithPosts = await prisma.user.findUnique({
where: {
id: 1,
},
include: {
posts: {
orderBy: {
title: "desc",
},
select: {
title: true,
published: true,
},
},
},
});
```
```json
{
"email": "sarah@prisma.io",
"id": 1,
"name": "Sarah",
"extendedProfile": null,
"role": "USER",
"posts": [
{
"title": "Prisma Day 2020",
"published": false
},
{
"title": "My first post",
"published": false
},
{
"title": "All about databases",
"published": true
}
]
}
```
Sort by enum [#sort-by-enum]
The following sorts all `User` records by `role` (an `enum`):
```ts
const sort = await prisma.user.findMany({
orderBy: {
role: "desc",
},
select: {
email: true,
role: true,
},
});
```
```json
[
{
"email": "emma@prisma.io",
"role": "USER"
},
{
"email": "suma@prisma.io",
"role": "ADMIN"
},
{
"email": "kwame@prisma.io",
"role": "ADMIN"
},
{
"email": "pearl@prisma.io",
"role": "ADMIN"
}
]
```
Generated types for orderBy [#generated-types-for-orderby]
The following examples demonstrate how to use TypeScript's `satisfies` operator with `orderBy`:
* `UserOrderByInput`
```ts
const orderEmailsByDescending = { email: "desc" } satisfies Prisma.UserOrderByInput;
```
distinct [#distinct]
Deduplicate a list of records from [`findMany`](#findmany) or [`findFirst`](#findfirst). See also: [Aggregation, grouping, and summarizing](/orm/prisma-client/queries/aggregation-grouping-summarizing#select-distinct)
Examples [#examples-24]
Select distinct on a single field [#select-distinct-on-a-single-field]
The following example returns all distinct `city` fields, and selects only the `city` and `country` fields:
```ts
const distinctCities = await prisma.user.findMany({
select: {
city: true,
country: true,
},
distinct: ["city"],
});
```
```json
[
{ city: "Paris", country: "France" },
{ city: "Lyon", country: "France" },
];
```
Select distinct on multiple fields [#select-distinct-on-multiple-fields]
The following example returns all distinct `city` *and* `country` field combinations, and selects only the `city` and `country` fields:
```ts
const distinctCitiesAndCountries = await prisma.user.findMany({
select: {
city: true,
country: true,
},
distinct: ["city", "country"],
});
```
```json
[
{ city: "Paris", country: "France" },
{ city: "Paris", country: "Denmark" },
{ city: "Lyon", country: "France" },
];
```
Note that there is now a "Paris, Denmark" in addition to "Paris, France":
Select distinct in combination with a filter [#select-distinct-in-combination-with-a-filter]
The following example returns all distinct `city` *and* `country` field combinations where the user's email contains `"prisma.io"`, and selects only the `city` and `country` fields:
```ts
const distinctCitiesAndCountries = await prisma.user.findMany({
where: {
email: {
contains: "prisma.io",
},
},
select: {
city: true,
country: true,
},
distinct: ["city", "country"],
});
```
```json
[
{ city: "Paris", country: "Denmark" },
{ city: "Lyon", country: "France" },
];
```
nativeDistinct [#nativedistinct]
Enabling `nativeDistinct` in your Prisma schema pushes the `distinct` operation to the database layer
(where supported). This can significantly improve performance. However, note that:
* Some databases may not fully support DISTINCT on certain field combinations.
* Behavior can differ among providers.
To enable `nativeDistinct`:
```prisma
generator client {
provider = "prisma-client"
output = "./generated"
previewFeatures = ["nativeDistinct"]
}
```
See [Preview Features](/orm/reference/preview-features/client-preview-features#preview-features-promoted-to-general-availability) for more details.
Nested queries [#nested-queries]
create [#create-1]
A nested `create` query adds a new related record or set of records to a parent record. See: [Working with relations](/orm/prisma-client/queries/relation-queries)
Remarks [#remarks-15]
* `create` is available as a nested query when you `create()` (`prisma.user.create(...)`) a new parent record or `update()` (`prisma.user.update(...)`) an existing parent record.
* You can use a nested `create` *or* a nested [`createMany`](#createmany-1) to create multiple related records. If you require the [`skipDuplicates` query option](#nested-createmany-options) you should use `createMany`.
Examples [#examples-25]
Create a new User record with a new Profile record [#create-a-new-user-record-with-a-new-profile-record]
```ts highlight=5;normal
const user = await prisma.user.create({
data: {
email: 'alice@prisma.io',
profile: {
create: { bio: 'Hello World' },
},
},
});
```
Create a new Profile record with a new User record [#create-a-new-profile-record-with-a-new-user-record]
```ts
const user = await prisma.profile.create({
data: {
bio: "Hello World",
user: {
create: { email: "alice@prisma.io" }, // [!code highlight]
},
},
});
```
Create a new User record with a new Post record [#create-a-new-user-record-with-a-new-post-record]
```ts highlight=5;normal
const user = await prisma.user.create({
data: {
email: "alice@prisma.io",
posts: {
create: { title: "Hello World" },
},
},
});
```
Create a new User record with two new Post records [#create-a-new-user-record-with-two-new-post-records]
Because it's a one-to-many relation, you can also create multiple `Post` records at once by passing an array to `create`:
```ts highlight=5-12;normal
const user = await prisma.user.create({
data: {
email: "alice@prisma.io",
posts: {
create: [
{
title: "This is my first post",
},
{
title: "Here comes a second post",
},
],
},
},
});
```
Note: You can also use a nested [`createMany`](#createmany-1) to achieve the same result.
Update an existing User record by creating a new Profile record [#update-an-existing-user-record-by-creating-a-new-profile-record]
```ts highlight=5;normal;
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
profile: {
create: { bio: "Hello World" },
},
},
});
```
Update an existing User record by creating a new Post record [#update-an-existing-user-record-by-creating-a-new-post-record]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
posts: {
create: { title: "Hello World" }, // [!code highlight]
},
},
});
```
createMany [#createmany-1]
A nested `createMany` query adds a new set of records to a parent record. See: [Working with relations](/orm/prisma-client/queries/relation-queries)
Remarks [#remarks-16]
* `createMany` is available as a nested query when you `create()` (`prisma.user.create(...)`) a new parent record or `update()` (`prisma.user.update(...)`) an existing parent record.
* Available in the context of a one-to-many relation — for example, you can `prisma.user.create(...)` a user and use a nested `createMany` to create multiple posts (posts have one user).
* **Not** available in the context of a many-to-many relation — for example, you **cannot** `prisma.post.create(...)` a post and use a nested `createMany` to create categories (many posts have many categories).
* You cannot nest an additional `create` or `createMany`.
* Allows setting foreign keys directly — for example, setting the `categoryId` on a post.
* Nested `createMany` is supported by SQLite.
* You can use a nested `create` *or* a nested `createMany` to create multiple related records - [if you do not need the `skipDuplicates` query option, you should probably use `create`](/orm/prisma-client/queries/relation-queries#create-a-single-record-and-multiple-related-records).
Options [#nested-createmany-options]
| Name | Type | Required | Description |
| ----------------- | --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Enumerable` | **Yes** | Wraps all the model fields in a type so that they can be provided when creating new records. Fields that are marked as optional or have default values in the datamodel are optional. |
| `skipDuplicates?` | `boolean` | No | Do not insert records with unique fields or ID fields that already exist. Only supported by databases that support [`ON CONFLICT DO NOTHING`](https://www.postgresql.org/docs/9.5/sql-insert.html#SQL-ON-CONFLICT). This excludes MongoDB and SQLServer |
Examples [#examples-26]
Update a User and multiple new related Post records [#update-a-user-and-multiple-new-related-post-records]
```ts
const user = await prisma.user.update({
where: {
id: 9,
},
data: {
name: "Elliott",
posts: {
createMany: {
data: [{ title: "My first post" }, { title: "My second post" }],
},
},
},
});
```
set [#set]
`set` overwrites the value of a relation - for example, replacing a list of `Post` records with a different list. See: [Working with relations](/orm/prisma-client/queries/relation-queries)
Examples [#examples-27]
Update an existing User record by disconnecting any previous Post records and connecting two other existing ones [#update-an-existing-user-record-by-disconnecting-any-previous-post-records-and-connecting-two-other-existing-ones]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
posts: {
set: [{ id: 32 }, { id: 42 }],
},
},
});
```
connect [#connect]
A nested `connect` query connects a record to an existing related record by specifying an ID or unique identifier. See: [Working with relations](/orm/prisma-client/queries/relation-queries)
Remarks [#remarks-17]
* `connect` is available as a nested query when you create a new parent record or update an existing parent record.
* If the related record does not exist, Prisma Client throws an exception:
```
The required connected records were not found. Expected 1 records to be connected, found 0.
```
* When using `set` and `connect` together, the order in which they are applied significantly impacts the result. If `set` is used before `connect`, the connected records will only reflect the final state established by the `connect` operation, as `set` clears all existing connections before `connect` establishes new ones. Conversely, if `connect` is applied before `set`, the `set` operation will override the `connect` action by clearing all connected records and replacing them with its own specified state.
Examples [#examples-28]
Create a new Profile record and connect it to an existing User record via unique field [#create-a-new-profile-record-and-connect-it-to-an-existing-user-record-via-unique-field]
```ts
const user = await prisma.profile.create({
data: {
bio: "Hello World",
user: {
connect: { email: "alice@prisma.io" },
},
},
});
```
Create a new Profile record and connect it to an existing User record via an ID field [#create-a-new-profile-record-and-connect-it-to-an-existing-user-record-via-an-id-field]
```ts
const user = await prisma.profile.create({
data: {
bio: "Hello World",
user: {
connect: { id: 42 }, // sets userId of Profile record
},
},
});
```
You can also set the foreign key directly:
```ts
const user = await prisma.profile.create({
data: {
bio: "Hello World",
userId: 42,
},
});
```
However, you can't use both the direct approach and the `connect` approach in the same query. See [this issue comment](https://github.com/prisma/prisma/issues/4322#issuecomment-737976117) for details.
Create a new Post record and connect it to an existing User record [#create-a-new-post-record-and-connect-it-to-an-existing-user-record]
```ts
const user = await prisma.post.create({
data: {
title: "Hello World",
author: {
connect: { email: "alice@prisma.io" },
},
},
});
```
Update an existing User record by connecting it to an existing Profile record [#update-an-existing-user-record-by-connecting-it-to-an-existing-profile-record]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
profile: {
connect: { id: 24 },
},
},
});
```
Update an existing User record by connecting it to two existing Post records [#update-an-existing-user-record-by-connecting-it-to-two-existing-post-records]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
posts: {
connect: [{ id: 24 }, { id: 42 }],
},
},
});
```
connectOrCreate [#connectorcreate]
`connectOrCreate` *either* connects a record to an existing related record by ID or unique identifier *or* creates a new related record if the record does not exist. See: [Working with relations](/orm/prisma-client/queries/relation-queries)
Remarks [#remarks-18]
Multiple `connectOrCreate` queries that run as concurrent transactions can result in a **race condition**. Consider the following example, where two queries attempt to `connectOrCreate` a blog post tag named `computing` at the same time (tag names must be unique):
Query A
Query B
```ts
const createPost = await prisma.post.create({
data: {
title: "How to create a compiler",
content: "...",
author: {
connect: {
id: 9,
},
},
tags: {
connectOrCreate: {
create: {
name: "computing",
},
where: {
name: "computing",
},
},
},
},
});
```
```ts
const createPost = await prisma.post.create({
data: {
title: "How to handle schema drift in production",
content: "...",
author: {
connect: {
id: 15,
},
},
tags: {
connectOrCreate: {
create: {
name: "computing",
},
where: {
name: "computing",
},
},
},
},
});
```
If query A and query B overlap in the following way, query A results in an exception:
| Query A (Fail ❌) | Query B (Success ✅) |
| :--------------------------------------------------------------- | :--------------------------------------------------------------- |
| Query hits server, starts transaction A | Query hits server, starts transaction B |
| | Find record where `tagName` equals `computing`, record not found |
| Find record where `tagName` equals `computing`, record not found | |
| | Create record where `tagName` equals `computing` and connect |
| Create record where `tagName` equals `computing` | |
| Unique violation, record already created by transaction B | |
To work around this scenario, we recommend catching the unique violation exception (`PrismaClientKnownRequestError`, error `P2002`) and retrying failed queries.
Examples [#examples-29]
Create a new Profile record, then connect it to an existing User record or create a new User [#create-a-new-profile-record-then-connect-it-to-an-existing-user-record-or-create-a-new-user]
The following example:
1. Creates a `Profile`
2. Attempts to connect the profile to a `User` where the email address is `alice@prisma.io`
3. Creates a new user if a matching user does not exist
```ts
const user = await prisma.profile.create({
data: {
bio: 'The coolest Alice on the planet',
user: {
connectOrCreate: {
where: { email: 'alice@prisma.io' },
create: { email: 'alice@prisma.io'}
},
},
})
```
Create a new Post record and connect it to an existing User record, or create a new User [#create-a-new-post-record-and-connect-it-to-an-existing-user-record-or-create-a-new-user]
```ts
const user = await prisma.post.create({
data: {
title: "Hello World",
author: {
connectOrCreate: {
where: { email: "alice@prisma.io" },
create: { email: "alice@prisma.io" },
},
},
},
});
```
Update an existing User record by connecting it to an existing Profile record, or creating a new Profile record [#update-an-existing-user-record-by-connecting-it-to-an-existing-profile-record-or-creating-a-new-profile-record]
The following example:
1. Attempts to connect the user to a `Profile` with an `id` of `20`
2. Creates a new profile if a matching profile does not exist
```ts
const updateUser = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
profile: {
connectOrCreate: {
where: { id: 20 },
create: {
bio: "The coolest Alice in town",
},
},
},
},
});
```
Update an existing User record by connect it to two existing Post records, or creating two new Post records [#update-an-existing-user-record-by-connect-it-to-two-existing-post-records-or-creating-two-new-post-records]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
posts: {
connectOrCreate: [
{
where: { id: 32 },
create: { title: "This is my first post" },
},
{
where: { id: 19 },
create: { title: "This is my second post" },
},
],
},
},
});
```
disconnect [#disconnect]
A nested `disconnect` query breaks the connection between a parent record and a related record, but does not delete either record. See: [Working with relations](/orm/prisma-client/queries/relation-queries)
Remarks [#remarks-19]
* `disconnect` is only available if the relation is optional.
* If the relationship you are attempting to disconnect does not exist, the operation does nothing.
Examples [#examples-30]
Update an existing User record by disconnecting the Profile record it's connected to [#update-an-existing-user-record-by-disconnecting-the-profile-record-its-connected-to]
```ts
const user = await prisma.user.update({
where: { email: "bob@prisma.io" },
data: {
profile: {
disconnect: true,
},
},
});
```
Update an existing User record by disconnecting two Post records it's connected to [#update-an-existing-user-record-by-disconnecting-two-post-records-its-connected-to]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
posts: {
disconnect: [{ id: 44 }, { id: 46 }],
},
},
});
```
update [#update-1]
A nested `update` query updates one or more related records where the parent record's ID is `n`. See: [Working with relations](/orm/prisma-client/queries/relation-queries#update-a-specific-related-record)
Remarks [#remarks-20]
* Nested `update` queries are only available in the context of a top-level `update` query (for example, `prisma.user.update(...)`).
* If the parent record does not exist, Prisma Client throws an exception:
```
AssertionError("Expected a valid parent ID to be present for nested update to-one case.")
```
* If the related record that you want to update does not exist, Prisma Client throws an exception:
```
AssertionError("Expected a valid parent ID to be present for nested update to-one case.")
```
Examples [#examples-31]
Update an existing User record by updating the Profile record it's connected to [#update-an-existing-user-record-by-updating-the-profile-record-its-connected-to]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
profile: {
update: { bio: "Hello World" },
},
},
});
```
Update an existing User record by updating two Post records it's connected to [#update-an-existing-user-record-by-updating-two-post-records-its-connected-to]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
posts: {
update: [
{
data: { published: true },
where: { id: 32 },
},
{
data: { published: true },
where: { id: 23 },
},
],
},
},
});
```
upsert [#upsert-1]
This section covers the usage of nested upsert within `update()`. To learn about the [`upsert()`](#upsert) operation, reference the linked documentation.
A nested `upsert` query updates a related record if it exists, or creates a new related record.
Examples [#examples-32]
Update an existing User record by updating the Profile record it's connected to or creating a new one (upsert) [#update-an-existing-user-record-by-updating-the-profile-record-its-connected-to-or-creating-a-new-one-upsert]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
profile: {
upsert: {
create: { bio: "Hello World" },
update: { bio: "Hello World" },
},
},
},
});
```
Update an existing User record by updating two Post record it's connected to or creating new ones (upsert) [#update-an-existing-user-record-by-updating-two-post-record-its-connected-to-or-creating-new-ones-upsert]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
posts: {
upsert: [
{
create: { title: "This is my first post" },
update: { title: "This is my first post" },
where: { id: 32 },
},
{
create: { title: "This is my second post" },
update: { title: "This is my second post" },
where: { id: 23 },
},
],
},
},
});
```
delete [#delete-1]
A nested `delete` query deletes a related record. The parent record is not deleted.
Remarks [#remarks-21]
* `delete` is only available if the relation is optional.
Examples [#examples-33]
Update an existing User record by deleting the Profile record it's connected to [#update-an-existing-user-record-by-deleting-the-profile-record-its-connected-to]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
profile: {
delete: true,
},
},
});
```
Update an existing User record by deleting two Post records it's connected to [#update-an-existing-user-record-by-deleting-two-post-records-its-connected-to]
```ts
const user = await prisma.user.update({
where: { email: "alice@prisma.io" },
data: {
posts: {
delete: [{ id: 34 }, { id: 36 }],
},
},
});
```
updateMany [#updatemany-1]
A nested `updateMany` updates a list of related records and supports filtering - for example, you can update a user's unpublished posts.
Examples [#examples-34]
Update all unpublished posts belonging to a specific user [#update-all-unpublished-posts-belonging-to-a-specific-user]
```ts
const result = await prisma.user.update({
where: {
id: 2,
},
data: {
posts: {
updateMany: {
where: {
published: false,
},
data: {
likes: 0,
},
},
},
},
});
```
deleteMany [#deletemany-1]
A nested `deleteMany` deletes related records and supports filtering. For example, you can delete a user's posts while updating other properties of that user.
Examples [#examples-35]
Delete all posts belonging to a specific user as part of an update [#delete-all-posts-belonging-to-a-specific-user-as-part-of-an-update]
```ts
const result = await prisma.user.update({
where: {
id: 2,
},
data: {
name: "Updated name",
posts: {
deleteMany: {},
},
},
});
```
Filter conditions and operators [#filter-conditions-and-operators]
equals [#equals]
Value equals `n`.
Examples [#examples-36]
**Return all users where `name` equals `"Eleanor"`**
```ts
const result = await prisma.user.findMany({
where: {
name: {
equals: "Eleanor",
},
},
});
```
You can also exclude the `equals`:
```ts
const result = await prisma.user.findMany({
where: {
name: "Eleanor",
},
});
```
**Return all products with a quantity lower than the "warn quantity" threshold**
This example compares fields of the same model.
```ts
const productsWithLowQuantity = await prisma.product.findMany({
where: {
quantity: {
lte: prisma.product.fields.warnQuantity,
},
},
});
```
**Return all users that have blue and green as their favorite colors**
This example finds users that have set their `favoriteColors` field to `['blue', 'green']`.
Note that when using `equals`, order of elements matters. That is to say `['blue', 'green']` is **not** equal to `['green', 'blue']`
```ts
const favoriteColorFriends = await prisma.user.findMany({
where: {
favoriteColors: {
equals: ["blue", "green"],
},
},
});
```
not [#not]
Value does not equal `n`.
Examples [#examples-37]
Return all users where name does not equal "Eleanor" [#return-all-users-where-name-does-not-equal-eleanor]
```ts
const result = await prisma.user.findMany({
where: {
name: {
not: "Eleanor",
},
},
});
```
`not` will return all items that do not match a given value. However, if the column is nullable, `NULL` values will not be returned. If you require null values to be returned, use an [`OR`](#or) operator to include `NULL` values.
Return all users where name does not equal "Eleanor" including users where name is NULL [#return-all-users-where-name-does-not-equal-eleanor-including-users-where-name-is-null]
```ts
await prisma.user.findMany({
where: {
OR: [{ name: { not: "Eleanor" } }, { name: null }],
},
});
```
in [#in]
Value `n` exists in list.
`null` values are not returned. For example, if you combine `in` and `NOT` to return a user whose name is *not* in the list, users with `null` value names are not returned.
Examples [#examples-38]
Get User records where the id can be found in the following list: [22, 91, 14, 2, 5] [#get-user-records-where-the-id-can-be-found-in-the-following-list-22-91-14-2-5]
```ts
const getUser = await prisma.user.findMany({
where: {
id: { in: [22, 91, 14, 2, 5] },
},
});
```
Get User records where the name can be found in the following list: ['Saqui', 'Clementine', 'Bob'] [#get-user-records-where-the-name-can-be-found-in-the-following-list-saqui-clementine-bob]
```ts
const getUser = await prisma.user.findMany({
where: {
name: { in: ["Saqui", "Clementine", "Bob"] },
},
});
```
Get User records where name is not present in the list [#get-user-records-where-name-is-not-present-in-the-list]
The following example combines `in` and [`NOT`](#not). You can also use [`notIn`](#notin).
```ts
const getUser = await prisma.user.findMany({
where: {
NOT: {
name: { in: ["Saqui", "Clementine", "Bob"] },
},
},
});
```
Get a User record where at least one Post has at least one specified Category [#get-a-user-record-where-at-least-one-post-has-at-least-one-specified-category]
```ts
const getUser = await prisma.user.findMany({
where: {
// Find users where..
posts: {
some: {
// ..at least one (some) posts..
categories: {
some: {
// .. have at least one category ..
name: {
in: ["Food", "Introductions"], // .. with a name that matches one of the following.
},
},
},
},
},
},
});
```
notIn [#notin]
Value `n` does not exist in list.
Remarks [#remarks-22]
* `null` values are not returned.
Examples [#examples-39]
Get User records where the id can not be found in the following list: [22, 91, 14, 2, 5] [#get-user-records-where-the-id-can-not-be-found-in-the-following-list-22-91-14-2-5]
```ts
const getUser = await prisma.user.findMany({
where: {
id: { notIn: [22, 91, 14, 2, 5] },
},
});
```
lt [#lt]
Value `n` is less than `x`.
Examples [#examples-40]
Get all Post records where likes is less than 9 [#get-all-post-records-where-likes-is-less-than-9]
```ts
const getPosts = await prisma.post.findMany({
where: {
likes: {
lt: 9,
},
},
});
```
lte [#lte]
Value `n` is less than *or* equal to `x`.
Examples [#examples-41]
Get all Post records where likes is less or equal to 9 [#get-all-post-records-where-likes-is-less-or-equal-to-9]
```ts
const getPosts = await prisma.post.findMany({
where: {
likes: {
lte: 9,
},
},
});
```
gt [#gt]
Value `n` is greater than `x`.
Examples [#examples-42]
Get all Post records where likes is greater than 9 [#get-all-post-records-where-likes-is-greater-than-9]
```ts
const getPosts = await prisma.post.findMany({
where: {
likes: {
gt: 9,
},
},
});
```
gte [#gte]
Value `n` is greater than *or* equal to `x`.
Examples [#examples-43]
Get all Post records where likes is greater than or equal to 9 [#get-all-post-records-where-likes-is-greater-than-or-equal-to-9]
```ts
const getPosts = await prisma.post.findMany({
where: {
likes: {
gte: 9,
},
},
});
```
Examples [#examples-44]
Get all Post records where date_created is greater than March 19th, 2020 [#get-all-post-records-where-date_created-is-greater-than-march-19th-2020]
```js
const result = await prisma.post.findMany({
where: {
date_created: {
gte: new Date("2020-03-19T14:21:00+0200") /* Includes time offset for UTC */,
},
},
});
```
contains [#contains]
Value `n` contains `x`.
Examples [#examples-45]
Count all Post records where content contains databases [#count-all-post-records-where-content-contains-databases]
```js
const result = await prisma.post.count({
where: {
content: {
contains: "databases",
},
},
});
```
Count all Post records where content does not contain databases [#count-all-post-records-where-content-does-not-contain-databases]
```js
const result = await prisma.post.count({
where: {
NOT: {
content: {
contains: "databases",
},
},
},
});
```
search [#search]
Use [Full-Text Search](/v6/orm/prisma-client/queries/full-text-search) to search within a `String` field.
For PostgreSQL, this feature is still in Preview. [Enable the `fullTextSearchPostgres` feature flag](/v6/orm/prisma-client/queries/full-text-search#enabling-full-text-search-for-postgresql) in order to use it.
Examples [#examples-46]
Find all posts with a title that contains cat or dog. [#find-all-posts-with-a-title-that-contains-cat-or-dog]
```js
const result = await prisma.post.findMany({
where: {
title: {
search: "cat | dog",
},
},
});
```
Find all posts with a title that contains cat and dog. [#find-all-posts-with-a-title-that-contains-cat-and-dog]
```js
const result = await prisma.post.findMany({
where: {
title: {
search: "cat & dog",
},
},
});
```
Find all posts with a title that doesn't contain cat. [#find-all-posts-with-a-title-that-doesnt-contain-cat]
```js
const result = await prisma.post.findMany({
where: {
title: {
search: "!cat",
},
},
});
```
mode [#mode]
Remarks [#remarks-23]
* Supported by the PostgreSQL and MongoDB connectors only
Examples [#examples-47]
Get all Post records where title contains prisma, in a case insensitive way [#get-all-post-records-where-title-contains-prisma-in-a-case-insensitive-way]
```js
const result = await prisma.post.findMany({
where: {
title: {
contains: "prisma",
mode: "insensitive",
},
},
});
```
startsWith [#startswith]
Examples [#examples-48]
Get all Post records where title starts with Pr (such as Prisma) [#get-all-post-records-where-title-starts-with-pr-such-as-prisma]
```js
const result = await prisma.post.findMany({
where: {
title: {
startsWith: "Pr",
},
},
});
```
endsWith [#endswith]
Get all User records where email ends with prisma.io [#get-all-user-records-where-email-ends-with-prismaio]
```js
const result = await prisma.user.findMany({
where: {
email: {
endsWith: "prisma.io",
},
},
});
```
AND [#and]
All conditions must return `true`. Alternatively, pass a list of objects into the `where` clause - the [`AND` operator is not required](#get-all-post-records-where-the-content-field-contains-prisma-and-published-is-false-no-and).
Examples [#examples-49]
Get all Post records where the content field contains Prisma and published is false [#get-all-post-records-where-the-content-field-contains-prisma-and-published-is-false]
```js
const result = await prisma.post.findMany({
where: {
AND: [
{
content: {
contains: "Prisma",
},
},
{
published: {
equals: false,
},
},
],
},
});
```
Get all Post records where the content field contains Prisma and published is false (no AND) [#get-all-post-records-where-the-content-field-contains-prisma-and-published-is-false-no-and]
The following format returns the same results as the previous example **without** the `AND` operator:
```js
const result = await prisma.post.findMany({
where: {
content: {
contains: "Prisma",
},
published: {
equals: false,
},
},
});
```
Get all Post records where the title field contains Prisma or databases, and published is false [#get-all-post-records-where-the-title-field-contains-prisma-or-databases-and-published-is-false]
The following example combines `OR` and `AND`:
```js
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: "Prisma",
},
},
{
title: {
contains: "databases",
},
},
],
AND: {
published: false,
},
},
});
```
OR [#or]
One or more conditions must return `true`.
Examples [#examples-50]
Get all Post records where the title field contains Prisma or databases [#get-all-post-records-where-the-title-field-contains-prisma-or-databases]
```js
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: "Prisma",
},
},
{
title: {
contains: "databases",
},
},
],
},
});
```
Get all Post records where the title field contains Prisma or databases, but not SQL [#get-all-post-records-where-the-title-field-contains-prisma-or-databases-but-not-sql]
The following example combines `OR` and `NOT`:
```js
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: "Prisma",
},
},
{
title: {
contains: "databases",
},
},
],
NOT: {
title: {
contains: "SQL",
},
},
},
});
```
Get all Post records where the title field contains Prisma or databases, and published is false [#get-all-post-records-where-the-title-field-contains-prisma-or-databases-and-published-is-false-1]
The following example combines `OR` and `AND`:
```js
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: "Prisma",
},
},
{
title: {
contains: "databases",
},
},
],
AND: {
published: false,
},
},
});
```
NOT [#not-1]
All conditions must return `false`.
Examples [#examples-51]
Get all Post records where the title does not contain SQL [#get-all-post-records-where-the-title-does-not-contain-sql]
```js
const result = await prisma.post.findMany({
where: {
NOT: {
title: {
contains: "SQL",
},
},
},
});
```
Get all Post records where the title field contains Prisma or databases, but not SQL, and the related User record' email address does not contain sarah [#get-all-post-records-where-the-title-field-contains-prisma-or-databases-but-not-sql-and-the-related-user-record-email-address-does-not-contain-sarah]
```js
const result = await prisma.post.findMany({
where: {
OR: [
{
title: {
contains: "Prisma",
},
},
{
title: {
contains: "databases",
},
},
],
NOT: {
title: {
contains: "SQL",
},
},
user: {
NOT: {
email: {
contains: "sarah",
},
},
},
},
include: {
user: true,
},
});
```
Relation filters [#relation-filters]
some [#some]
Returns all records where **one or more** ("some") *related* records match filtering criteria.
Remarks [#remarks-24]
* You can use `some` without parameters to return all records with at least one relation
Examples [#examples-52]
Get all User records where some posts mention Prisma [#get-all-user-records-where-some-posts-mention-prisma]
```ts
const result = await prisma.user.findMany({
where: {
post: {
some: {
content: {
contains: "Prisma"
}
}
}
}
}
```
every [#every]
Returns all records where **all** ("every") *related* records match filtering criteria.
Examples [#examples-53]
Get all User records where all posts are published [#get-all-user-records-where-all-posts-are-published]
```ts
const result = await prisma.user.findMany({
where: {
post: {
every: {
published: true
},
}
}
}
```
none [#none]
Returns all records where **zero** *related* records match filtering criteria.
Remarks [#remarks-25]
* You can use `none` without parameters to [return all records with no relations](#get-all-user-records-with-zero-posts)
Examples [#examples-54]
Get all User records with zero posts [#get-all-user-records-with-zero-posts]
```ts
const result = await prisma.user.findMany({
where: {
post: {
none: {} // User has no posts
}
}
}
```
Get all User records with zero published posts [#get-all-user-records-with-zero-published-posts]
```ts
const result = await prisma.user.findMany({
where: {
post: {
none: {
published: true
}
}
}
}
```
is [#is]
Returns all records where related record matches filtering criteria (for example, user's name `is` Bob).
Examples [#examples-55]
Get all Post records where user's name is "Bob" [#get-all-post-records-where-users-name-is-bob]
```ts
const result = await prisma.post.findMany({
where: {
user: {
is: {
name: "Bob"
},
}
}
}
```
isNot [#isnot]
Returns all records where the related record does not match the filtering criteria (for example, user's name `isNot` Bob).
Examples [#examples-56]
Get all Post records where user's name is NOT "Bob" [#get-all-post-records-where-users-name-is-not-bob]
```ts
const result = await prisma.post.findMany({
where: {
user: {
isNot: {
name: "Bob"
},
}
}
}
```
Scalar list methods [#scalar-list-methods]
set [#set-1]
Use `set` to overwrite the value of a scalar list field.
Remarks [#remarks-26]
* `set` is optional - you can set the value directly:
```ts
tags: ["computers", "books"];
```
Examples [#examples-57]
Set the value of tags to a list of string values [#set-the-value-of-tags-to-a-list-of-string-values]
```ts
const setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
set: ["computing", "books"],
},
},
});
```
Set tags to a list of values without using the set keyword [#set-tags-to-a-list-of-values-without-using-the-set-keyword]
```ts
const setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: ["computing", "books"],
},
});
```
Set the value of tags to a single string value [#set-the-value-of-tags-to-a-single-string-value]
```ts
const setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
set: "computing",
},
},
});
```
push [#push]
Use `push` to add *one* value or *multiple* values to a scalar list field.
Remarks [#remarks-27]
* Available for PostgreSQL and MongoDB only.
* You can push a list of values or only a single value.
Examples [#examples-58]
Add a computing item to the tags list [#add-a-computing-item-to-the-tags-list]
```ts
const addTag = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
push: "computing",
},
},
});
```
```ts
const addTag = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
push: ["computing", "genetics"],
},
},
});
```
unset [#unset]
Use `unset` to unset the value of a scalar list (MongoDB only). Unlike `set: null`, `unset` removes the list entirely.
Examples [#examples-59]
Unset the value of tags [#unset-the-value-of-tags]
```ts
const setTags = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
unset: true,
},
},
});
```
Scalar list filters [#scalar-list-filters]
Scalar list filters allow you to filter by the contents of a list / array field.
Available for PostgreSQL, CockroachDB, and MongoDB.
Remarks [#remarks-28]
* Scalar list / array filters [ignore `NULL` values](/orm/prisma-client/special-fields-and-types/working-with-scalar-lists-arrays#null-values-in-arrays) . Using `isEmpty` or `NOT` does not return records with `NULL` value lists / arrays, and `{ equals: null }` results in an error.
has [#has]
The given value exists in the list.
Examples [#examples-60]
The following query returns all `Post` records where the `tags` list includes `"databases"`:
```ts
const posts = await client.post.findMany({
where: {
tags: {
has: "databases",
},
},
});
```
The following query returns all `Post` records where the `tags` list **does not** include `"databases"`:
```ts
const posts = await client.post.findMany({
where: {
NOT: {
tags: {
has: "databases",
},
},
},
});
```
hasEvery [#hasevery]
Every value exists in the list.
Examples [#examples-61]
The following query returns all `Post` records where the `tags` list includes *at least* `"databases"` *and* `"typescript"`:
```ts
const posts = await prisma.post.findMany({
where: {
tags: {
hasEvery: ["databases", "typescript"],
},
},
});
```
hasSome [#hassome]
At least one value exists in the list.
Examples [#examples-62]
The following query returns all `Post` records where the `tags` list includes `"databases"` *or* `"typescript"`:
```ts
const posts = await prisma.post.findMany({
where: {
tags: {
hasSome: ["databases", "typescript"],
},
},
});
```
isEmpty [#isempty]
The list is empty.
Examples [#examples-63]
The following query returns all `Post` records that have no tags:
```ts
const posts = await prisma.post.findMany({
where: {
tags: {
isEmpty: true,
},
},
});
```
isSet [#isset]
Filter lists to include only results that have been set (MongoDB only) (either set to a value, or explicitly set to `null`). Setting this filter to `true` will exclude undefined results that are not set at all.
Examples [#examples-64]
The following query returns all `Post` records where the `tags` have been set to either `null` or a value:
```ts
const posts = await prisma.post.findMany({
where: {
tags: {
isSet: true,
},
},
});
```
equals [#equals-1]
The list matches the given value exactly.
Examples [#examples-65]
The following query returns all `Post` records where the `tags` list includes `"databases"` and `"typescript"` only:
```ts
const posts = await prisma.post.findMany({
where: {
tags: {
equals: ["databases", "typescript"],
},
},
});
```
Composite type methods [#composite-type-methods]
Composite type methods allow you to create, update and delete [composite types](/orm/prisma-client/special-fields-and-types/composite-types) (MongoDB only).
set [#set-2]
Use `set` to overwrite the value of a composite type.
Remarks [#remarks-29]
* The `set` keyword is optional - you can set the value directly:
```ts
photos: [
{ height: 100, width: 200, url: "1.jpg" },
{ height: 100, width: 200, url: "2.jpg" },
];
```
Examples [#examples-66]
Set the shippingAddress composite type within a new order [#set-the-shippingaddress-composite-type-within-a-new-order]
```ts
const order = await prisma.order.create({
data: {
// Normal relation
product: { connect: { id: "some-object-id" } },
color: "Red",
size: "Large",
// Composite type
shippingAddress: {
set: {
street: "1084 Candycane Lane",
city: "Silverlake",
zip: "84323",
},
},
},
});
```
Set an optional composite type to null [#set-an-optional-composite-type-to-null]
```ts
const order = await prisma.order.create({
data: {
// Embedded optional type, set to null
billingAddress: {
set: null,
},
},
});
```
unset [#unset-1]
Use `unset` to unset the value of a composite type. Unlike `set: null`, this removes the field entirely from the MongoDB document.
Examples [#examples-67]
Remove the billingAddress from an order [#remove-the-billingaddress-from-an-order]
```ts
const order = await prisma.order.update({
where: {
id: "some-object-id",
},
data: {
billingAddress: {
// Unset the billing address
// Removes "billingAddress" field from order
unset: true,
},
},
});
```
update [#update-2]
Use `update` to update fields within a required composite type.
Remarks [#remarks-30]
The `update` method cannot be used on optional types. Instead, use [upsert](#upsert-2)
Examples [#examples-68]
Update the zip field of a shippingAddress composite type [#update-the-zip-field-of-a-shippingaddress-composite-type]
```ts
const order = await prisma.order.update({
where: {
id: "some-object-id",
},
data: {
shippingAddress: {
// Update just the zip field
update: {
zip: "41232",
},
},
},
});
```
upsert [#upsert-2]
Use `upsert` to update an existing optional composite type if it exists, and otherwise set the composite type.
Remarks [#remarks-31]
The `upsert` method cannot be used on required types. Instead, use [update](#update-2)
Examples [#examples-69]
Create a new billingAddress if it doesn't exist, and otherwise update it [#create-a-new-billingaddress-if-it-doesnt-exist-and-otherwise-update-it]
```ts
const order = await prisma.order.update({
where: {
id: "some-object-id",
},
data: {
billingAddress: {
// Create the address if it doesn't exist,
// otherwise update it
upsert: {
set: {
street: "1084 Candycane Lane",
city: "Silverlake",
zip: "84323",
},
update: {
zip: "84323",
},
},
},
},
});
```
push [#push-1]
Use `push` to push values to the end of a list of composite types.
Examples [#examples-70]
Add a new photo to the photos list [#add-a-new-photo-to-the-photos-list]
```ts
const product = prisma.product.update({
where: {
id: 10,
},
data: {
photos: {
// Push a photo to the end of the photos list
push: [{ height: 100, width: 200, url: "1.jpg" }],
},
},
});
```
Composite type filters [#composite-type-filters]
Composite type filters allow you to filter the contents of [composite types](/orm/prisma-client/special-fields-and-types/composite-types) (MongoDB only).
equals [#equals-2]
Use `equals` to filter results by matching a composite type or a list of composite types. Requires all required fields of the composite type to match.
Remarks [#remarks-32]
When matching optional fields, you need to distinguish between undefined (missing) fields of the document, and fields that have been explicitly set to `null`:
* If you omit an optional field, it will match undefined fields, but not fields that have been set to `null`
* If you filter for `null` values of an optional field with `equals: { ... exampleField: null ... }`, then it will match only documents where the field has been set to `null`, and not undefined fields
The ordering of fields and lists matters when using `equals`:
* For fields, `{ "a": "1", "b": "2" }` and `{ "b": "2", "a": "1" }` are not considered equal
* For lists, `[ { "a": 1 }, { "a": 2 } ]` and `[ { "a": 2 }, { "a": 1 } ]` are not considered equal
Examples [#examples-71]
Find orders that exactly match the given shippingAddress [#find-orders-that-exactly-match-the-given-shippingaddress]
```ts
const orders = await prisma.order.findMany({
where: {
shippingAddress: {
equals: {
street: "555 Candy Cane Lane",
city: "Wonderland",
zip: "52337",
},
},
},
});
```
Find products with photos that match all of a list of urls [#find-products-with-photos-that-match-all-of-a-list-of-urls]
```ts
const product = prisma.product.findMany({
where: {
equals: {
photos: [{ url: "1.jpg" }, { url: "2.jpg" }],
},
},
});
```
is [#is-1]
Use `is` to filter results by matching specific fields within composite types.
Examples [#examples-72]
Find orders with a shippingAddress that matches the given street name [#find-orders-with-a-shippingaddress-that-matches-the-given-street-name]
```ts
const orders = await prisma.order.findMany({
where: {
shippingAddress: {
is: {
street: "555 Candy Cane Lane",
},
},
},
});
```
isNot [#isnot-1]
Use `isNot` to filter results for composite type fields that do not match.
Examples [#examples-73]
Find orders with a shippingAddress that does not match the given zip code [#find-orders-with-a-shippingaddress-that-does-not-match-the-given-zip-code]
```ts
const orders = await prisma.order.findMany({
where: {
shippingAddress: {
isNot: {
zip: "52337",
},
},
},
});
```
isEmpty [#isempty-1]
Use `isEmpty` to filter results for an empty list of composite types.
Examples [#examples-74]
Find products with no photos [#find-products-with-no-photos]
```ts
const product = prisma.product.findMany({
where: {
photos: {
isEmpty: true,
},
},
});
```
every [#every-1]
Use `every` to filter for lists of composite types where every item in the list matches the condition
Examples [#examples-75]
Find the first product where every photo has a height of 200 [#find-the-first-product-where-every-photo-has-a-height-of-200]
```ts
const product = await prisma.product.findFirst({
where: {
photos: {
every: {
height: 200,
},
},
},
});
```
some [#some-1]
Use `some` to filter for lists of composite types where one or more items in the list match the condition.
Examples [#examples-76]
Find the first product where one or more photos have a url of 2.jpg [#find-the-first-product-where-one-or-more-photos-have-a-url-of-2jpg]
```ts
const product = await prisma.product.findFirst({
where: {
photos: {
some: {
url: "2.jpg",
},
},
},
});
```
none [#none-1]
Use `none` to filter for lists of composite types where no items in the list match the condition.
Examples [#examples-77]
Find the first product where no photos have a url of 2.jpg [#find-the-first-product-where-no-photos-have-a-url-of-2jpg]
```ts
const product = await prisma.product.findFirst({
where: {
photos: {
none: {
url: "2.jpg",
},
},
},
});
```
Atomic number operations [#atomic-number-operations]
Atomic operations on update is available for number field types (`Float` and `Int`). This feature allows you to update a field based on its **current** value (such as *subtracting* or *dividing*) without risking a race condition.
Overview: Race conditions
A race conditions occurs when two or more operations must be done in sequence in order to complete a task. In the following example, two clients try to increase the same field (`postCount`) by one:
| Client | Operation | Value |
| :------- | :------------------ | :----- |
| Client 1 | **Get** field value | `21` |
| Client 2 | **Get** field value | `21` |
| Client 2 | **Set** field value | `22` |
| Client 1 | **Set** field value | `22` ✘ |
The value *should* be `23`, but the two clients did not read and write to the `postCount` field in sequence. Atomic operations on update combine read and write into a single operation, which prevents a race condition:
| Client | Operation | Value |
| :------- | :-------------------------- | :------------ |
| Client 1 | **Get and set** field value | `21` → `22` |
| Client 2 | **Get and set** field value | `22` → `23` ✔ |
Operators [#operators]
| Option | Description |
| :---------- | :------------------------------------------------------------ |
| `increment` | Adds `n` to the current value. |
| `decrement` | Subtacts `n` from the current value. |
| `multiply` | Multiplies the current value by `n`. |
| `divide` | Divides the current value by `n`. |
| `set` | Sets the current field value. Identical to `{ myField : n }`. |
Remarks [#remarks-33]
* You can only perform **one** atomic update per field, per query.
* If a field is `null`, it will not be updated by `increment`, `decrement`, `multiply`, or `divide`.
Examples [#examples-78]
Increment all view and likes fields of all Post records by 1 [#increment-all-view-and-likes-fields-of-all-post-records-by-1]
```ts
const updatePosts = await prisma.post.updateMany({
data: {
views: {
increment: 1,
},
likes: {
increment: 1,
},
},
});
```
Set all views fields of all Post records to 0 [#set-all-views-fields-of-all-post-records-to-0]
```ts
const updatePosts = await prisma.post.updateMany({
data: {
views: {
set: 0,
},
},
});
```
Can also be written as:
```ts
const updatePosts = await prisma.post.updateMany({
data: {
views: 0,
},
});
```
Json filters [#json-filters]
For use cases and advanced examples, see: [Working with `Json` fields](/orm/prisma-client/special-fields-and-types/working-with-json-fields).
Supported by [PostgreSQL](/orm/core-concepts/supported-databases/postgresql) and [MySQL](/orm/core-concepts/supported-databases/mysql) with different syntaxes for the `path` option. PostgreSQL does not support filtering on object key values in arrays.
The examples in this section assumes that the value of the `pet` field is:
```json
{
"favorites": {
"catBreed": "Turkish van",
"dogBreed": "Rottweiler",
"sanctuaries": ["RSPCA", "Alley Cat Allies"],
"treats": [
{ "name": "Dreamies", "manufacturer": "Mars Inc" },
{ "name": "Treatos", "manufacturer": "The Dog People" }
]
},
"fostered": {
"cats": ["Bob", "Alice", "Svetlana the Magnificent", "Queenie"]
},
"owned": {
"cats": ["Elliott"]
}
}
```
Remarks [#remarks-34]
* The implementation of `Json` filtering [differs between database connectors](/orm/prisma-client/special-fields-and-types/working-with-json-fields)
* Filtering is case sensitive in PostgreSQL and does not yet support `mode`
path [#path]
`path` represents the location of a specific key. The following query returns all users where the nested `favorites` > `dogBreed` key equals `"Rottweiler"`.
PostgreSQL
MySQL
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["favorites", "dogBreed"],
equals: "Rottweiler",
},
},
});
```
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.dogBreed",
equals: "Rottweiler",
},
},
});
```
The following query returns all users where the nested `owned` > `cats` array contains `"Elliott"`.
PostgreSQL
MySQL
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["owned", "cats"],
array_contains: ["Elliott"],
},
},
});
```
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.owned.cats",
array_contains: "Elliott",
},
},
});
```
Filtering by the key values of objects inside an array (below) is only supported by the MySQL connector.
The following query returns all users where the nested `favorites` > `treats` array contains an object where the `name` value is `"Dreamies"`:
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.treats[*].name",
array_contains: "Dreamies",
},
},
});
```
string_contains [#string_contains]
The following query returns all users where the nested `favorites` > `catBreed` key value contains `"Van"`:
PostgreSQL
MySQL
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["favorites", "catBreed"],
string_contains: "Van",
},
},
});
```
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.catBreed",
string_contains: "Van",
},
},
});
```
string_starts_with [#string_starts_with]
The following query returns all users where the nested `favorites` > `catBreed` key value starts with `"Turkish"`:
PostgreSQL
MySQL
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["favorites", "catBreed"],
string_starts_with: "Turkish",
},
},
});
```
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.catBreed",
string_starts_with: "Turkish",
},
},
});
```
string_ends_with [#string_ends_with]
The following query returns all users where the nested `favorites` > `catBreed` key value ends with `"Van"`:
PostgreSQL
MySQL
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["favorites", "catBreed"],
string_ends_with: "Van",
},
},
});
```
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.catBreed",
string_ends_with: "Van",
},
},
});
```
mode [#mode-1]
Specify whether the string filtering should be case sensitive (default) or case insensitive.
The following query returns all users where the nested `favorites` > `catBreed` key value contains `"Van"` or `"van"`:
PostgreSQL
MySQL
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["favorites", "catBreed"],
string_contains: "Van",
mode: "insensitive",
},
},
});
```
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.favorites.catBreed",
string_contains: "Van",
mode: "insensitive",
},
},
});
```
array_contains [#array_contains]
The following query returns all users where the `sanctuaries` array contains the value `"RSPCA"`:
PostgreSQL
MySQL
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["sanctuaries"],
array_contains: ["RSPCA"],
},
},
});
```
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.sanctuaries",
array_contains: "RSPCA",
},
},
});
```
In PostgreSQL, the value of `array_contains` must be an array and not a string, even if the array only contains a single value.
The following query returns all users where the `sanctuaries` array contains *all* the values in the given array:
PostgreSQL
MySQL
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["sanctuaries"],
array_contains: ["RSPCA", "Alley Cat Allies"],
},
},
});
```
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.sanctuaries",
array_contains: ["RSPCA", "Alley Cat Allies"],
},
},
});
```
array_starts_with [#array_starts_with]
The following query returns all users where the `sanctuaries` array starts with the value `"RSPCA"`:
PostgreSQL
MySQL
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["sanctuaries"],
array_starts_with: "RSPCA",
},
},
});
```
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.sanctuaries",
array_starts_with: "RSPCA",
},
},
});
```
array_ends_with [#array_ends_with]
The following query returns all users where the `sanctuaries` array ends with the value `"Alley Cat Allies"`:
PostgreSQL
MySQL
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: ["sanctuaries"],
array_ends_with: "Alley Cat Allies",
},
},
});
```
```ts
const getUsers = await prisma.user.findMany({
where: {
pets: {
path: "$.sanctuaries",
array_ends_with: "Alley Cat Allies",
},
},
});
```
Client methods [#client-methods]
**Note:** Client-level methods are prefixed by `$`.
Remarks [#remarks-35]
* `$on` and `$use` client methods do not exist on extended client instances which are extended using [`$extends`](#extends)
In [extended clients](/orm/prisma-client/client-extensions), Client methods do not necessarily exist. If you are extending your client, make sure to check for existence before using Client methods like `$transaction` or `$connect`.
In addition, if you are using `$on` or `$use`, you will need to use these client methods before extending your client as these methods do not exist on extended clients. For `$use` specifically we recommend transitioning [to use query extensions](/orm/prisma-client/client-extensions/query).
$disconnect() [#disconnect-1]
The `$disconnect()` method closes the database connections that were established when `$connect` was called and stops the process that was running Prisma ORM's query engine. See [Connection management](/orm/prisma-client/setup-and-configuration/databases-connections/connection-management) for an overview of `$connect()` and `$disconnect()`.
Remarks [#remarks-36]
* `$disconnect()` returns a `Promise`, so you should call it inside an `async` function with the `await` keyword.
$connect() [#connect-1]
The `$connect()` method establishes a physical connection to the database via Prisma ORM's query engine. See [Connection management](/orm/prisma-client/setup-and-configuration/databases-connections/connection-management) for an overview of `$connect()` and `$disconnect()`.
Remarks [#remarks-37]
* `$connect()` returns a `Promise`, so you should call it inside an `async` function with the `await` keyword.
$on() [#on]
`$on` is not available in [extended clients](/orm/prisma-client/client-extensions). Please either migrate to client extensions or use the `$on` method prior to extending your client.
The `$on()` method allows you to subscribe to [logging events](#log) or the [exit hook](/orm/prisma-client/setup-and-configuration/databases-connections/connection-management#exit-hooks).
$queryRawTyped [#queryrawtyped]
See: [Using Raw SQL (`$queryRawTyped`)](/orm/prisma-client/using-raw-sql/typedsql).
$queryRaw [#queryraw]
See: [Using Raw SQL (`$queryRaw`)](/orm/prisma-client/using-raw-sql/raw-queries#queryraw).
$queryRawUnsafe() [#queryrawunsafe]
See: [Using Raw SQL (`$queryRawUnsafe()`)](/orm/prisma-client/using-raw-sql/raw-queries#queryrawunsafe).
$executeRaw [#executeraw]
See: [Using Raw SQL (`$executeRaw`)](/orm/prisma-client/using-raw-sql/raw-queries#executeraw).
$executeRawUnsafe() [#executerawunsafe]
See: [Using Raw SQL (`$executeRawUnsafe()`)](/orm/prisma-client/using-raw-sql/raw-queries#executerawunsafe).
$runCommandRaw() [#runcommandraw]
See: [Using Raw SQL (`$runCommandRaw()`)](/orm/prisma-client/using-raw-sql/raw-queries#runcommandraw).
$transaction() [#transaction]
See: [Transactions](/orm/prisma-client/queries/transactions).
$extends [#extends]
With `$extends`, you can create and use Prisma Client extensions to add functionality to Prisma Client in the following ways:
* `model`: add custom methods to your models
* `client`: add custom methods to your client
* `query`: create custom Prisma Client queries
* `result`: add custom fields to your query results
Learn more: [Prisma Client extensions](/orm/prisma-client/client-extensions).
Utility types [#utility-types]
Utility types are helper functions and types that live on the `Prisma` namespace. They are useful for keeping your application type safe.
Type-checking with satisfies [#type-checking-with-satisfies]
You can use TypeScript's `satisfies` operator to create re-usable query parameters based on your schema models while ensuring that the objects you create are type-compatible with the generated Prisma Client types. See also: [Type safety with Prisma Client](/orm/prisma-client/type-safety).
Use the generated Prisma Client types with `satisfies` to get type checking and inference:
```ts
const args = { ... } satisfies Prisma.GeneratedType;
```
Example [#example-3]
The following example shows how you can create type-checked input for the `create` operation that you can reuse within your app:
```ts
import { Prisma } from "../prisma/generated/client";
const createUserAndPostInput = (
name: string,
email: string,
postTitle: string,
) =>
({
name,
email,
posts: {
create: {
title: postTitle,
},
},
}) satisfies Prisma.UserCreateInput;
```
Compare columns in the same table [#compare-columns-in-the-same-table]
You can compare columns in the same table directly, for non-unique filters.
In the following situations, you must [use raw queries to compare columns in the same table](/orm/more/troubleshooting/raw-sql-comparisons):
* If you want to use a unique filter, such as [`findUnique`](#findunique) or [`findUniqueOrThrow`](#finduniqueorthrow)
* If you want to compare a field with a [unique constraint](/orm/prisma-schema/data-model/models#defining-a-unique-field)
* If you want to use one of the following operators to compare a [JSON field](/orm/prisma-client/special-fields-and-types/working-with-json-fields) in MySQL or MariaDB with another field: [`gt`](#gt), [`gte`](#gte), [`lt`](#lt), or [`lte`](#lte). Note that you can use these operators to compare the JSON field with a scalar value. This limitation applies only if you try to compare a JSON field with another field.
To compare columns in the same table, use the `.fields` property. In the following example, the query returns all records where the value in the `prisma.product.quantity` field is less than or equal to the value in the `prisma.product.warnQuantity` field.
```ts
prisma.product.findMany({
where: { quantity: { lte: prisma.product.fields.warnQuantity } },
});
```
`fields` is a special property of every model. It contains the list of fields for that model.
Considerations [#considerations]
Fields must be of the same type [#fields-must-be-of-the-same-type]
You can only make comparisons on fields of the same type. For example, the following causes an error:
```ts
await prisma.order.findMany({
where: {
id: { equals: prisma.order.fields.due },
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Type error: id is a string, while amountDue is an integer
},
});
```
Fields must be in the same model [#fields-must-be-in-the-same-model]
You can only make comparisons with the `fields` property on fields in the same model. The following example does not work:
```ts
await prisma.order.findMany({
where: {
id: { equals: prisma.user.fields.name },
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Type error: name is a field on the User model, not Order
},
});
```
However, you can compare fields in separate models with [standard queries](#model-queries).
In groupBy model queries, put your referenced fields in the by argument [#in-groupby-model-queries-put-your-referenced-fields-in-the-by-argument]
If you use the [groupBy](#groupby) model query with the `having` option, then you must put your referenced fields in the `by` argument.
The following example works:
```ts
prisma.user.groupBy({
by: ["id", "name"],
having: { id: { equals: prisma.user.fields.name } },
});
```
The following example does not work, because `name` is not in the `by` argument:
```ts
prisma.user.groupBy({
by: ["id"],
having: { id: { equals: prisma.user.fields.name } },
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// name is not in the 'by' argument
});
```
Search for fields in scalar lists [#search-for-fields-in-scalar-lists]
If your data source supports scalar lists (for example in PostgreSQL), then you can search for all records where a specific field is in a list of fields. To do so, reference the scalar list with the [`in`](#in) and [`notIn`](#notin) filters. For example:
```ts
await prisma.user.findMany({
where: {
// find all users where 'name' is in a list of tags
name: { in: prisma.user.fields.tags },
},
});
```
Filter on non-unique fields with UserWhereUniqueInput [#filter-on-non-unique-fields-with-userwhereuniqueinput]
The generated type `UserWhereUniqueInput` on [`where`](#where) exposes all fields on the model, not just unique fields.
You must specify at least one unique field in your `where` statement [outside of boolean operators](#boolean-operators-with-userwhereuniqueinput), and you can specify any number of additional unique and non-unique fields. You can use this to add filters to any operation that returns a single record. For example, you can use this feature for the following:
* [Optimistic concurrency control on updates](#optimistic-concurrency-control-on-updates)
* [Permission checks](#permission-checks)
* [Soft deletes](#soft-deletes)
* Filter on optional [one-to-one nested reads](/orm/prisma-client/queries/relation-queries#nested-reads)
Optimistic concurrency control on updates [#optimistic-concurrency-control-on-updates]
You can filter on non-unique fields to perform [optimistic concurrency control](/orm/prisma-client/queries/transactions#optimistic-concurrency-control) on `update` operations.
To perform optimistic concurrency control, use a `version` field to check whether the data in a record or related record has changed while your code executes.
In the following example, `updateOne` and `updateTwo` first read the same record and then attempt to update it. The database only executes these updates if the value in `version` is the same as the value when it did the initial read. When the database executes the first of these updates (which might be `updateOne` or `updateTwo`, depending on timing), it increments the value in `version`. This means that the database does not execute the second update because the value in `version` has changed.
```prisma
model User {
id Int @id @default(autoincrement())
email String @unique
city String
version Int
}
```
```ts
function updateOne() {
const user = await prisma.user.findUnique({ id: 1 });
await prisma.user.update({
where: { id: user.id, version: user.version },
data: { city: "Berlin", version: { increment: 1 } },
});
}
function updateTwo() {
const user = await prisma.user.findUnique({ id: 1 });
await prisma.user.update({
where: { id: user.id, version: user.version },
data: { city: "New York", version: { increment: 1 } },
});
}
function main() {
await Promise.allSettled([updateOne(), updateTwo()]);
}
```
Permission checks [#permission-checks]
You can filter on non-unique fields to check permissions during an update.
In the following example, a user wants to update a post title. The `where` statement checks the value in `authorId` to confirm that the user is the author of the post. The application only updates the post title if the user is the post author.
```ts
await prisma.post.update({
where: { id: 1, authorId: 1 },
data: { title: "Updated post title" },
});
```
Soft deletes [#soft-deletes]
You can filter on non-unique fields to handle soft deletes.
In the following example, we do not want to return a post if it is soft-deleted. The operation only returns the post if the value in `isDeleted` is `false`.
```ts
prisma.Post.findUnique({ where: { id: postId, isDeleted: false } });
```
UserWhereUniqueInput considerations [#userwhereuniqueinput-considerations]
Boolean operators with UserWhereUniqueInput [#boolean-operators-with-userwhereuniqueinput]
With `UserWhereUniqueInput`, you must specify at least one unique field outside of the boolean operators `AND`, `OR`, `NOT`. You can still use these boolean operators in conjunction with any other unique fields or non-unique fields in your filter.
In the following example, we test `id`, a unique field, in conjunction with `email`. This is valid.
```ts
await prisma.user.update({
where: { id: 1, OR: [{ email: "bob@prisma.io" }, { email: "alice@prisma.io" }] },
// ^^^ Valid: the expression specifies a unique field (`id`) outside of any boolean operators
data: { ... }
})
// SQL equivalent:
// WHERE id = 1 AND (email = "bob@prisma.io" OR email = "alice@prisma.io")
```
The following example is not valid, because there is no unique field outside of any boolean operators:
```ts
await prisma.user.update({
where: { OR: [{ email: "bob@prisma.io" }, { email: "alice@prisma.io" }] },
// ^^^ Invalid: the expressions does not contain a unique field outside of boolean operators
data: { ... }
})
```
One-to-one relations [#one-to-one-relations]
You can filter on non-unique fields in the following operations on [one-to-one relations](/orm/prisma-schema/data-model/relations/one-to-one-relations):
* Nested update
* Nested upsert
* Nested disconnect
* Nested delete
Prisma Client automatically uses a unique filter to select the appropriate related record. As a result, you do not need to specify a unique filter in your `where` statement with a `WhereUniqueInput` [generated type](#generated-types-for-where). Instead, the `where` statement has a `WhereInput` generated type. You can use this to filter without the restrictions of `WhereUniqueInput`.
Nested update example [#nested-update-example]
```ts
await prisma.user.update({
where: { id: 1 },
data: {
to_one: {
update: { where: { /* WhereInput */ }, data: { field: "updated" } }
}
}
})
```
Nested upsert example [#nested-upsert-example]
```ts
await prisma.user.update({
where: { id: 1 },
data: {
to_one: {
upsert: {
where: { /* WhereInput */ },
create: { /* CreateInput */ },
update: { /* UpdateInput */ },
}
}
}
})
```
Nested disconnect example [#nested-disconnect-example]
```ts
await prisma.user.update({
where: { id: 1 },
data: {
to_one: {
disconnect: { /* WhereInput */ }
}
}
})
```
Nested delete example [#nested-delete-example]
```ts
await prisma.user.update({
where: { id: 1 },
data: {
to_one: {
delete: { /* WhereInput */ }
}
}
})
```
PrismaPromise behavior [#prismapromise-behavior]
All Prisma Client queries return an instance of `PrismaPromise`. This is a ["thenable"](https://masteringjs.io/tutorials/fundamentals/thenable), meaning a `PrismaPromise` only executes when you call `await` or `.then()` or `.catch()`. This behavior is different from a regular JavaScript [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), which starts executing immediately.
For example:
```ts
const findPostOperation = prisma.post.findMany({}); // Query not yet executed
findPostOperation.then(); // Prisma Client now executes the query
// or
await findPostOperation; // Prisma Client now executes the query
```
When using the [`$transaction` API](/orm/prisma-client/queries/transactions#the-transaction-api), this behavior makes it possible for Prisma Client to pass all the queries on to the query engine as a single transaction.
# Config API (/docs/orm/reference/prisma-config-reference)
The Prisma Config file (`prisma.config.ts`) configures the Prisma CLI using TypeScript. It's automatically created when you run `prisma init`.
You can define your config using either the `defineConfig` helper or TypeScript's `satisfies` operator:
* Using the `defineConfig` helper:
```ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx prisma/seed.ts",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
* Using TypeScript's `satisfies` operator with the `PrismaConfig` type:
```ts
import "dotenv/config";
import type { PrismaConfig } from "prisma";
import { env } from "prisma/config";
export default {
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx prisma/seed.ts",
},
datasource: {
url: env("DATABASE_URL"),
},
} satisfies PrismaConfig;
```
Configuration interface [#configuration-interface]
Here is a simplified version of the `PrismaConfig` type:
```ts
export declare type PrismaConfig = {
// Whether features with an unstable API are enabled.
experimental: {
externalTables: boolean;
};
// The path to the schema file, or path to a folder that shall be recursively searched for *.prisma files.
schema?: string;
// Configuration for Prisma migrations.
migrations?: {
path: string;
seed: string;
initShadowDb: string;
};
// Configuration for the database view entities.
views?: {
path: string;
};
// Configuration for the `typedSql` preview feature.
typedSql?: {
path: string;
};
// Database connection configuration
datasource?: {
url: string;
shadowDatabaseUrl?: string;
};
};
```
Supported file extensions [#supported-file-extensions]
Prisma Config files can be named as `prisma.config.*` or `.config/prisma.*` with the extensions `js`, `ts`, `mjs`, `cjs`, `mts`, or `cts`. Other extensions are supported to ensure compatibility with different TypeScript compiler settings.
Recommendation
* Use **`prisma.config.ts`** for small TypeScript projects.
* Use **`.config/prisma.ts`** for larger TypeScript projects with multiple configuration files (following the [`.config` directory proposal](https://github.com/pi0/config-dir)).
Options reference [#options-reference]
schema [#schema]
Configures how Prisma ORM locates and loads your schema file(s). Can be a file or folder path. Relative paths are resolved relative to the `prisma.config.ts` file location. See [here](/orm/prisma-schema/overview/location#multi-file-prisma-schema) for more info about schema location options.
| Property | Type | Required | Default |
| -------- | -------- | -------- | ---------------------------------------------- |
| `schema` | `string` | No | `./prisma/schema.prisma` and `./schema.prisma` |
tables.external and enums.external [#tablesexternal-and-enumsexternal]
These options declare tables and enums in your database that are **managed externally** (not by Prisma Migrate). You can still query them with Prisma Client, but they will be ignored by migrations.
| Property | Type | Required | Default |
| ----------------- | ---------- | -------- | ------- |
| `tables.external` | `string[]` | No | `[]` |
| `enums.external` | `string[]` | No | `[]` |
**Example:**
```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"),
},
experimental: {
externalTables: true,
},
tables: {
external: ["public.users"],
},
enums: {
external: ["public.role"],
},
});
```
Learn more about the [`externalTables` feature here](/orm/prisma-schema/data-model/externally-managed-tables).
migrations.path [#migrationspath]
The path to the directory where Prisma should store migration files, and look for them.
| Property | Type | Required | Default |
| ----------------- | -------- | -------- | ------- |
| `migrations.path` | `string` | No | none |
migrations.seed [#migrationsseed]
Defines the command to run when executing `npx prisma db seed`. Seeding is only triggered explicitly via this command.
| Property | Type | Required | Default |
| ----------------- | -------- | -------- | ------- |
| `migrations.seed` | `string` | No | none |
**Example:**
```ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx db/seed.ts",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
migrations.initShadowDb [#migrationsinitshadowdb]
This option allows you to define SQL statements that Prisma runs on the **shadow database** before creating migrations. It is useful when working with [external managed tables](/orm/prisma-schema/data-model/externally-managed-tables), as Prisma needs to know about the structure of these tables to correctly generate migrations.
| Property | Type | Required | Default |
| ------------------------- | -------- | -------- | ------- |
| `migrations.initShadowDb` | `string` | No | none |
**Example:**
```ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
initShadowDb: `
CREATE TABLE public.users (id SERIAL PRIMARY KEY);
`,
},
datasource: {
url: env("DATABASE_URL"),
},
experimental: {
externalTables: true,
},
tables: {
external: ["public.users"],
},
});
```
Learn more about the [`externalTables` feature here](/orm/prisma-schema/data-model/externally-managed-tables).
views.path [#viewspath]
The path to the directory where Prisma should look for the SQL view definitions.
| Property | Type | Required | Default |
| ------------ | -------- | -------- | ------- |
| `views.path` | `string` | No | none |
typedSql.path [#typedsqlpath]
The path to the directory where Prisma should look for the SQL files used for generating typings via [`typedSql`](/orm/prisma-client/using-raw-sql/typedsql).
| Property | Type | Required | Default |
| --------------- | -------- | -------- | ------- |
| `typedSql.path` | `string` | No | none |
experimental [#experimental]
Enables specific experimental features in the Prisma CLI.
| Property | Type | Required | Default |
| ---------------- | --------- | -------- | ------- |
| `externalTables` | `boolean` | No | `false` |
Example:
```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"),
},
experimental: {
externalTables: true,
},
});
```
If you use the `externalTables` feature without enabling the experimental flag, Prisma will throw an error:
```bash
Failed to load config file "~" as a TypeScript/JavaScript module. Error: Error: The `externalTables` configuration requires `experimental.externalTables` to be set to `true`.
```
datasource.url [#datasourceurl]
Connection URL including authentication info. Uses [the syntax provided by the database](/orm/reference/connection-urls#format).
| Property | Type | Required | Default |
| ---------------- | -------- | -------- | ------- |
| `datasource.url` | `string` | Yes | `''` |
**Example:**
```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"),
},
});
```
datasource.shadowDatabaseUrl [#datasourceshadowdatabaseurl]
Connection URL to the shadow database used by Prisma Migrate. Allows you to use a cloud-hosted database as the shadow database.
| Property | Type | Required | Default |
| ------------------------------ | -------- | -------- | ------- |
| `datasource.shadowDatabaseUrl` | `string` | No | `''` |
datasource.directUrl (Removed) [#datasourcedirecturl-removed]
Removed in Prisma ORM v7
The `datasource.directUrl` property has been removed in Prisma ORM v7 in favor of the [`url` property](#datasourceurl).
For Prisma ORM v6.19 and earlier
Connection URL for direct connection to the database.
If you use a connection pooler URL in the `url` argument (for example, pgBouncer), Prisma CLI commands that require a direct connection to the database use the URL in the `directUrl` argument.
The `directUrl` property is supported by Prisma Studio from version 5.1.0 upwards. The `directUrl` property is not needed when using [Prisma Postgres](/postgres) database.
| Property | Type | Required | Default |
| ---------------------- | -------- | -------- | ------- |
| `datasource.directUrl` | `string` | No | `''` |
adapter (Removed) [#adapter-removed]
Removed in Prisma ORM v7
The `adapter` property has been removed in Prisma ORM v7. Migrations for driver adapters work automatically without additional configuration in `prisma.config.ts` as of Prisma ORM v7.
For Prisma ORM v6.19 and earlier
A function that returns a Prisma driver adapter instance which is used by the Prisma CLI to run migrations. The function should return a `Promise` that resolves to a valid Prisma driver adapter.
| Property | Type | Required | Default |
| --------- | ------------------------------------------------------ | -------- | ------- |
| `adapter` | `() => Promise` | No | none |
Example using the Prisma ORM D1 driver adapter:
```ts
import path from "node:path";
import type { PrismaConfig } from "prisma";
import { PrismaD1 } from "@prisma/adapter-d1";
export default {
experimental: {
adapter: true,
},
engine: "js",
schema: path.join("prisma", "schema.prisma"),
async adapter() {
return new PrismaD1({
CLOUDFLARE_D1_TOKEN: process.env.CLOUDFLARE_D1_TOKEN,
CLOUDFLARE_ACCOUNT_ID: process.env.CLOUDFLARE_ACCOUNT_ID,
CLOUDFLARE_DATABASE_ID: process.env.CLOUDFLARE_DATABASE_ID,
});
},
} satisfies PrismaConfig;
```
As of [Prisma ORM v6.11.0](https://github.com/prisma/prisma/releases/tag/6.11.0), the D1 adapter has been renamed from `PrismaD1HTTP` to `PrismaD1`.
engine (Removed) [#engine-removed]
Removed in Prisma ORM v7
The `engine` property has been removed in Prisma ORM v7.
For Prisma ORM v6.19 and earlier
Configure the schema engine your project should use.
| Property | Type | Required | Default |
| -------- | ----------------- | -------- | --------- |
| `engine` | `classic` or `js` | No | `classic` |
By default it is set to use the classic engine, which requires that `datasource` be set in your `prisma.config.ts`.
```ts
import "dotenv/config";
import path from "node:path";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
engine: "classic",
datasource: {
url: env("DATABASE_URL"),
},
schema: path.join("prisma", "schema.prisma"),
});
```
studio (Removed) [#studio-removed]
Removed in Prisma ORM v7
The `studio` property has been removed in Prisma ORM v7. To run Prisma Studio, use:
npm
pnpm
yarn
bun
```bash
npx prisma studio --config ./prisma.config.ts
```
```bash
pnpm dlx prisma studio --config ./prisma.config.ts
```
```bash
yarn dlx prisma studio --config ./prisma.config.ts
```
```bash
bunx --bun prisma studio --config ./prisma.config.ts
```
Prisma Studio now uses the connection configuration from the `datasource` property automatically. See the [Prisma Studio documentation](/orm/reference/prisma-cli-reference#studio) for more details.
For Prisma ORM v6.19 and earlier
Configures how Prisma Studio connects to your database. See sub-options below for details.
| Property | Type | Required | Default |
| -------- | -------- | -------- | ------- |
| `studio` | `object` | No | none |
studio.adapter (Removed) [#studioadapter-removed]
A function that returns a Prisma driver adapter instance. The function receives an `env` parameter containing environment variables and should return a `Promise` that resolves to a valid Prisma driver adapter.
| Property | Type | Required | Default |
| ----------------- | -------------------------------------------------------------- | -------- | ------- |
| `studio.adapter ` | `(env: Env) => Promise` | No | none |
Example using the Prisma ORM LibSQL driver adapter:
```ts
import type { PrismaConfig } from "prisma";
export default {
experimental: {
studio: true,
},
engine: "js",
studio: {
adapter: async (env: Env) => {
const { PrismaLibSQL } = await import("@prisma/adapter-libsql");
const { createClient } = await import("@libsql/client");
const libsql = createClient({
url: env.DOTENV_PRISMA_STUDIO_LIBSQL_DATABASE_URL,
});
return new PrismaLibSQL(libsql);
},
},
} satisfies PrismaConfig;
```
Common patterns [#common-patterns]
Setting up your project [#setting-up-your-project]
To get started with Prisma Config, create a `prisma.config.ts` file in your project root. You can use either of these approaches:
Using `defineConfig`:
```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"),
},
});
```
Using TypeScript types:
```ts
import "dotenv/config";
import type { PrismaConfig } from "prisma";
import { env } from "prisma/config";
export default {
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
} satisfies PrismaConfig;
```
Using environment variables [#using-environment-variables]
Environment variables from `.env` files need to be loaded explicitly. The `prisma init` command generates a config that includes `import 'dotenv/config'` by default.
Using dotenv (Recommended for Prisma ORM v7) [#using-dotenv-recommended-for-prisma-orm-v7]
1. Install the `dotenv` package:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
2. Import `dotenv/config` at the top of your `prisma.config.ts` file:
```ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx prisma/seed.ts",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Using Node.js v20+ or tsx with --env-file flag [#using-nodejs-v20-or-tsx-with---env-file-flag]
If using Node.js v20+ or `tsx`, you can pass a `--env-file` flag to automatically load environment variables:
```bash
tsx --env-title=".env" src/index.ts
tsx watch --env-title=".env" --env-title=".local.env" src/index.ts
tsx --env-title=".env" ./prisma/seed.ts
```
Using Bun [#using-bun]
For Bun, `.env` files are automatically loaded without additional configuration. The `import 'dotenv/config'` line that `prisma init` generates is not needed when using Bun and can be safely removed from your `prisma.config.ts` file.
When running Prisma CLI commands with Bun, use the `--bun` flag (e.g., `bunx --bun prisma init`) to ensure Prisma uses the Bun runtime instead of falling back to Node.js.
Type-safe environment variables [#type-safe-environment-variables]
Use the `env()` helper function to provide type-safe access to environment variables:
```ts
import "dotenv/config";
import { defineConfig, env } from "prisma/config";
type Env = {
DATABASE_URL: string;
};
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
Handling optional environment variables [#handling-optional-environment-variables]
The `env()` helper function from `prisma/config` **throws an error** if the specified environment variable is not defined. This is important to understand because:
* Every Prisma CLI command loads the `prisma.config.ts` file
* Only **some** commands actually need the `datasource.url` value (e.g., `prisma db *`, `prisma migrate *`, `prisma generate --sql`)
* Commands like `prisma generate` don't need a database URL, but will still fail if `env()` throws an error when loading the config file
For example, if you run `prisma generate` without `DATABASE_URL` set, and your config uses `env('DATABASE_URL')`, you'll see:
```bash
Error: PrismaConfigEnvError: Missing required environment variable: DATABASE_URL
```
**Solution:** If your environment variable isn't guaranteed to exist (e.g., in CI/CD pipelines where you only run `prisma generate` for type-checking), don't use the `env()` helper. Instead, access the environment variable directly:
```ts
import "dotenv/config";
import { defineConfig } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
},
datasource: {
url: process.env.DATABASE_URL!, // Or use: process.env.DATABASE_URL ?? '' to provide a fallback value
},
});
```
Use the `env()` helper when you want to **enforce** that an environment variable exists. Use `process.env` directly when the variable may be optional depending on the command being run.
Using multi-file schemas [#using-multi-file-schemas]
If you want to split your Prisma schema into multiple files, you need to specify the path to your Prisma schema folder via the `schema` property:
```ts
import path from "node:path";
import type { PrismaConfig } from "prisma";
export default {
schema: path.join("prisma", "schema"),
} satisfies PrismaConfig;
```
In that case, your `migrations` directory must be located next to the `.prisma` file that defines the `datasource` block.
For example, assuming `schema.prisma` defines the `datasource`, here's how how need to place the migrations folder:
```
# `migrations` and `schema.prisma` are on the same level
.
├── migrations
├── models
│ ├── posts.prisma
│ └── users.prisma
└── schema.prisma
```
Path resolution [#path-resolution]
Prisma CLI commands such as `prisma validate` or `prisma migrate` use `prisma.config.ts` (or `.config/prisma.ts`) to locate your Prisma schema and other resources.
**Key rules:**
* Paths defined in the config file (e.g., `schema`, `migrations`) are always resolved **relative to the location of the config file**, not where you run the CLI command from.
* The CLI must first **find the config file** itself, which depends on how Prisma is installed and the package manager used.
Behavior with pnpm prisma [#behavior-with-pnpm-prisma]
When Prisma is installed locally and run via `pnpm prisma`, the config file is detected automatically whether you run the command from the project root or a subdirectory.
Example project tree:
```
.
├── node_modules
├── package.json
├── prisma-custom
│ └── schema.prisma
├── prisma.config.ts
└── src
```
Example run from the project root:
```bash
pnpm prisma validate
# → Loaded Prisma config from ./prisma.config.ts
# → Prisma schema loaded from prisma-custom/schema.prisma
```
Example run from a subdirectory:
```bash
cd src
pnpm prisma validate
# → Still finds prisma.config.ts and resolves schema correctly
```
Behavior with npx prisma or bunx --bun prisma [#behavior-with-npx-prisma-or-bunx---bun-prisma]
When running via `npx prisma` or `bunx --bun prisma`, the CLI only detects the config file if the command is run from the **project root** (where `package.json` declares Prisma).
The `--bun` flag is required when using Bun to ensure Prisma runs with the Bun runtime. Without it, Prisma falls back to Node.js due to the `#!/usr/bin/env node` shebang in the CLI.
Example run from the project root:
npm
pnpm
yarn
bun
```bash
npx prisma validate
# → Works as expected
```
```bash
pnpm dlx prisma validate
# → Works as expected
```
```bash
yarn dlx prisma validate
# → Works as expected
```
```bash
bunx --bun prisma validate
# → Works as expected
```
Run from a subdirectory (fails):
npm
pnpm
yarn
bun
```bash
cd src
npx prisma validate
# → Error: Could not find Prisma Schema...
```
```bash
cd src
pnpm dlx prisma validate
# → Error: Could not find Prisma Schema...
```
```bash
cd src
yarn dlx prisma validate
# → Error: Could not find Prisma Schema...
```
```bash
cd src
bun x prisma validate
# → Error: Could not find Prisma Schema...
```
To fix this, you can use the `--config` flag:
npm
pnpm
yarn
bun
```bash
npx prisma validate --config ../prisma.config.ts
```
```bash
pnpm dlx prisma validate --config ../prisma.config.ts
```
```bash
yarn dlx prisma validate --config ../prisma.config.ts
```
```bash
bunx --bun prisma validate --config ../prisma.config.ts
```
Global Prisma installations [#global-prisma-installations]
If Prisma is installed globally (`npm i -g prisma`), it may not find your `prisma.config.ts` or `prisma/config` module by default.
To avoid issues:
* Prefer local Prisma installations in your project.
* Or use `prisma/config` locally and pass `--config` to point to your config file.
Monorepos [#monorepos]
* If Prisma is installed in the **workspace root**, `pnpm prisma` will detect the config file from subdirectories.
* If Prisma is installed in a **subpackage** (e.g., `./packages/db`), run commands from that package directory or deeper.
Custom config location [#custom-config-location]
You can specify a custom location for your config file when running Prisma CLI commands:
```bash
prisma validate --config ./path/to/myconfig.ts
```
Loading environment variables [#loading-environment-variables]
To load environment variables, install the `dotenv` package and add `import 'dotenv/config'` at the top of your `prisma.config.ts` file.
To load environment variables in your Prisma application, you can use the `prisma.config.ts` file along with the `env` helper from `prisma/config`. This approach provides better type safety and configuration management.
1. Install the `dotenv` package:
npm
pnpm
yarn
bun
```bash
npm install dotenv
```
```bash
pnpm add dotenv
```
```bash
yarn add dotenv
```
```bash
bun add dotenv
```
2. Create a `.env` file in your project root (if it doesn't exist) and add your database connection string:
```bash
DATABASE_URL="your_database_connection_string_here"
```
3. Ensure your `prisma.config.ts` file imports `dotenv/config` at the top:
```ts title="prisma.config.ts"
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx prisma/seed.ts",
},
datasource: {
url: env("DATABASE_URL"),
},
});
```
# Schema API (/docs/orm/reference/prisma-schema-reference)
datasource [#datasource]
Defines a [data source](/orm/prisma-schema/overview/data-sources) in the Prisma schema.
Fields [#fields]
A `datasource` block accepts the following fields:
| Name | Required | Type | Description |
| -------------- | -------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `provider` | **Yes** | String (`postgresql`, `mysql`, `sqlite`, `sqlserver`, `mongodb`, `cockroachdb`) | Specifies the database connector to use. |
| `relationMode` | No | String (`foreignKeys`, `prisma`) | Sets whether [referential integrity](/orm/prisma-schema/data-model/relations/relation-mode) is enforced by foreign keys or by Prisma. |
| `schemas` | No | Array of strings | List of database schemas to include ([multi-schema](/orm/prisma-schema/data-model/multi-schema) support, PostgreSQL and SQL Server). |
| `extensions` | No | Array of extension names | [PostgreSQL extensions](/orm/prisma-schema/postgresql-extensions) to enable. |
Connection URLs (`url`, `directUrl`, `shadowDatabaseUrl`) are configured in [`prisma.config.ts`](/orm/reference/prisma-config-reference#datasourceurl), not in the schema file.
The following providers are available:
* [`sqlite`](/orm/core-concepts/supported-databases/sqlite)
* [`postgresql`](/orm/core-concepts/supported-databases/postgresql)
* [`mysql`](/orm/core-concepts/supported-databases/mysql)
* [`sqlserver`](/orm/core-concepts/supported-databases/sql-server)
* [`mongodb`](/orm/core-concepts/supported-databases/mongodb)
* [`cockroachdb`](/orm/core-concepts/supported-databases/postgresql#cockroachdb)
Remarks [#remarks]
* You can only have **one** `datasource` block in a schema.
* `datasource db` is convention - however, you can give your data source any name - for example, `datasource mysql` or `datasource data`.
Examples [#examples]
PostgreSQL datasource [#postgresql-datasource]
```prisma
datasource db {
provider = "postgresql"
}
```
Configure the connection URL in `prisma.config.ts`:
```ts
import { defineConfig, env } from "prisma/config";
export default defineConfig({
datasource: {
url: env("DATABASE_URL"),
},
});
```
Learn more about PostgreSQL connection strings [here](/orm/core-concepts/supported-databases/postgresql).
Specify a PostgreSQL data source via an environment variable [#specify-a-postgresql-data-source-via-an-environment-variable]
In this example, the target database is available with the following credentials:
* User: `johndoe`
* Password: `mypassword`
* Host: `localhost`
* Port: `5432`
* Database name: `mydb`
* Schema name: `public`
```prisma
datasource db {
provider = "postgresql"
}
```
When running a Prisma CLI command that needs the database connection URL (e.g. `prisma generate`), you need to make sure that the `DATABASE_URL` environment variable is set.
One way to do so is by creating a [`.env`](https://github.com/motdotla/dotenv) file with the following contents. Note that the file must be in the same directory as your `schema.prisma` file to automatically picked up the Prisma CLI.
```
DATABASE_URL=postgresql://johndoe:mypassword@localhost:5432/mydb?schema=public
```
MySQL datasource [#mysql-datasource]
```prisma
datasource db {
provider = "mysql"
}
```
Learn more about [MySQL connection URLs](/orm/core-concepts/supported-databases/mysql).
MongoDB datasource [#mongodb-datasource]
```prisma
datasource db {
provider = "mongodb"
}
```
Learn more about [MongoDB connection URLs](/orm/core-concepts/supported-databases/mongodb).
SQLite datasource [#sqlite-datasource]
```prisma
datasource db {
provider = "sqlite"
}
```
Learn more about [SQLite connection URLs](/orm/core-concepts/supported-databases/sqlite).
CockroachDB datasource [#cockroachdb-datasource]
```prisma
datasource db {
provider = "cockroachdb"
}
```
CockroachDB uses the same connection URL format as PostgreSQL. Learn more about [PostgreSQL connection URLs](/orm/core-concepts/supported-databases/postgresql).
Multi-schema datasource (PostgreSQL) [#multi-schema-datasource-postgresql]
```prisma
datasource db {
provider = "postgresql"
schemas = ["public", "analytics"]
}
```
generator [#generator]
Defines a [generator](/orm/prisma-schema/overview/generators) in the Prisma schema.
Fields for prisma-client-js provider [#fields-for-prisma-client-js-provider]
This is the default generator for Prisma ORM 6.x and earlier versions. Learn more about [generators](/orm/prisma-schema/overview/generators#prisma-client-js-deprecated).
A `generator` block accepts the following fields:
| Name | Required | Type | Description |
| :---------------- | :------- | :--------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `provider` | **Yes** | `prisma-client-js` | Describes which [generator](/orm/prisma-schema/overview/generators) to use. This can point to a file that implements a generator or specify a built-in generator directly. |
| `output` | No | String (file path) | Determines the location for the generated client, [learn more](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider). **Default**: `node_modules/.prisma/client` |
| `previewFeatures` | No | List of Enums | Use intellisense to see list of currently available Preview features (`Ctrl+Space` in Visual Studio Code) **Default**: none |
| `engineType` | No | Enum (`library` or `binary`) | Defines the query engine type to download and use. **Default**: `library` |
| `binaryTargets` | No | List of Enums (see below) | Specify the OS on which the Prisma Client will run to ensure compatibility of the query engine. **Default**: `native` |
| `moduleFormat` | No | Enum (`cjs` or `esm`) | Defines the module format of the generated Prisma Client. This field is available only with `prisma-client` generator. |
important
We recommend defining a custom output path, adding the path to `.gitignore`, and then making sure to run `prisma generate` via a custom build script or postinstall hook.
Fields for prisma-client provider [#fields-for-prisma-client-provider]
The ESM-first client generator that offers greater control and flexibility across different JavaScript environments. It generates plain TypeScript code into a custom directory, providing full visibility over the generated code. Learn more about the new [`prisma-client`](/orm/prisma-schema/overview/generators#prisma-client) generator.
The `prisma-client` generator is the default generator in Prisma ORM 7.
A `generator` block accepts the following fields:
| Name | Required | Type | Description |
| :----------------------- | :------- | :----------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `provider` | **Yes** | `prisma-client` | Describes which [generator](/orm/prisma-schema/overview/generators) to use. This can point to a file that implements a generator or specify a built-in generator directly. |
| `output` | **Yes** | String (file path) | Determines the location for the generated client, [learn more](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider). |
| `previewFeatures` | No | List of Enums | Use intellisense to see list of currently available Preview features (`Ctrl+Space` in Visual Studio Code) **Default**: none |
| `runtime` | No | Enum (`nodejs`, `deno`, `bun`, `workerd` (alias `cloudflare`), `vercel-edge` (alias `edge-light`), `react-native`) | Target runtime environment. **Default**: `nodejs` |
| `moduleFormat` | No | Enum (`esm` or `cjs`) | Determines whether the generated code supports ESM (uses `import`) or CommonJS (uses `require(...)`) modules. We always recommend `esm` unless you have a good reason to use `cjs`. **Default**: Inferred from environment. |
| `generatedFileExtension` | No | Enum (`ts` or `mts` or `cts`) | File extension for generated TypeScript files. **Default**: `ts` |
| `importFileExtension` | No | Enum (`ts`,`mts`,`cts`,`js`,`mjs`,`cjs`, empty (for bare imports)) | File extension used in import statements **Default**: Inferred from environment. |
| `compilerBuild` | No | String (`fast`, `small`) | Defines what build of the query compiler to use for the generated client. `fast`, the default, gives you fast query compilation, but with an increase in size. `small` gives you the smallest size, but with a slightly slower execution. |
binaryTargets options [#binarytargets-options]
The following tables list all supported operating systems with the name of platform to specify in `binaryTargets`.
Unless specified otherwise, the default supported CPU architecture is x86\_64.
macOS [#macos]
| Build OS | Prisma engine build name |
| :------------------ | :----------------------- |
| macOS Intel x86\_64 | `darwin` |
| macOS ARM64 | `darwin-arm64` |
Windows [#windows]
| Build OS | Prisma engine build name |
| :------- | :----------------------- |
| Windows | `windows` |
Linux (Alpine on x86_64 architectures) [#linux-alpine-on-x86_64-architectures]
| Build OS | Prisma engine build name | OpenSSL |
| :---------------------- | :------------------------- | :-----: |
| Alpine (3.17 and newer) | `linux-musl-openssl-3.0.x` | 3.0.x |
| Alpine (3.16 and older) | `linux-musl` | 1.1.x |
Linux (Alpine on ARM64 architectures) [#linux-alpine-on-arm64-architectures]
| Build OS | Prisma engine build name | OpenSSL |
| :---------------------- | :------------------------------- | :-----: |
| Alpine (3.17 and newer) | `linux-musl-arm64-openssl-3.0.x` | 3.0.x |
| Alpine (3.16 and older) | `linux-musl-arm64-openssl-1.1.x` | 1.1.x |
Linux (Debian), x86_64 [#linux-debian-x86_64]
| Build OS | Prisma engine build name | OpenSSL |
| :------------------- | :----------------------- | :-----: |
| Debian 8 (Jessie) | `debian-openssl-1.0.x` | 1.0.x |
| Debian 9 (Stretch) | `debian-openssl-1.1.x` | 1.1.x |
| Debian 10 (Buster) | `debian-openssl-1.1.x` | 1.1.x |
| Debian 11 (Bullseye) | `debian-openssl-1.1.x` | 1.1.x |
| Debian 12 (Bookworm) | `debian-openssl-3.0.x` | 3.0.x |
Linux (Ubuntu), x86_64 [#linux-ubuntu-x86_64]
| Build OS | Prisma engine build name | OpenSSL |
| :--------------------- | :----------------------- | :-----: |
| Ubuntu 14.04 (trusty) | `debian-openssl-1.0.x` | 1.0.x |
| Ubuntu 16.04 (xenial) | `debian-openssl-1.0.x` | 1.0.x |
| Ubuntu 18.04 (bionic) | `debian-openssl-1.1.x` | 1.1.x |
| Ubuntu 19.04 (disco) | `debian-openssl-1.1.x` | 1.1.x |
| Ubuntu 20.04 (focal) | `debian-openssl-1.1.x` | 1.1.x |
| Ubuntu 21.04 (hirsute) | `debian-openssl-1.1.x` | 1.1.x |
| Ubuntu 22.04 (jammy) | `debian-openssl-3.0.x` | 3.0.x |
| Ubuntu 23.04 (lunar) | `debian-openssl-3.0.x` | 3.0.x |
Linux (CentOS), x86_64 [#linux-centos-x86_64]
| Build OS | Prisma engine build name | OpenSSL |
| :------- | :----------------------- | :-----: |
| CentOS 7 | `rhel-openssl-1.0.x` | 1.0.x |
| CentOS 8 | `rhel-openssl-1.1.x` | 1.1.x |
Linux (Fedora), x86_64 [#linux-fedora-x86_64]
| Build OS | Prisma engine build name | OpenSSL |
| :-------- | :----------------------- | :-----: |
| Fedora 28 | `rhel-openssl-1.1.x` | 1.1.x |
| Fedora 29 | `rhel-openssl-1.1.x` | 1.1.x |
| Fedora 30 | `rhel-openssl-1.1.x` | 1.1.x |
| Fedora 36 | `rhel-openssl-3.0.x` | 3.0.x |
| Fedora 37 | `rhel-openssl-3.0.x` | 3.0.x |
| Fedora 38 | `rhel-openssl-3.0.x` | 3.0.x |
Linux (Linux Mint), x86_64 [#linux-linux-mint-x86_64]
| Build OS | Prisma engine build name | OpenSSL |
| :------------ | :----------------------- | :-----: |
| Linux Mint 18 | `debian-openssl-1.0.x` | 1.0.x |
| Linux Mint 19 | `debian-openssl-1.1.x` | 1.1.x |
| Linux Mint 20 | `debian-openssl-1.1.x` | 1.1.x |
| Linux Mint 21 | `debian-openssl-3.0.x` | 3.0.x |
Linux (Arch Linux), x86_64 [#linux-arch-linux-x86_64]
| Build OS | Prisma engine build name | OpenSSL |
| :-------------------- | :----------------------- | :-----: |
| Arch Linux 2019.09.01 | `debian-openssl-1.1.x` | 1.1.x |
| Arch Linux 2023.04.23 | `debian-openssl-3.0.x` | 3.0.x |
Linux ARM64 (all major distros but Alpine) [#linux-arm64-all-major-distros-but-alpine]
| Build OS | Prisma engine build name | OpenSSL |
| :----------------------------- | :-------------------------- | :-----: |
| Linux ARM64 glibc-based distro | `linux-arm64-openssl-1.0.x` | 1.0.x |
| Linux ARM64 glibc-based distro | `linux-arm64-openssl-1.1.x` | 1.1.x |
| Linux ARM64 glibc-based distro | `linux-arm64-openssl-3.0.x` | 3.0.x |
Examples [#examples-1]
Specify the prisma-client-js generator with the default output, previewFeatures, engineType and binaryTargets [#specify-the-prisma-client-js-generator-with-the-default-output-previewfeatures-enginetype-and-binarytargets]
```prisma
generator client {
provider = "prisma-client-js"
}
```
Note that the above `generator` definition is **equivalent** to the following because it uses the default values for `output`, `engineType` and `binaryTargets` (and implicitly `previewFeatures`):
```prisma
generator client {
provider = "prisma-client-js"
output = "node_modules/.prisma/client"
engineType = "library"
binaryTargets = ["native"]
}
```
Specify a custom output location for Prisma Client [#specify-a-custom-output-location-for-prisma-client]
This example shows how to define a custom `output` location of the generated asset to override the default one.
```prisma
generator client {
provider = "prisma-client-js"
output = "../src/generated/client"
}
```
Specify custom binaryTargets to ensure compatibility with the OS [#specify-custom-binarytargets-to-ensure-compatibility-with-the-os]
This example shows how to configure Prisma Client to run on `Ubuntu 19.04 (disco)` based on the table [above](#linux-ubuntu-x86_64).
```prisma
generator client {
provider = "prisma-client-js"
binaryTargets = ["debian-openssl-1.1.x"]
}
```
Specify a provider pointing to some custom generator implementation [#specify-a-provider-pointing-to-some-custom-generator-implementation]
This example shows how to use a custom generator that's located in a directory called `my-generator`.
```prisma
generator client {
provider = "./my-generator"
}
```
model [#model]
Defines a Prisma [model](/orm/prisma-schema/data-model/models#defining-models) .
Remarks [#remarks-1]
* Every record of a model must be *uniquely* identifiable. You must define *at least* one of the following attributes per model:
* [`@unique`](#unique)
* [`@@unique`](#unique-1)
* [`@id`](#id)
* [`@@id`](#id-1)
Naming conventions [#naming-conventions]
* Model names must adhere to the following regular expression: `[A-Za-z][A-Za-z0-9_]*`
* Model names must start with a letter and are typically spelled in [PascalCase](https://wiki.c2.com/?PascalCase)
* Model names should use the singular form (for example, `User` instead of `user`, `users` or `Users`)
* Prisma ORM has a number of **reserved words** that are being used by Prisma ORM internally and therefore cannot be used as a model name. You can find the reserved words [here](https://github.com/prisma/prisma/blob/6.5.0/packages/client/src/generation/generateClient.ts#L556-L605) and [here](https://github.com/prisma/prisma-engines/blob/main/psl/parser-database/src/names/reserved_model_names.rs#L44).
> **Note**: You can use the [`@@map` attribute](#map-1) to map a model (for example, `User`) to a table with a different name that does not match model naming conventions (for example, `users`).
Order of fields [#order-of-fields]
* Introspection lists model fields in the same order as the corresponding columns in the database. Relation fields are listed after scalar fields.
Examples [#examples-2]
A model named User with two scalar fields [#a-model-named-user-with-two-scalar-fields]
Relational databases
MongoDB
```prisma
model User {
email String @unique // `email` can not be optional because it's the only unique field on the model
name String?
}
```
```prisma
model User {
id String @default(auto()) @map("_id") @db.ObjectId
email String @unique
name String?
}
```
model fields [#model-fields]
[Fields](/orm/prisma-schema/data-model/models#defining-fields) are properties of models.
Remarks [#remarks-2]
Naming conventions [#naming-conventions-1]
* Must start with a letter
* Typically spelled in camelCase
* Must adhere to the following regular expression: `[A-Za-z][A-Za-z0-9_]*`
> **Note**: You can use the [`@map` attribute](#map) to [map a field name to a column](/orm/prisma-client/setup-and-configuration/custom-model-and-field-names) with a different name that does not match field naming conventions: e.g. `myField @map("my_field")`.
model field scalar types [#model-field-scalar-types]
The *data source connector* determines what *native database type* each of Prisma ORM scalar type maps to. Similarly, the *generator* determines what *type in the target programming language* each of these types map to.
Prisma models also have [model field types](/orm/prisma-schema/data-model/relations) that define relations between models.
String [#string]
Variable length text.
Default type mappings [#default-type-mappings]
| Connector | Default mapping |
| ----------- | ---------------- |
| PostgreSQL | `text` |
| SQL Server | `nvarchar(1000)` |
| MySQL | `varchar(191)` |
| MongoDB | `String` |
| SQLite | `TEXT` |
| CockroachDB | `STRING` |
PostgreSQL [#postgresql]
| Native database type | Native database type attribute | Notes |
| :------------------- | :----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `text` | `@db.Text` | |
| `char(x)` | `@db.Char(x)` | |
| `varchar(x)` | `@db.VarChar(x)` | |
| `bit(x)` | `@db.Bit(x)` | |
| `varbit` | `@db.VarBit` | |
| `uuid` | `@db.Uuid` | |
| `xml` | `@db.Xml` | |
| `inet` | `@db.Inet` | |
| `citext` | `@db.Citext` | Only available if [Citext extension is enabled](/orm/prisma-schema/data-model/unsupported-database-features#enable-postgresql-extensions-for-native-database-functions). |
MySQL [#mysql]
| Native database type | Native database type attribute |
| :------------------- | :----------------------------- |
| `VARCHAR(x)` | `@db.VarChar(x)` |
| `TEXT` | `@db.Text` |
| `CHAR(x)` | `@db.Char(x)` |
| `TINYTEXT` | `@db.TinyText` |
| `MEDIUMTEXT` | `@db.MediumText` |
| `LONGTEXT` | `@db.LongText` |
You can use Prisma Migrate to map `@db.Bit(1)` to `String`:
```prisma
model Model {
/* ... */
myField String @db.Bit(1)
}
```
MongoDB [#mongodb]
`String`
| Native database type attribute | Notes |
| :----------------------------- | :-------------------------------------------------------------------------------- |
| `@db.String` | |
| `@db.ObjectId` | Required if the underlying BSON type is `OBJECT_ID` (ID fields, relation scalars) |
Microsoft SQL Server [#microsoft-sql-server]
| Native database type | Native database type attribute |
| :------------------- | :----------------------------- |
| `char(x)` | `@db.Char(x)` |
| `nchar(x)` | `@db.NChar(x)` |
| `varchar(x)` | `@db.VarChar(x)` |
| `nvarchar(x)` | `@db.NVarChar(x)` |
| `text` | `@db.Text` |
| `ntext` | `@db.NText` |
| `xml` | `@db.Xml` |
| `uniqueidentifier` | `@db.UniqueIdentifier` |
SQLite [#sqlite]
`TEXT`
CockroachDB [#cockroachdb]
| Native database type | Native database type attribute | Notes |
| :--------------------------------------- | :----------------------------- | ----- |
| `STRING(x)` \| `TEXT(x)` \| `VARCHAR(x)` | `@db.String(x)` | |
| `CHAR(x)` | `@db.Char(x)` | |
| `"char"` | `@db.CatalogSingleChar` | |
| `BIT(x)` | `@db.Bit(x)` | |
| `VARBIT` | `@db.VarBit` | |
| `UUID` | `@db.Uuid` | |
| `INET` | `@db.Inet` | |
Note that the `xml` and `citext` types supported in PostgreSQL are not currently supported in CockroachDB.
Clients [#clients]
| Prisma Client JS |
| ---------------- |
| `string` |
Boolean [#boolean]
True or false value.
Default type mappings [#default-type-mappings-1]
| Connector | Default mapping |
| ----------- | --------------- |
| PostgreSQL | `boolean` |
| SQL Server | `bit` |
| MySQL | `TINYINT(1)` |
| MongoDB | `Bool` |
| SQLite | `INTEGER` |
| CockroachDB | `BOOL` |
PostgreSQL [#postgresql-1]
| Native database types | Native database type attribute | Notes |
| :-------------------- | :----------------------------- | ----- |
| `boolean` | `@db.Boolean` | |
MySQL [#mysql-1]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TINYINT(1)` | `@db.TinyInt(1)` | `TINYINT` maps to `Int` if the max length is greater than 1 (for example, `TINYINT(2)`) *or* the default value is anything other than `1`, `0`, or `NULL` |
| `BIT(1)` | `@db.Bit` | |
MongoDB [#mongodb-1]
`Bool`
Microsoft SQL Server [#microsoft-sql-server-1]
| Native database types | Native database type attribute | Notes |
| :-------------------- | :----------------------------- | ----- |
| `bit` | `@db.Bit` | |
SQLite [#sqlite-1]
`INTEGER`
CockroachDB [#cockroachdb-1]
| Native database types | Native database type attribute | Notes |
| :-------------------- | :----------------------------- | ----- |
| `BOOL` | `@db.Bool` | |
Clients [#clients-1]
| Prisma Client JS |
| ---------------- |
| `boolean` |
Int [#int]
Default type mappings [#default-type-mappings-2]
| Connector | Default mapping |
| ----------- | --------------- |
| PostgreSQL | `integer` |
| SQL Server | `int` |
| MySQL | `INT` |
| MongoDB | `Int` |
| SQLite | `INTEGER` |
| CockroachDB | `INT` |
PostgreSQL [#postgresql-2]
| Native database types | Native database type attribute | Notes |
| -------------------------- | ---------------------------------------- | ----- |
| `integer` \| `int`, `int4` | `@db.Integer` | |
| `smallint` \| `int2` | `@db.SmallInt` | |
| `smallserial` \| `serial2` | `@db.SmallInt @default(autoincrement())` | |
| `serial` \| `serial4` | `@db.Int @default(autoincrement())` | |
| `oid` | `@db.Oid` | |
MySQL [#mysql-2]
| Native database types | Native database type attribute | Notes |
| :-------------------- | :----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `INT` | `@db.Int` | |
| `INT UNSIGNED` | `@db.UnsignedInt` | |
| `SMALLINT` | `@db.SmallInt` | |
| `SMALLINT UNSIGNED` | `@db.UnsignedSmallInt` | |
| `MEDIUMINT` | `@db.MediumInt` | |
| `MEDIUMINT UNSIGNED` | `@db.UnsignedMediumInt` | |
| `TINYINT` | `@db.TinyInt` | `TINYINT` maps to `Int` if the max length is greater than 1 (for example, `TINYINT(2)`) *or* the default value is anything other than `1`, `0`, or `NULL`. `TINYINT(1)` maps to `Boolean`. |
| `TINYINT UNSIGNED` | `@db.UnsignedTinyInt` | `TINYINT(1) UNSIGNED` maps to `Int`, not `Boolean` |
| `YEAR` | `@db.Year` | |
MongoDB [#mongodb-2]
`Int`
| Native database type attribute | Notes |
| :----------------------------- | :---- |
| `@db.Int` | |
| `@db.Long` | |
Microsoft SQL Server [#microsoft-sql-server-2]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `int` | `@db.Int` | |
| `smallint` | `@db.SmallInt` | |
| `tinyint` | `@db.TinyInt` | |
| `bit` | `@db.Bit` | |
SQLite [#sqlite-2]
`INTEGER`
CockroachDB [#cockroachdb-2]
| Native database types | Native database type attribute | Notes |
| ---------------------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| `INTEGER` \| `INT` \| `INT8` | `@db.Int8` | Note that this differs from PostgreSQL, where `integer` and `int` are aliases for `int4` and map to `@db.Integer` |
| `INT4` | `@db.Int4` | |
| `INT2` \| `SMALLINT` | `@db.Int2` | |
| `SMALLSERIAL` \| `SERIAL2` | `@db.Int2 @default(autoincrement())` | |
| `SERIAL` \| `SERIAL4` | `@db.Int4 @default(autoincrement())` | |
| `SERIAL8` \| `BIGSERIAL` | `@db.Int8 @default(autoincrement())` | |
Clients [#clients-2]
| Prisma Client JS |
| ---------------- |
| `number` |
BigInt [#bigint]
Default type mappings [#default-type-mappings-3]
| Connector | Default mapping |
| ----------- | --------------- |
| PostgreSQL | `bigint` |
| SQL Server | `int` |
| MySQL | `BIGINT` |
| MongoDB | `Long` |
| SQLite | `INTEGER` |
| CockroachDB | `INTEGER` |
PostgreSQL [#postgresql-3]
| Native database types | Native database type attribute | Notes |
| ------------------------ | -------------------------------------- | ----- |
| `bigint` \| `int8` | `@db.BigInt` | |
| `bigserial` \| `serial8` | `@db.BigInt @default(autoincrement())` | |
MySQL [#mysql-3]
| Native database types | Native database type attribute | Notes |
| --------------------- | ---------------------------------------------- | ----- |
| `BIGINT` | `@db.BigInt` | |
| `SERIAL` | `@db.UnsignedBigInt @default(autoincrement())` | |
MongoDB [#mongodb-3]
`Long`
Microsoft SQL Server [#microsoft-sql-server-3]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `bigint` | `@db.BigInt` | |
SQLite [#sqlite-3]
`INTEGER`
CockroachDB [#cockroachdb-3]
| Native database types | Native database type attribute | Notes |
| --------------------------- | ------------------------------------ | -------------------------------------------------------------------------- |
| `BIGINT` \| `INT` \| `INT8` | `@db.Int8` | Note that this differs from PostgreSQL, where `int` is an alias for `int4` |
| `bigserial` \| `serial8` | `@db.Int8 @default(autoincrement())` | |
Clients [#clients-3]
| Client | Type | Description |
| :--------------- | :-------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------- |
| Prisma Client JS | [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) | See [examples of working with `BigInt`](/orm/prisma-client/special-fields-and-types#working-with-bigint) |
Float [#float]
Floating point number.
Default type mappings [#default-type-mappings-4]
| Connector | Default mapping |
| ----------- | ------------------ |
| PostgreSQL | `double precision` |
| SQL Server | `float(53)` |
| MySQL | `DOUBLE` |
| MongoDB | `Double` |
| SQLite | `REAL` |
| CockroachDB | `DOUBLE PRECISION` |
PostgreSQL [#postgresql-4]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `double precision` | `@db.DoublePrecision` | |
| `real` | `@db.Real` | |
MySQL [#mysql-4]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `FLOAT` | `@db.Float` | |
| `DOUBLE` | `@db.Double` | |
MongoDB [#mongodb-4]
`Double`
Microsoft SQL Server [#microsoft-sql-server-4]
| Native database types | Native database type attribute |
| --------------------- | ------------------------------ |
| `float` | `@db.Float` |
| `money` | `@db.Money` |
| `smallmoney` | `@db.SmallMoney` |
| `real` | `@db.Real` |
SQLite connector [#sqlite-connector]
`REAL`
CockroachDB [#cockroachdb-4]
| Native database types | Native database type attribute | Notes |
| ------------------------------ | ------------------------------ | ----- |
| `DOUBLE PRECISION` \| `FLOAT8` | `@db.Float8` | |
| `REAL` \| `FLOAT4` \| `FLOAT` | `@db.Float4` | |
Clients [#clients-4]
| Prisma Client JS |
| ---------------- |
| `number` |
Decimal [#decimal]
Default type mappings [#default-type-mappings-5]
| Connector | Default mapping |
| ----------- | -------------------------------------------------------------- |
| PostgreSQL | `decimal(65,30)` |
| SQL Server | `decimal(32,16)` |
| MySQL | `DECIMAL(65,30)` |
| MongoDB | [Not supported](https://github.com/prisma/prisma/issues/12637) |
| SQLite | `DECIMAL` |
| CockroachDB | `DECIMAL` |
PostgreSQL [#postgresql-5]
| Native database types | Native database type attribute | Notes |
| ---------------------- | ------------------------------ | ----- |
| `decimal` \| `numeric` | `@db.Decimal(p, s)`† | |
| `money` | `@db.Money` | |
* † `p` (precision), the maximum total number of decimal digits to be stored. `s` (scale), the number of decimal digits that are stored to the right of the decimal point.
MySQL [#mysql-5]
| Native database types | Native database type attribute | Notes |
| ---------------------- | ------------------------------ | ----- |
| `DECIMAL` \| `NUMERIC` | `@db.Decimal(p, s)`† | |
* † `p` (precision), the maximum total number of decimal digits to be stored. `s` (scale), the number of decimal digits that are stored to the right of the decimal point.
MongoDB [#mongodb-5]
[Not supported](https://github.com/prisma/prisma/issues/12637).
Microsoft SQL Server [#microsoft-sql-server-5]
| Native database types | Native database type attribute | Notes |
| ---------------------- | ------------------------------ | ----- |
| `decimal` \| `numeric` | `@db.Decimal(p, s)`† | |
* † `p` (precision), the maximum total number of decimal digits to be stored. `s` (scale), the number of decimal digits that are stored to the right of the decimal point.
SQLite [#sqlite-4]
`DECIMAL` (changed from `REAL` in 2.17.0)
CockroachDB [#cockroachdb-5]
| Native database types | Native database type attribute | Notes |
| ------------------------------- | ------------------------------ | ------------------------------------------------------------- |
| `DECIMAL` \| `DEC` \| `NUMERIC` | `@db.Decimal(p, s)`† | |
| `money` | Not yet | PostgreSQL's `money` type is not yet supported by CockroachDB |
* † `p` (precision), the maximum total number of decimal digits to be stored. `s` (scale), the number of decimal digits that are stored to the right of the decimal point.
Clients [#clients-5]
| Client | Type | Description |
| :--------------- | :------------------------------------------------- | :--------------------------------------------------------------------------------------------------------- |
| Prisma Client JS | [`Decimal`](https://mikemcl.github.io/decimal.js/) | See [examples of working with `Decimal`](/orm/prisma-client/special-fields-and-types#working-with-decimal) |
DateTime [#datetime]
Remarks [#remarks-3]
* Prisma Client returns all `DateTime` as native [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) objects.
* Currently, Prisma ORM [does not support](https://github.com/prisma/prisma/issues/5006) [zero dates](https://dev.mysql.com/doc/refman/8.3/en/date-and-time-types.html#:~\:text=The%20following%20table%20shows%20the%20format%20of%20the%20%E2%80%9Czero%E2%80%9D%20value%20for%20each%20type) (`0000-00-00 00:00:00`, `0000-00-00`, `00:00:00`) in MySQL.
* There currently is a [bug](https://github.com/prisma/prisma/issues/9516) that doesn't allow you to pass in `DateTime` values as strings and produces a runtime error when you do. `DateTime` values need to be passed as [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) objects (i.e. `new Date('2024-12-04')` instead of `'2024-12-04'`).
You can find more info and examples in this section: [Working with `DateTime`](/orm/prisma-client/special-fields-and-types#working-with-datetime).
Default type mappings [#default-type-mappings-6]
| Connector | Default mapping |
| ----------- | --------------- |
| PostgreSQL | `timestamp(3)` |
| SQL Server | `datetime2` |
| MySQL | `DATETIME(3)` |
| MongoDB | `Timestamp` |
| SQLite | `NUMERIC` |
| CockroachDB | `TIMESTAMP` |
PostgreSQL [#postgresql-6]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `timestamp(x)` | `@db.Timestamp(x)` | |
| `timestamptz(x)` | `@db.Timestamptz(x)` | |
| `date` | `@db.Date` | |
| `time(x)` | `@db.Time(x)` | |
| `timetz(x)` | `@db.Timetz(x)` | |
MySQL [#mysql-6]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `DATETIME(x)` | `@db.DateTime(x)` | |
| `DATE(x)` | `@db.Date(x)` | |
| `TIME(x)` | `@db.Time(x)` | |
| `TIMESTAMP(x)` | `@db.Timestamp(x)` | |
You can also use MySQL's `YEAR` type with `Int`:
```prisma
yearField Int @db.Year
```
MongoDB [#mongodb-6]
`Timestamp`
Microsoft SQL Server [#microsoft-sql-server-6]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `date` | `@db.Date` | |
| `time` | `@db.Time` | |
| `datetime` | `@db.DateTime` | |
| `datetime2` | `@db.DateTime2` | |
| `smalldatetime` | `@db.SmallDateTime` | |
| `datetimeoffset` | `@db.DateTimeOffset` | |
SQLite [#sqlite-5]
`NUMERIC` or `STRING`. If the underlying data type is `STRING`, you must use one of the following formats:
* [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) (`1996-12-19T16:39:57-08:00`)
* [RFC 2822](https://datatracker.ietf.org/doc/html/rfc2822#section-3.3) (`Tue, 1 Jul 2003 10:52:37 +0200`)
CockroachDB [#cockroachdb-6]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `TIMESTAMP(x)` | `@db.Timestamp(x)` | |
| `TIMESTAMPTZ(x)` | `@db.Timestamptz(x)` | |
| `DATE` | `@db.Date` | |
| `TIME(x)` | `@db.Time(x)` | |
| `TIMETZ(x)` | `@db.Timetz(x)` | |
Clients [#clients-6]
| Prisma Client JS |
| ---------------- |
| `Date` |
Json [#json]
A JSON object.
Default type mappings [#default-type-mappings-7]
| Connector | Default mapping |
| ----------- | ------------------------------------------------------------------------------------------------------------ |
| PostgreSQL | `jsonb` |
| SQL Server | [Not supported](https://github.com/prisma/prisma/issues/7417) |
| MySQL | `JSON` |
| MongoDB | [A valid `BSON` object (Relaxed mode)](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/) |
| SQLite | `JSONB` |
| CockroachDB | `JSONB` |
PostgreSQL [#postgresql-7]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `json` | `@db.Json` | |
| `jsonb` | `@db.JsonB` | |
MySQL [#mysql-7]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `JSON` | `@db.Json` | |
MongoDB [#mongodb-7]
[A valid `BSON` object (Relaxed mode)](https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/)
Microsoft SQL Server [#microsoft-sql-server-7]
Microsoft SQL Server does not have a specific data type for JSON. However, there are a number of [built-in functions for reading and modifying JSON](https://learn.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server?view=sql-server-ver15#extract-values-from-json-text-and-use-them-in-queries).
SQLite [#sqlite-6]
Not supported
CockroachDB [#cockroachdb-7]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `JSON` \| `JSONB` | `@db.JsonB` | |
Clients [#clients-7]
| Prisma Client JS |
| ---------------- |
| `object` |
Bytes [#bytes]
Default type mappings [#default-type-mappings-8]
| Connector | Default mapping |
| ----------- | --------------- |
| PostgreSQL | `bytea` |
| SQL Server | `varbinary` |
| MySQL | `LONGBLOB` |
| MongoDB | `BinData` |
| SQLite | `BLOB` |
| CockroachDB | `BYTES` |
PostgreSQL [#postgresql-8]
| Native database types | Native database type attribute |
| --------------------- | ------------------------------ |
| `bytea` | `@db.ByteA` |
MySQL [#mysql-8]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `LONGBLOB` | `@db.LongBlob` | |
| `BINARY` | `@db.Binary` | |
| `VARBINARY` | `@db.VarBinary` | |
| `TINYBLOB` | `@db.TinyBlob` | |
| `BLOB` | `@db.Blob` | |
| `MEDIUMBLOB` | `@db.MediumBlob` | |
| `BIT` | `@db.Bit` | |
MongoDB [#mongodb-8]
`BinData`
| Native database type attribute | Notes |
| :----------------------------- | :-------------------------------------------------------------------------------- |
| `@db.ObjectId` | Required if the underlying BSON type is `OBJECT_ID` (ID fields, relation scalars) |
| `@db.BinData` | |
Microsoft SQL Server [#microsoft-sql-server-8]
| Native database types | Native database type attribute | Notes |
| --------------------- | ------------------------------ | ----- |
| `binary` | `@db.Binary` | |
| `varbinary` | `@db.VarBinary` | |
| `image` | `@db.Image` | |
SQLite [#sqlite-7]
`BLOB`
CockroachDB [#cockroachdb-8]
| Native database types | Native database type attribute |
| ---------------------------- | ------------------------------ |
| `BYTES` \| `BYTEA` \| `BLOB` | `@db.Bytes` |
Clients [#clients-8]
| Client | Type | Description |
| :------------------------------------------------------------ | :---------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------- |
| Prisma Client JS | [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) | See [examples of working with `Bytes`](/orm/prisma-client/special-fields-and-types#working-with-bytes) |
| Prisma Client JS ([before v6](/guides/upgrade-prisma-orm/v6)) | [`Buffer`](https://nodejs.org/api/buffer.html) | See [examples of working with `Bytes`](/orm/prisma-client/special-fields-and-types#working-with-bytes) |
Unsupported [#unsupported]
**Not supported by MongoDB**
The [MongoDB connector](/orm/core-concepts/supported-databases/mongodb) does not support the `Unsupported` type.
The `Unsupported` type was introduced in [2.17.0](https://github.com/prisma/prisma/releases/tag/2.17.0) and allows you to represent data types in the Prisma schema that are not supported by Prisma Client. Fields of type `Unsupported` can be created during Introspection with `prisma db pull` or written by hand, and created in the database with Prisma Migrate or `db push`.
Remarks [#remarks-4]
* Fields with `Unsupported` types are not available in the generated client.
* If a model contains a **required** `Unsupported` type, `prisma.model.create(..)`, `prisma.model.update(...)` and `prisma.model.upsert(...)` are not available in Prisma Client.
* When you introspect a database that contains unsupported types, Prisma ORM will provide the following warning:
```
*** WARNING ***
These fields are not supported by Prisma Client, because Prisma does not currently support their types.
* Model "Post", field: "circle", original data type: "circle"
```
Examples [#examples-3]
```prisma
model Star {
id Int @id @default(autoincrement())
position Unsupported("circle")?
example1 Unsupported("circle")
circle Unsupported("circle")? @default(dbgenerated("'<(10,4),11>'::circle"))
}
```
model field type modifiers [#model-field-type-modifiers]
[] modifier [#-modifier]
Makes a field a list.
Remarks [#remarks-5]
* Cannot be optional (for example `Post[]?`).
Relational databases [#relational-databases]
* Scalar lists (arrays) are only supported in the data model if your database natively supports them. Currently, scalar lists are therefore only supported when using PostgreSQL or CockroachDB (since MySQL and SQLite don't natively support scalar lists).
MongoDB [#mongodb-9]
* Scalar lists are supported
Examples [#examples-4]
Define a scalar list [#define-a-scalar-list]
Relational databases
MongoDB
```prisma highlight=3;normal
model User {
id Int @id @default(autoincrement())
favoriteColors String[] // [!code highlight]
}
```
```prisma highlight=3;normal
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
favoriteColors String[] // [!code highlight]
}
```
Define a scalar list with a default value [#define-a-scalar-list-with-a-default-value]
Relational databases
MongoDB
```prisma highlight=3;normal
model User {
id Int @id @default(autoincrement())
favoriteColors String[] @default(["red", "blue", "green"]) // [!code highlight]
}
```
```prisma highlight=3;normal
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
favoriteColors String[] @default(["red", "blue", "green"]) // [!code highlight]
}
```
? modifier [#-modifier-1]
Makes a field optional.
Remarks [#remarks-6]
* Cannot be used with a list field (for example, `Posts[]`)
Examples [#examples-5]
Optional name field [#optional-name-field]
```prisma highlight=3;normal
model User {
id Int @id @default(autoincrement())
name String? // [!code highlight]
}
```
Attributes [#attributes]
Attributes modify the behavior of a [field](#model-fields) or block (e.g. [models](#model)). There are two ways to add attributes to your data model:
* *Field* attributes are prefixed with `@`
* *Block* attributes are prefixed with `@@`
Some attributes take arguments. Arguments in attributes are always named, but in most cases the argument *name* can be omitted.
> **Note**: The leading underscore in a signature means the *argument name* can be omitted.
@id [#id]
Defines a single-field ID on the model.
Remarks [#remarks-7]
General [#general]
* Cannot be defined on a relation field
* Cannot be optional
Relational databases [#relational-databases-1]
* Corresponding database construct: `PRIMARY KEY`
* Can be annotated with a [`@default`](#default) attribute that uses [functions](#attribute-functions) to auto-generate an ID:
* [`autoincrement()`](#autoincrement)
* [`cuid()`](#cuid)
* [`uuid()`](#uuid)
* [`ulid()`](#ulid)
* Can be defined on any scalar field (`String`, `Int`, `enum`)
MongoDB [#mongodb-10]
* Corresponding database construct: [Any valid BSON type, except arrays](https://www.mongodb.com/docs/manual/core/document/#the-_id-field)
* Every model must define an `@id` field
* The [underlying ID field name is always `_id`](https://www.mongodb.com/docs/manual/core/document/#the-_id-field), and must be mapped with `@map("_id")`
* Can be defined on any scalar field (`String`, `Int`, `enum`) unless you want to use `ObjectId` in your database
* To use an [`ObjectId`](https://www.mongodb.com/docs/manual/reference/method/ObjectId/) as your ID, you must:
* Use the `String` or `Bytes` field type
* Annotate your field with `@db.ObjectId`:
```prisma
id String @db.ObjectId @map("_id")
```
* Optionally, annotate your field with a [`@default`](#default) attribute that uses [the `auto()` function](#auto) to auto-generate an `ObjectId`
```prisma
id String @db.ObjectId @map("_id") @default(auto())
```
* [`cuid()`](#cuid), [`uuid()`](#uuid) and [`ulid()`](#ulid) are supported but do not generate a valid `ObjectId` - use `auto()` instead for `@id`
* `autoincrement()` is **not supported**
Arguments [#arguments]
| Name | Required | Type | Description |
| ----------- | -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `map` | **No** | `String` | The name of the underlying primary key constraint in the database.