# Elysia (Prisma ORM v7) (/docs/guides/v7/frameworks/elysia) > 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. Learn how to use Prisma ORM in an Elysia app Location: Guides > v7 > Frameworks > Elysia ## Introduction [#introduction] [Elysia](https://elysiajs.com/) is a web framework for Bun with end-to-end type safety. Its route handlers are where you call Prisma ORM to read and write a [Prisma Postgres](https://www.prisma.io/postgres) database, and Prismabox keeps its request and response schemas in sync with your Prisma models. In this guide, you'll learn to integrate Prisma ORM with a Prisma Postgres database in an Elysia application. You can find a complete example of this guide on [GitHub](https://github.com/prisma/prisma-examples/tree/latest/orm/elysia). ## Quick start [#quick-start] Run one command to scaffold an Elysia project with Prisma ORM and Prisma Postgres ready to go: #### bun ```bash bunx create-prisma@stable --template elysia ``` #### pnpm ```bash pnpm create prisma@stable --template elysia ``` #### yarn ```bash yarn create prisma@stable --template elysia ``` #### npm ```bash npm create prisma@stable -- --template elysia ``` Or follow the steps below to set it up manually. ## Prerequisites [#prerequisites] * [Bun](https://bun.sh/docs/installation) installed on your system ## 1. Set up your project [#1-set-up-your-project] Create a new Elysia project: #### bun ```bash bunx create-elysia elysia-prisma ``` #### pnpm ```bash pnpm create elysia elysia-prisma ``` #### yarn ```bash yarn create elysia elysia-prisma ``` #### npm ```bash npm create elysia@latest elysia-prisma ``` Navigate to the project directory: ```bash cd elysia-prisma ``` ## 2. Install and configure Prisma [#2-install-and-configure-prisma] ### 2.1. Install dependencies [#21-install-dependencies] Install the required Prisma packages, database adapter, and Prismabox (for generated TypeBox schemas): #### bun ```bash bun add prisma@prev bun-types --dev bun add @prisma/client@7 @prisma/adapter-pg pg prismabox ``` #### pnpm ```bash pnpm add prisma@prev bun-types --save-dev pnpm add @prisma/client@7 @prisma/adapter-pg pg prismabox ``` #### yarn ```bash yarn add prisma@prev bun-types --dev yarn add @prisma/client@7 @prisma/adapter-pg pg prismabox ``` #### npm ```bash npm install prisma@prev bun-types --save-dev npm install @prisma/client@7 @prisma/adapter-pg pg prismabox ``` > [!NOTE] > 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](https://www.prisma.io/docs/orm/v7/core-concepts/supported-databases/database-drivers). Once installed, initialize Prisma in your project: #### bun ```bash bunx --bun prisma init --output ../src/generated/prisma ``` #### pnpm ```bash pnpm prisma init --output ../src/generated/prisma ``` #### yarn ```bash yarn prisma init --output ../src/generated/prisma ``` #### npm ```bash npx prisma init --output ../src/generated/prisma ``` > [!NOTE] > `prisma init` creates the Prisma scaffolding and a local `DATABASE_URL`. In the next step, you will create a Prisma Postgres database and replace that value with a direct `postgres://...` connection string. This will create: * A `prisma/` directory with a `schema.prisma` file * A `prisma.config.ts` file for configuring Prisma * A `.env` file with a local `DATABASE_URL` already set Create a Prisma Postgres database and replace the generated `DATABASE_URL` in your `.env` file with the `postgres://...` connection string from the CLI output: #### bun ```bash bunx create-db ``` #### pnpm ```bash pnpm dlx create-db ``` #### yarn ```bash yarn dlx create-db ``` #### npm ```bash npx create-db ``` ### 2.2. Define your Prisma Schema [#22-define-your-prisma-schema] In the `prisma/schema.prisma` file, mirror the example app structure with Prismabox TypeBox generators and a `Todo` model: ```prisma title="prisma/schema.prisma" generator client { provider = "prisma-client" output = "../src/generated/prisma" } generator prismabox { provider = "prismabox" typeboxImportDependencyName = "elysia" typeboxImportVariableName = "t" inputModel = true output = "../src/generated/prismabox" } datasource db { provider = "postgresql" } model Todo { // [!code ++] id Int @id @default(autoincrement()) // [!code ++] title String // [!code ++] completed Boolean @default(false) // [!code ++] createdAt DateTime @default(now()) // [!code ++] updatedAt DateTime @updatedAt // [!code ++] } // [!code ++] ``` This matches the Prisma Elysia example: it generates Prisma Client to `src/generated/prisma` and Prismabox TypeBox schemas to `src/generated/prismabox`. #### Prismabox [#prismabox] * A Prisma generator that reads your Prisma schema and emits Elysia-friendly TypeBox models. * Generates files like `src/generated/prismabox/Todo.ts` (and one per model) with `TodoPlain`, `TodoPlainInputCreate`, etc. * Use those generated models in routes to validate requests/responses and keep Elysia types in sync with your Prisma schema (also useful for OpenAPI/Eden). ### 2.3. Run migrations and generate Prisma Client [#23-run-migrations-and-generate-prisma-client] Run the following commands to create the database tables and generate the Prisma Client: #### bun ```bash bunx prisma migrate dev --name init bunx prisma generate ``` #### pnpm ```bash pnpm prisma migrate dev --name init pnpm prisma generate ``` #### yarn ```bash yarn prisma migrate dev --name init yarn prisma generate ``` #### npm ```bash npx prisma migrate dev --name init npx prisma generate ``` ### 2.4. Seed the database [#24-seed-the-database] Add some seed data to populate the database with sample todos (mirrors the example repo). Create a new file called `seed.ts` in the `prisma/` directory: ```typescript title="prisma/seed.ts" import { PrismaClient } from "../src/generated/prisma/client.js"; import { PrismaPg } from "@prisma/adapter-pg"; if (!process.env.DATABASE_URL) { throw new Error("DATABASE_URL is not set"); } const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }); const prisma = new PrismaClient({ adapter }); const todoData = [ { title: "Learn Elysia" }, { title: "Learn Prisma" }, { title: "Build something awesome", completed: true }, ]; async function main() { console.log("Start seeding..."); for (const todo of todoData) { const created = await prisma.todo.create({ data: todo, }); console.log(`Created todo with id: ${created.id}`); } console.log("Seeding finished."); } main() .then(async () => { await prisma.$disconnect(); }) .catch(async (e) => { console.error(e); await prisma.$disconnect(); process.exit(1); }); ``` Run the seed script: #### bun ```bash bunx prisma db seed ``` #### pnpm ```bash pnpm prisma db seed ``` #### yarn ```bash yarn prisma db seed ``` #### npm ```bash npx prisma db seed ``` And open Prisma Studio to inspect your data: #### bun ```bash bunx prisma studio ``` #### pnpm ```bash pnpm prisma studio ``` #### yarn ```bash yarn prisma studio ``` #### npm ```bash npx prisma studio ``` ## 3. Integrate Prisma into Elysia [#3-integrate-prisma-into-elysia] ### 3.1. Create a Prisma Client instance [#31-create-a-prisma-client-instance] Inside the `src/` directory, create a `lib` directory with a `prisma.ts` file. This file will create and export your Prisma Client instance and add the following code: ```typescript title="src/lib/prisma.ts" import { PrismaClient } from "../generated/prisma/client.js"; import { PrismaPg } from "@prisma/adapter-pg"; const databaseUrl = process.env.DATABASE_URL; if (!databaseUrl) { throw new Error("DATABASE_URL is not set"); } const adapter = new PrismaPg({ connectionString: databaseUrl }); export const prisma = new PrismaClient({ adapter }); ``` ### 3.2. Create API routes [#32-create-api-routes] Update your `src/index.ts` file to match the Prisma Elysia example, including Prismabox-generated validation types: ```typescript title="src/index.ts" import { Elysia, t } from "elysia"; import { prisma } from "./lib/prisma"; import { TodoPlain, TodoPlainInputCreate, TodoPlainInputUpdate } from "./generated/prismabox/Todo"; const app = new Elysia() // Health check .get("/", () => { return { message: "Hello Elysia with Prisma!" }; }) // Get all todos .get( "/todos", async () => { const todos = await prisma.todo.findMany({ orderBy: { createdAt: "desc" }, }); return todos; }, { response: t.Array(TodoPlain), }, ) // Get a single todo by ID .get( "/todos/:id", async ({ params, set }) => { const id = Number(params.id); const todo = await prisma.todo.findUnique({ where: { id }, }); if (!todo) { set.status = 404; return { error: "Todo not found" }; } return todo; }, { params: t.Object({ id: t.Numeric(), }), response: { 200: TodoPlain, 404: t.Object({ error: t.String(), }), }, }, ) // Create a new todo .post( "/todos", async ({ body }) => { const todo = await prisma.todo.create({ data: { title: body.title, }, }); return todo; }, { body: TodoPlainInputCreate, response: TodoPlain, }, ) // Update a todo .put( "/todos/:id", async ({ params, body, set }) => { const id = Number(params.id); try { const todo = await prisma.todo.update({ where: { id }, data: { title: body.title, completed: body.completed, }, }); return todo; } catch { set.status = 404; return { error: "Todo not found" }; } }, { params: t.Object({ id: t.Numeric(), }), body: TodoPlainInputUpdate, response: { 200: TodoPlain, 404: t.Object({ error: t.String(), }), }, }, ) // Toggle todo completion .patch( "/todos/:id/toggle", async ({ params, set }) => { const id = Number(params.id); try { const todo = await prisma.todo.findUnique({ where: { id }, }); if (!todo) { set.status = 404; return { error: "Todo not found" }; } const updated = await prisma.todo.update({ where: { id }, data: { completed: !todo.completed }, }); return updated; } catch { set.status = 404; return { error: "Todo not found" }; } }, { params: t.Object({ id: t.Numeric(), }), response: { 200: TodoPlain, 404: t.Object({ error: t.String(), }), }, }, ) // Delete a todo .delete( "/todos/:id", async ({ params, set }) => { const id = Number(params.id); try { const todo = await prisma.todo.delete({ where: { id }, }); return todo; } catch { set.status = 404; return { error: "Todo not found" }; } }, { params: t.Object({ id: t.Numeric(), }), response: { 200: TodoPlain, 404: t.Object({ error: t.String(), }), }, }, ) .listen(3000); console.log(`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`); ``` This creates the same endpoints as the official example: * `GET /` - Health check * `GET /todos` - Fetch all todos (newest first) * `GET /todos/:id` - Fetch a single todo * `POST /todos` - Create a todo * `PUT /todos/:id` - Update a todo * `PATCH /todos/:id/toggle` - Toggle completion * `DELETE /todos/:id` - Delete a todo Prismabox generates the `TodoPlain`/`TodoPlainInput*` TypeBox schemas so responses and request bodies are validated and typed. ### 3.3. Run the application [#33-run-the-application] Start your Elysia server: #### bun ```bash bun run dev ``` #### pnpm ```bash pnpm run dev ``` #### yarn ```bash yarn dev ``` #### npm ```bash npm run dev ``` You should see `🦊 Elysia is running at localhost:3000` in the console. ### 3.4. Test the API [#34-test-the-api] Test the endpoints using `curl`: ```bash # Health check curl http://localhost:3000/ | jq # Get all todos curl http://localhost:3000/todos | jq # Get a single todo curl http://localhost:3000/todos/1 | jq # Create a new todo curl -X POST http://localhost:3000/todos \ -H "Content-Type: application/json" \ -d '{"title": "Ship the Prisma + Elysia guide"}' | jq # Toggle completion curl -X PATCH http://localhost:3000/todos/1/toggle | jq # Update a todo curl -X PUT http://localhost:3000/todos/1 \ -H "Content-Type: application/json" \ -d '{"title": "Updated title", "completed": true}' | jq # Delete a todo curl -X DELETE http://localhost:3000/todos/1 | jq ``` Your Elysia app now serves a todo API backed by a Prisma Postgres database. ## Next steps [#next-steps] Now that you have a working Elysia app connected to a Prisma Postgres database, you can: * Extend your Prisma schema with more models and relationships * Add update and delete endpoints * Explore authentication with [Elysia plugins](https://elysiajs.com/plugins/overview.html) * Use [Eden](https://elysiajs.com/eden/overview.html) for end-to-end type-safe API calls ### More info [#more-info] * [Prisma Documentation](https://www.prisma.io/docs/orm/v7) * [Elysia Documentation](https://elysiajs.com/) * [Elysia with Prisma Guide](https://elysiajs.com/integrations/prisma.html) ## Related pages - [`Astro`](https://www.prisma.io/docs/guides/v7/frameworks/astro): Learn how to use Prisma ORM in an Astro app - [`Hono`](https://www.prisma.io/docs/guides/v7/frameworks/hono): Learn how to use Prisma ORM in a Hono app - [`NestJS`](https://www.prisma.io/docs/guides/v7/frameworks/nestjs): Learn how to use Prisma ORM in a NestJS app - [`Next.js`](https://www.prisma.io/docs/guides/v7/frameworks/nextjs): Learn how to use Prisma ORM in a Next.js app and deploy it to Vercel - [`Nuxt`](https://www.prisma.io/docs/guides/v7/frameworks/nuxt): A step-by-step guide to setting up and using Prisma ORM and Prisma Postgres in a Nuxt app