How to use Prisma ORM with Cloudflare D1
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.
Prerequisites
Before starting this guide, make sure you have:
- A Cloudflare account
- Node.js installed (version 18 or higher)
- Wrangler CLI installed (version 3.39.0 or higher)
- Basic familiarity with Cloudflare Workers and D1
1. Configure Prisma schema
In your Prisma schema, add the driverAdapters
Preview feature to the generator
block and set the provider
of the datasource
to sqlite
. If you just bootstrapped the Prisma schema with prisma init
, also be sure to add the following User
model to it:
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"]
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
2. Install dependencies
Next, install the required packages:
npm install @prisma/adapter-d1
Also, be sure to use a version of the Wrangler CLI that's above wrangler@^3.39.0
, otherwise the --remote
flag that's used in the next sections won't be available.
3. Set up D1 database connection
To connect your Workers with the D1 instance, add the following binding to your wrangler.toml
:
name = "prisma-cloudflare-worker-example"
main = "src/index.ts"
compatibility_date = "2024-03-20"
compatibility_flags = ["nodejs_compat"]
[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "__YOUR_D1_DATABASE_NAME__" # to be replaced
database_id = "__YOUR_D1_DATABASE_ID__" # to be replaced
Note that __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 this 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.
4. Set up database migrations
We recommend using prisma migrate
in order to keep your data in D1 migrated. However, if you would prefer to use Cloudflare's migration system, that workflow is also available
4.1 Add needed environment variables
In order to use the Prisma D1 adapter, you'll need to add a few secrets to a .env
file:
DATABASE_URL
: A path to your local D1 instance. Usually"file:./prisma/db.sqlite"
.CLOUDFLARE_ACCOUNT_ID
: Your Cloudflare account ID, fetched vianpx wrangler whoami
CLOUDFLARE_DATABASE_ID
: The ID of your database, retrieved during D1 database creation.CLOUDFLARE_D1_TOKEN
: This API token is used by Prisma ORM to communicate with your D1 instance directly. To create this, follow these steps:- Visit https://dash.cloudflare.com/profile/api-tokens
- Click "Create Token"
- Click "Custom token" template
- Fill out the template: Make sure you use a recognizable name and add the
Account / D1 / Edit
permission. - Click "Continue to summary" and then "Create Token".
You can now store these secrets to be used by Prisma ORM. We recommend a .env
file for local development, but any secret store will work.
DATABASE_URL="file:./prisma/db.sqlite"
CLOUDFLARE_ACCOUNT_ID="0773..."
CLOUDFLARE_DATABASE_ID="01f30366-..."
CLOUDFLARE_D1_TOKEN="F8Cg..."
4.2 Configure Prisma Config
Ensure that you have a prisma.config.ts
file set up in the root of your project with a migration driver adapter defined.
import path from 'node:path'
import type { PrismaConfig } from 'prisma'
import { PrismaD1HTTP } from '@prisma/adapter-d1'
// import your .env file
import 'dotenv/config'
type Env = {
CLOUDFLARE_D1_TOKEN: string
CLOUDFLARE_ACCOUNT_ID: string
CLOUDFLARE_DATABASE_ID: string
}
export default {
earlyAccess: true,
schema: path.join('prisma', 'schema.prisma'),
migration: {
async adapter(env) {
return new PrismaD1HTTP({
CLOUDFLARE_D1_TOKEN: env.CLOUDFLARE_D1_TOKEN,
CLOUDFLARE_ACCOUNT_ID: env.CLOUDFLARE_ACCOUNT_ID,
CLOUDFLARE_DATABASE_ID: env.CLOUDFLARE_DATABASE_ID,
})
},
},
} satisfies PrismaConfig<Env>
This will allow prisma migrate
to interact with your D1 database.
4.3 Run your first migration
You can now run prisma migrate dev
to migrate your database to match your local schema:
npx prisma migrate dev --name init
Let's also create some dummy data that we can query once the Worker is running. This time, we'll use wrangler to run a SQL statement without storing it in a file:
# 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
5. Implement the Worker
Before adding a Prisma Client query to your Worker, you need to generate Prisma Client with the following command:
npx prisma generate
In order to query your database from the Worker using Prisma ORM, you need to:
- Add the
DB
binding to theEnv
interface. (Alternatively, you can runnpx wrangler types
to generate theEnv
type from the binding in a separate file calledworker-configuration.d.ts
.) - Instantiate
PrismaClient
using thePrismaD1
driver adapter. - Send a query using Prisma Client and return the result.
Open src/index.ts
and replace the entire content with the following:
import { PrismaClient } from '@prisma/client'
import { PrismaD1 } from '@prisma/adapter-d1'
export interface Env {
DB: D1Database
}
export default {
async fetch(
request: Request,
env: Env,
ctx: ExecutionContext
): Promise<Response> {
const adapter = new PrismaD1(env.DB)
const prisma = new PrismaClient({ adapter })
const users = await prisma.user.findMany()
const result = JSON.stringify(users)
return new Response(result)
},
}
6. Run the Worker locally
With the database query in place and Prisma Client generated, you can go ahead and run the Worker locally:
npm run dev
Now you can open your browser at http://localhost:8787
to see the result of the database query:
;[{ id: 1, email: 'jane@prisma.io', name: 'Jane Doe (Local)' }]
7. Set the DATABASE_URL
environment variable and deploy the Worker
To deploy the Worker, run the the following command:
npm run deploy
Your deployed Worker is accessible via https://prisma-d1-example.USERNAME.workers.dev
. If you navigate your browser to that URL, you should see the following data that's queried from your remote D1 database:
;[{ id: 1, email: 'jane@prisma.io', name: 'Jane Doe (Remote)' }]
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:
Stay connected with Prisma
Continue your Prisma journey by connecting with our active community. Stay informed, get involved, and collaborate with other developers:
- Follow us on X for announcements, live events and useful tips.
- Join our Discord to ask questions, talk to the community, and get active support through conversations.
- Subscribe on YouTube for tutorials, demos, and streams.
- Engage on GitHub by starring the repository, reporting issues, or contributing to an issue.