DEV Community

Xavier Carrera Gimbert
Xavier Carrera Gimbert

Posted on

Setting Up NestJS with Prisma (Without the Headache )

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
Enter fullscreen mode Exit fullscreen mode

2. Set Up PostgreSQL with Docker

Create a Docker file:

touch docker-compose.yml
Enter fullscreen mode Exit fullscreen mode

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:
Enter fullscreen mode Exit fullscreen mode

Run the container and keep the terminal open:

docker-compose up
Enter fullscreen mode Exit fullscreen mode

3. Install Prisma

pnpm add prisma -D
Enter fullscreen mode Exit fullscreen mode

Initialize Prisma:

pnpm dlx prisma init
Enter fullscreen mode Exit fullscreen mode

4. Configure Environment Variables

Install dotenv:

pnpm add dotenv
Enter fullscreen mode Exit fullscreen mode

Update your config files to load environment variables:

// prisma.config.ts
import 'dotenv/config';
// rest of the file...
Enter fullscreen mode Exit fullscreen mode
// src/main.ts
import 'dotenv/config';
// rest of the file...
Enter fullscreen mode Exit fullscreen mode

Update your .env file (remove any comments):

DATABASE_URL="postgres://myuser:mypassword@localhost:5432"
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

Run the initial migration:

pnpm dlx prisma migrate dev --name "init"
Enter fullscreen mode Exit fullscreen mode

6. Install Prisma Client

pnpm add @prisma/client
Enter fullscreen mode Exit fullscreen mode

💡 You don’t need to run generate now - 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();
  }
}
Enter fullscreen mode Exit fullscreen mode

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 {}
Enter fullscreen mode Exit fullscreen mode

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();
  }
}
Enter fullscreen mode Exit fullscreen mode

💡 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
Enter fullscreen mode Exit fullscreen mode

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)