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
💡 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 (0)