Getting Started with Prisma - AI Style
Prisma offers a modern, type-safe ORM experience tailored for TypeScript developers working with relational databases. In this guide, you'll integrate Prisma into an existing Node.js TypeScript project, focusing on setup, schema modelling, and generating database clients. If you're comfortable with databases and want a clean, intuitive API for querying data, Prisma will fit right into your workflow.
The Database
First, we need a database. Let's start with docker compose
.
services:
db:
image: postgres:16
restart: always
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: secret
POSTGRES_DB: db
ports:
- 5432:5432
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Now start it with:
docker compose up -d
Add Prisma to an Existing Project
Since you already have a typescript application up and running, let's add Prisma. I use yarn
so I'll use that, but you can use npm, pnpm or any other package manager you like.
yarn add -D prisma
Now, make sure it works.
npx prisma
Set up to use Postgres
Let's initialize Prisma to use PostgreSQL
npx prisma init --datasource-provider postgresql
This will add the necessary packages and create a .env
file that has the DATABASE_URL. We'll have to update that to match our docker compose postgres database.
DATABASE_URL="postgres://user:password@localhost:5432/userservice?schema=public"
.env
Create some helper methods for package.json
npm pkg set "scripts.prisma:generate"="prisma generate"
npm pkg set "scripts.prisma:migrate:dev"="prisma migrate dev"
npm pkg set "scripts.prisma:migrate:deploy"="prisma migrate deploy"
Add a post-install handler to generate Prisma files, so that after you run yarn, it will also create the files needed to compile and run the app
npm pkg set "scripts.postinstall"="prisma generate"
Run yarn
to make sure the generate command runs
yarn install v1.22.22
[1/4] 🔍 Resolving packages...
success Already up-to-date.
$ prisma generate
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
âś” Generated Prisma Client (v6.9.0) to ./src/generated/prisma in 58ms
Start by importing your Prisma Client (See: https://pris.ly/d/importing-client)
Tip: Want to turn off tips and other hints? https://pris.ly/tip-4-nohints
âś” Installed the @prisma/client and prisma packages in your project
âś” Generated Prisma Client (v6.9.0) to ./src/generated/prisma in 99ms
Start by importing your Prisma Client (See: https://pris.ly/d/importing-client)
Tip: Want to turn off tips and other hints? https://pris.ly/tip-4-nohints
✨ Done in 5.28s.
Create a schema from ChatGPT
Now we are ready to go. Let's create a schema using ChatGPT
I'm using prisma with a node application.
Create for me a prisma schema for a postgres database use uuid's that
are generated by default that has the following entities.
User - name, email
Organization - name
Create a many to many relationship between user and organization and
include a role for this link. Roles can be owner (default), admin or user.
prompt
This will create the following schema.prisma
that you can add to your project.
// schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(uuid()) @db.Uuid
name String
email String @unique
userOrganizations UserOrganization[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Organization {
id String @id @default(uuid()) @db.Uuid
name String
userOrganizations UserOrganization[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model UserOrganization {
userId String @db.Uuid
organizationId String @db.Uuid
role Role @default(OWNER)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
@@id([userId, organizationId])
}
enum Role {
OWNER
ADMIN
USER
}
Run yarn prisma:migrate:dev
to set this up in the database
yarn run v1.22.22
$ prisma migrate dev
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "userservice", schema "public" at "localhost:5432"
✔ Enter a name for the new migration: … init
Applying migration `20250610023909_init`
The following migration(s) have been created and applied from new schema changes:
migrations/
└─ 20250610023909_init/
└─ migration.sql
Your database is now in sync with your schema.
âś” Generated Prisma Client (v6.9.0) to ./src/generated/prisma in 141ms
✨ Done in 9.06s.
Since this is the first migration, I've called it 'init'.
I can now connect to it using docker compose exec db psql -U user userservice
and see the tables
psql (16.9 (Debian 16.9-1.pgdg120+1))
Type "help" for help.
userservice=# \dt
List of relations
Schema | Name | Type | Owner
--------+--------------------+-------+-------
public | Organization | table | user
public | User | table | user
public | UserOrganization | table | user
public | _prisma_migrations | table | user
(4 rows)
userservice=# \d "User"
Table "public.User"
Column | Type | Collation | Nullable | Default
-----------+--------------------------------+-----------+----------+-------------------
id | uuid | | not null |
name | text | | not null |
email | text | | not null |
createdAt | timestamp(3) without time zone | | not null | CURRENT_TIMESTAMP
updatedAt | timestamp(3) without time zone | | not null |
Indexes:
"User_pkey" PRIMARY KEY, btree (id)
"User_email_key" UNIQUE, btree (email)
Referenced by:
TABLE ""UserOrganization"" CONSTRAINT "UserOrganization_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"(id) ON UPDATE CASCADE ON DELETE CASCADE
userservice=#
With Prisma set up in your TypeScript project, you now have a powerful, type-safe way to work with your database, without sacrificing clarity or developer experience. From schema modelling to querying, Prisma streamlines everyday tasks and helps you catch issues early through tight TypeScript integration. As your application grows, Prisma’s tooling and ecosystem will support you every step of the way.