Bun (/docs/guides/runtimes/bun)
For the complete Prisma documentation index, see llms.txt. A markdown version of any docs page is available by appending
.mdto its URL.
Scaffold a Prisma ORM app with Bun, run your first typed query, serve users over HTTP, and deploy to Prisma Compute.
Location: Guides > Runtimes > Bun
Introduction
Section titled “Introduction”In this guide, you scaffold a Prisma ORM project with Bun, initialize a PostgreSQL database from your schema, run your first typed query, serve query results over HTTP with Bun.serve, and deploy the server to Prisma Compute. Bun runs TypeScript directly, so nothing has to be compiled to work locally; the deploy bundles the server with tsdown.
Every command and code sample below was run end to end against a live Prisma Postgres database.
Prerequisites
Section titled “Prerequisites”- Bun 1.1 or later (
bun --version) - A PostgreSQL connection string, or nothing at all:
bunx create-dbcan create a Prisma Postgres database for you
Use with your agent
Section titled “Use with your agent”To delegate this guide to your coding agent, copy the prompt below and hand it over:
Create a new Bun app with Prisma ORM, run a first typed query, and deploy it to Prisma Compute.
1. Scaffold: `bun create prisma@latest my-bun-app --template minimal --provider postgres --package-manager bun --yes`. Then run `bunx prisma@latest init` in `my-bun-app` so the Prisma agent skills are installed and stay current, and use them. Get a database connection string: use the one I give you, or create a Prisma Postgres database with `bunx create-db` and show me the claim URL it prints. Export it as `DATABASE_URL` in the shell; the generated scripts read the environment variable, not `.env`.
2. In `my-bun-app`, run `bun run contract:emit`, then `bun run db:init`, with `DATABASE_URL` exported.
3. Replace `src/index.ts` with a script that creates a user and reads all users back via `db.orm.public.User`, following https://www.prisma.io/docs/guides/runtimes/bun.md, and verify `bun src/index.ts` prints the created user (`bun run dev` is `tsx watch`, which does not exit).
4. Add `src/server.ts` with a `Bun.serve` server exposing GET /users, and verify `curl http://localhost:3000/users` returns the users.
5. Deploy: check `bunx prisma@latest auth whoami`; if I am not signed in, stop and ask me to run `bunx prisma@latest auth login`. Then point the build at the server by setting `entry` in `tsdown.config.ts` to `{ server: "src/server.ts" }`, run `bun run build`, then `bunx prisma@latest deploy module.ts`, and verify the live URL's /users endpoint returns `[]`. The deployed app provisions its own fresh Prisma Postgres database, so the local users are not there; do not pass the local DATABASE_URL. If the deploy fails with `HostedStateBootstrapError`, a project with the module's name exists in my workspace but its hosted state cannot be verified; re-run the deploy with `--name <a unique name>`.
Use the installed Prisma ORM skills.1. Scaffold the project
Section titled “1. Scaffold the project”Create the project with create-prisma. Pick Bun as the package manager when prompted, or pass everything up front:
bun create prisma@latest my-bun-app --template minimal --provider postgres --package-manager bun --no-deployAnswer the prompts for contract authoring style and agent skills. The scaffold sets up src/prisma/ with a starter schema and installs dependencies with Bun.
cd my-bun-appNext, set the database connection for the local steps. Use your own PostgreSQL connection string, or create a Prisma Postgres database with bunx create-db; it prints a connection string and a claim URL you can open to keep the database. Export the variable in the shell you work in; the generated scripts read the environment variable, not .env:
export DATABASE_URL="<your connection string>"2. Emit the contract and initialize the database
Section titled “2. Emit the contract and initialize the database”Prisma ORM compiles your schema (src/prisma/contract.prisma) into a contract that your queries are type-checked against. If you chose TypeScript authoring (--authoring typescript), the source is src/prisma/contract.ts and the emitted files land in src/prisma/generated/ instead. Emit it, then apply the schema to the database:
bun run contract:emit
bun run db:initdb:init creates the tables and signs the database:
"summary": "Applied 5 operation(s) across 1 space(s), database signed"If db:init stops with Connection terminated unexpectedly, a database you just created is still starting; wait a few seconds and run it again. The command is safe to repeat and reports Applied 0 operation(s) when there is nothing left to do.
If db:init reports that the contract file is missing, run bun run contract:emit first; the emit step generates src/prisma/contract.json.
3. Write your first query
Section titled “3. Write your first query”Replace src/index.ts with a script that creates a user and reads every user back. Model access is namespace-qualified on PostgreSQL: db.orm.public.User, where public is the default schema.
import { db } from "./prisma/db";
// Create a user, then read every user back
const user = await db.orm.public.User.create({
email: `ada+${Date.now()}@prisma.io`,
name: "Ada Lovelace",
});
console.log(`created user ${user.email}`);
const users = await db.orm.public.User.select("id", "email", "name").all();
console.log(`there are now ${users.length} users`);
await db.close();await db.close() at the end lets the script exit cleanly; without it, the connection pool keeps the process alive.
4. Run it
Section titled “4. Run it”The generated dev script is tsx watch src/index.ts, which re-runs the file on every save. For a single run, call Bun directly:
bun src/index.tscreated user ada+1784893846026@prisma.io
there are now 1 usersThe pg driver may print an SSL mode deprecation warning above the output; it comes from the sslmode=require setting in the generated connection string and does not affect the query.
That is the whole loop: schema to contract, contract to database, typed queries against both.
5. Serve it over HTTP
Section titled “5. Serve it over HTTP”The script pattern works for one-off jobs. To keep the app running and serve query results, add a small HTTP server with Bun.serve. Create src/server.ts:
import { db } from "./prisma/db";
const server = Bun.serve({
port: Number(process.env.PORT ?? 3000),
async fetch(req) {
const { pathname } = new URL(req.url);
if (pathname === "/users") {
const users = await db.orm.public.User.select("id", "email", "name").all();
return Response.json(users);
}
return new Response("Not found", { status: 404 });
},
});
console.log(`Listening on http://localhost:${server.port}`);Start it and check the endpoint:
bun src/server.tscurl http://localhost:3000/users[{ "id": 1, "email": "ada+1784893846026@prisma.io", "name": "Ada Lovelace" }]The server listens on port 3000; set PORT to change it. Unlike the script, the server never calls db.close(): the connection pool is shared across requests and closes when the process exits.
6. Deploy to Prisma Compute
Section titled “6. Deploy to Prisma Compute”Plain Bun servers are supported on Prisma Compute. The scaffold declares the app for Prisma Composer in module.ts and service.ts, which deploy whatever the build script bundles into dist/server.mjs. That script runs tsdown, and the generated tsdown.config.ts sets its entry to src/index.ts, so point the entry at your server instead:
export default defineConfig({
entry: { server: "src/server.ts" },
// the rest of the generated config is unchanged
});Sign in once (it opens a browser):
bunx prisma@latest auth loginThen build and deploy from the project directory:
bun run build
bunx prisma@latest deploy module.tsmy-bun-app
├─ database postgres-database db_abc123
└─ app compute-service cps_abc123
https://xyz.ewr.prisma.buildThe deploy creates a project named after your module in your workspace, and re-running the deploy reuses it: the CLI finds the hosted state it stored on the first run and converges the project to your module. If a project with that name exists but the CLI cannot identify or verify its stored state (one left behind by a different checkout, for example), the deploy stops with HostedStateBootstrapError; deploy under another name with --name <unique-name>, or rename the module in module.ts. The deploy also provisions its own Prisma Postgres database on the platform, declared in module.ts; the users you created locally are not in it. Verify the live endpoint responds with an empty list from the fresh database:
curl https://xyz.ewr.prisma.build/users[]For previews per Git branch and deploy on push, see Deploy on push.
Prompt your coding agent
Section titled “Prompt your coding agent”Run bunx prisma@latest init once to install the Prisma ORM skills for your coding agent and keep them matching your installed packages. Prompts that map to this guide:
- "Using the prisma-8 skill, add a script that lists the 10 newest users."
- "Add a published flag to the Post model in the starter contract, emit the contract, and update the database."
Next steps
Section titled “Next steps”- Learn the fundamentals: filtering, sorting, pagination, and writes.
- Read the Prisma ORM overview for the concepts behind contracts and typed queries.
Related pages
Section titled “Related pages”Deno: Run a minimal Prisma ORM and PostgreSQL app on Deno.