# Bun (/docs/guides/runtimes/bun)

> For the complete Prisma documentation index, see [llms.txt](https://www.prisma.io/docs/llms.txt). A markdown version of any docs page is available by appending `.md` to its URL.

Scaffold a Prisma 8 app with Bun, run your first typed query, serve users over HTTP, and deploy to Prisma Compute.

Location: Guides > Runtimes > Bun

## Introduction [#introduction]

In this guide, you scaffold a Prisma 8 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](https://www.prisma.io/docs/compute). Bun runs TypeScript directly, so there is no build step anywhere in the flow.

Every command and code sample below was run end to end against a live Prisma Postgres database.

## Prerequisites [#prerequisites]

* [Bun](https://bun.sh/) 1.1 or later (`bun --version`)
* A PostgreSQL connection string, or nothing at all: `bunx create-db` can create a [Prisma Postgres](https://www.prisma.io/docs/postgres) database for you

## Use with your agent [#use-with-your-agent]

To delegate this guide to your coding agent, copy the prompt below and hand it over:

```text
Create a new Bun app with Prisma 8, run a first typed query, and deploy it to Prisma Compute.

1. Scaffold: `bunx create-prisma@latest create 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 run dev` prints the created user.
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` script at the server (`esbuild src/server.ts --bundle --platform=node --format=esm --outfile=dist/server.mjs`), 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 8 skills.
```

## 1. Scaffold the project [#1-scaffold-the-project]

Create the project with `create-prisma`. Pick Bun as the package manager when prompted, or pass everything up front:

```bash
bunx create-prisma@latest create my-bun-app --template minimal --provider postgres --package-manager bun
```

Answer the prompts for contract authoring style. The scaffold sets up `src/prisma/` with a starter schema and installs dependencies with Bun.

```bash
cd my-bun-app
```

Next, 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`:

```bash
export DATABASE_URL="<your connection string>"
```

## 2. Emit the contract and initialize the database [#2-emit-the-contract-and-initialize-the-database]

Prisma 8 compiles your schema (`src/prisma/contract.prisma`) into a contract that your queries are type-checked against. Emit it, then apply the schema to the database:

```bash
bun run contract:emit
bun run db:init
```

`db:init` creates the tables and signs the database:

```text no-copy
"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 [#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.

```ts title="src/index.ts"
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.runtime().close();
```

`await db.runtime().close()` at the end lets the script exit cleanly; without it, the connection pool keeps the process alive.

## 4. Run it [#4-run-it]

```bash
bun run dev
```

```text no-copy
created user ada+1784893846026@prisma.io
there are now 1 users
```

The `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 [#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`:

```ts title="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:

```bash
bun src/server.ts
```

```bash
curl http://localhost:3000/users
```

```json no-copy
[{ "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.runtime().close()`: the connection pool is shared across requests and closes when the process exits.

## 6. Deploy to Prisma Compute [#6-deploy-to-prisma-compute]

Plain Bun servers are supported on [Prisma Compute](https://www.prisma.io/docs/compute). The scaffold declares the app for [Prisma Composer](https://www.prisma.io/docs/composer) in `module.ts` and `service.ts`, which deploy whatever the `build` script bundles into `dist/server.mjs`. That script bundles `src/index.ts`, so point it at your server instead:

```json title="package.json"
{
  "scripts": {
    "build": "esbuild src/server.ts --bundle --platform=node --format=esm --outfile=dist/server.mjs"
  }
}
```

Sign in once (it opens a browser):

```bash
bunx prisma@latest auth login
```

Then build and deploy from the project directory:

```bash
bun run build
bunx prisma@latest deploy module.ts
```

```text no-copy
my-bun-app
├─ database   postgres-database db_abc123
└─ app        compute-service cps_abc123
              https://xyz.ewr.prisma.build
```

The 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:

```bash
curl https://xyz.ewr.prisma.build/users
```

```json no-copy
[]
```

For previews per Git branch and deploy-on-push, see [Deploy your first app](https://www.prisma.io/docs/prisma-compute/deploy).

## Prompt your coding agent [#prompt-your-coding-agent]

Run [`bunx prisma@latest init`](https://www.prisma.io/docs/cli/init) once to install the [Prisma 8 skills](https://www.prisma.io/docs/ai/tools/skills#available-skills-for-prisma-8) 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 [#next-steps]

* [Learn the fundamentals](https://www.prisma.io/docs/orm/fundamentals/reading-data): filtering, sorting, pagination, and writes.
* [Read the Prisma 8 overview](https://www.prisma.io/docs/orm) for the concepts behind contracts and typed queries.

## Related pages

- [`Deno`](https://www.prisma.io/docs/guides/runtimes/deno): Run a minimal Prisma 8 and PostgreSQL app on Deno.