Bun
Scaffold a Prisma ORM app with Bun, run your first typed query, serve users over HTTP, and deploy to Prisma Compute.
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
- 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
To delegate this guide to your coding agent, copy the prompt below and hand it over:
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 bunAnswer the prompts for contract authoring style. 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
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
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
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
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
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 your first app.
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
- Learn the fundamentals: filtering, sorting, pagination, and writes.
- Read the Prisma ORM overview for the concepts behind contracts and typed queries.
