-
Notifications
You must be signed in to change notification settings - Fork 876
docs(docs): added bun workspace guide #7469
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
aidankmcalister
wants to merge
4
commits into
main
Choose a base branch
from
docs(docs)/bun-workspace-guide
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+357
−1
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,356 @@ | ||
| --- | ||
| title: 'How to use Prisma ORM and Prisma Postgres in a Bun workspaces monorepo' | ||
| metaTitle: 'How to use Prisma ORM and Prisma Postgres in a Bun workspaces monorepo' | ||
| description: 'Learn step-by-step how to integrate Prisma ORM in a Bun workspaces monorepo to build scalable and modular applications efficiently.' | ||
| sidebar_label: 'Bun workspaces' | ||
| image: '/img/guides/prisma-bun-workspaces-cover.png' | ||
| completion_time: '10 min' | ||
| community_section: true | ||
| --- | ||
|
|
||
| ## 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 | ||
|
|
||
| - [Bun](https://bun.sh/docs/installation) installed | ||
| - A [Prisma Postgres](/postgres) database (or another [supported database](/orm/reference/supported-databases)) | ||
|
|
||
| ## 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 | ||
| ``` | ||
|
|
||
| This creates a basic Bun project that includes a `package.json` file and an `index.ts` file. | ||
|
|
||
| Next, add the `workspaces` array to your root `package.json` to define your workspace structure: | ||
|
|
||
| ```json file=package.json | ||
| { | ||
| // add-start | ||
| "name": "my-monorepo", | ||
| "workspaces": ["apps/*", "packages/*"] | ||
| // add-end | ||
| } | ||
| ``` | ||
|
|
||
| Finally, create directories for your applications and shared packages: | ||
|
|
||
| ```bash | ||
| mkdir apps | ||
| mkdir -p packages/database | ||
| ``` | ||
|
|
||
| ## 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 | ||
|
|
||
| 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 | ||
| ``` | ||
|
|
||
| :::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/overview/databases/database-drivers). | ||
|
|
||
| ::: | ||
|
|
||
| ### 2.2. 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. | ||
|
|
||
| :::info | ||
|
|
||
| We're going to be using [Prisma Postgres](/getting-started/prisma-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 file=prisma/schema.prisma | ||
| generator client { | ||
| provider = "prisma-client" | ||
| output = "../generated/prisma" | ||
| } | ||
|
|
||
| datasource db { | ||
| provider = "postgresql" | ||
| } | ||
aidankmcalister marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // add-start | ||
| model User { | ||
| id Int @id @default(autoincrement()) | ||
| email String @unique | ||
| name String? | ||
| } | ||
| // add-end | ||
| ``` | ||
|
|
||
| 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 file=database/package.json | ||
| { | ||
| // add-start | ||
| "scripts": { | ||
| "db:generate": "prisma generate", | ||
| "db:migrate": "prisma migrate dev", | ||
| "db:deploy": "prisma migrate deploy", | ||
| "db:seed": "prisma db seed", | ||
| "db:studio": "prisma studio" | ||
| } | ||
| // add-end | ||
| } | ||
| ``` | ||
|
|
||
| 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 file=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 file=database/index.ts | ||
| export { prisma } from "./client"; | ||
| export * from "./generated/prisma/client"; | ||
| ``` | ||
|
|
||
| ### 2.3. Seed the database | ||
|
|
||
| Add a seed script to populate the database with sample users. Create `prisma/seed.ts` in the database package: | ||
|
|
||
| ```ts file=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 file=database/prisma.config.ts | ||
| migrations: { | ||
| path: "prisma/migrations", | ||
| // add-start | ||
| seed: "bun prisma/seed.ts", | ||
| // add-end | ||
| }, | ||
| ``` | ||
|
|
||
| At this point, your shared database package is fully configured and ready for use across your monorepo. | ||
|
|
||
| ### 2.4. 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 file=package.json | ||
| { | ||
| // add-start | ||
| "scripts": { | ||
| "build": "bun run --filter database db:deploy && bun run --filter database db:generate && bun run --filter web build", | ||
| "start": "bun run --filter web start", | ||
| "dev": "bun run --filter database db:generate && bun run --filter web dev", | ||
| "seed": "bun run --filter database db:seed", | ||
| "studio": "bun run --filter database db:studio" | ||
| } | ||
| // add-end | ||
| } | ||
| ``` | ||
|
|
||
| From the monorepo root, run `bun run seed` to add sample users. Run `bun run studio` to open [Prisma Studio](/postgres/database/prisma-studio) at [`http://localhost:5555`](http://localhost:5555) to view and edit your data. | ||
|
|
||
| ## 3. Set up Next.js 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 | ||
|
|
||
| Navigate to the `apps` directory: | ||
|
|
||
| ```bash | ||
| cd ../../apps | ||
| ``` | ||
|
|
||
| Create a new Next.js app named `web`: | ||
|
|
||
| ```bash | ||
| bun create next-app@latest web --yes | ||
| ``` | ||
|
|
||
| :::note[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 file=web/package.json | ||
| "dependencies": { | ||
| // add-start | ||
| "database": "workspace:*" | ||
| // add-end | ||
| } | ||
| ``` | ||
|
|
||
| Run the following command to install the `database` package: | ||
|
|
||
| ```bash | ||
| bun install | ||
| ``` | ||
|
|
||
| ### 3.2. 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 file=app/page.tsx | ||
| import { prisma } from "database"; | ||
|
|
||
| export default async function Home() { | ||
| const user = await prisma.user.findFirst({ | ||
| select: { | ||
| name: true, | ||
| }, | ||
| }); | ||
|
|
||
| return ( | ||
| <div> | ||
| {user?.name && <p>Hello from {user.name}</p>} | ||
| {!user?.name && <p>No user has been added to the database yet.</p>} | ||
| </div> | ||
| ); | ||
| } | ||
| ``` | ||
|
|
||
| This code demonstrates importing and using the shared Prisma ORM client to query your `User` model. | ||
|
|
||
| ### 3.3. 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](/postgres/database/prisma-studio) at [`http://localhost:5555`](http://localhost:5555) to view and edit your data. | ||
|
|
||
| ## 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/turborepo) guide. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: prisma/docs
Length of output: 1292
🌐 Web query:
Prisma v7 prisma init --db generated prisma.config.ts template💡 Result:
If you run Prisma ORM v7+:
…it will create
prisma.config.ts(plusprisma/schema.prisma, etc.). If--db“is not recognized”, it’s usuallynpxcaching—usenpx prisma@latest init --dbexplicitly. [3]Typical
prisma.config.tstemplate (Node)This is the shape Prisma expects (and matches what Prisma’s guides show after
init --db):Prisma config files support
prisma.config.ts(and other extensions/locations), and.envis not auto-loaded when usingprisma.config.ts—so importingdotenv/config(in Node) is the common fix. [4][5][2]Note on Bun vs Node
As of Prisma ORM 7.2.0 (Dec 17, 2025),
prisma initgenerates runtime-specific config output (e.g., it won’t assumedotenvis needed for Bun). [1]Sources: Prisma ORM 7.2.0 announcement [1], Prisma “React Router 7” guide showing
init --db+ config example [2], Prisma docs troubleshooting for--dbnot recognized /npxcaching [3], Prisma config reference (file names +.envloading behavior) [4], Prisma config patterns (defineConfig,env()) [5].Update the
prisma.config.tsdescription to match Prisma v7's actual generated template.The generated file uses
env("DATABASE_URL")from theprisma/configmodule (notprocess.env), and it explicitly imports"dotenv/config"rather than simply "expecting" it. Update line 96 to:This matches the actual template generated by
prisma init --dbin Prisma v7.🤖 Prompt for AI Agents