Starting a project with NestJS and Prisma should be easy, right? They’re both popular technologies and a great match. There are even official articles (1)(2) explaining how to integrate them.
Wrong.
For some reason, those articles are outdated. So here I am, writing this guide to save you a serious headache when setting up your project.
Let's Get to It
💡 Here is the final code of this set up project. Use it if you get stuck.
💡 I’ll be using pnpm for this project, but feel free to use any package manager you prefer.
1. Create the Project
You’ll be prompted to choose a package manager. Select pnpm if you want to follow this guide without changes. Otherwise, adapt as needed.
💡 At the time of writing, the latest version of @nestjs/cli appears to have a bug, so I'm using an older version. This may have been resolved by the time you're reading.
pnpm dlx @nestjs/cli@11.0.0 new nestjs-prisma-test 2. Set Up PostgreSQL with Docker
Create a Docker file:
touch docker-compose.yml Add the following content:
# docker-compose.yml version: '3.8' services: postgres: image: postgres:13.5 restart: always environment: - POSTGRES_USER=myuser - POSTGRES_PASSWORD=mypassword volumes: - postgres:/var/lib/postgresql/data ports: - '5432:5432' volumes: postgres: Run the container and keep the terminal open:
docker-compose up 3. Install Prisma
pnpm add prisma -D Initialize Prisma:
pnpm dlx prisma init 4. Configure Environment Variables
Install dotenv:
pnpm add dotenv Update your config files to load environment variables:
// prisma.config.ts import 'dotenv/config'; // rest of the file... // src/main.ts import 'dotenv/config'; // rest of the file... Update your .env file (remove any comments):
DATABASE_URL="postgres://myuser:mypassword@localhost:5432" 5. Define Your Models
Edit prisma/schema.prisma:
model User { id Int @id @default(autoincrement()) email String @unique name String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } Run the initial migration:
pnpm dlx prisma migrate dev --name "init" 6. Install Prisma Client
pnpm add @prisma/client 💡 You don’t need to run
generatenow - Prisma does it automatically when installing the client. But for future schema changes, run:pnpm dlx prisma generate
7. Create the Prisma Service
Note: We import from /client, not as shown in the official docs.
// src/services/prisma.service.ts import { Injectable, OnModuleInit } from '@nestjs/common'; import { PrismaClient } from 'generated/prisma/client'; @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { async onModuleInit() { await this.$connect(); } } 8. Register the Prisma Service
// src/app.module.ts import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { PrismaService } from './services/prisma.service'; @Module({ imports: [], controllers: [AppController], providers: [PrismaService], }) export class AppModule {} 9. Use the Prisma Service
// src/app.controller.ts import { Controller, Get } from '@nestjs/common'; import { PrismaService } from './services/prisma.service'; @Controller() export class AppController { constructor(private readonly prismaService: PrismaService) {} @Get() async getUsers() { return this.prismaService.user.findMany(); } } 💡 This is a minimal setup and not production-ready. In a real app, you shouldn’t call a service directly from the controller. But this is a Prisma + NestJS set up tutorial - so I don’t care.
10. Run the Server
pnpm run start:dev And that’s it! Populate your database and test the endpoint.
If you run into any issues, let me know in the comments. Hope you enjoyed the ride!
Top comments (6)
Very useful post! 👏🏻
Hi, this tutorial helped me a lot. Thank you!
Can you provide an update for Prisma 7 which was released a few days ago?
https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-7?utm_source=blog&utm_campaign=prisma7
I’m really glad it helped, Dennis! It should work fine without any major changes. Did you run into any issues while using Prisma 7?
I tried to fix it, but it was too complicated for me. I decided to wait for the official sample to be updated: github.com/nestjs/nest/issues/15965
Maybe you can join there.
Great post!
but why is dotenv necessary in "main.ts"? I'm a beginner and I'm a little confused. is it required for specifically using prisma or does it completely replace nest/config?
Dotenv is necessary because it allows NestJS to access the database URL stored in the .env file.
It doesn’t replace the NestJS config. It’s simply an add-on.
Hopefully, this explanation helps!
Feel free to ask if you have any other question.