Prisma in NestJS

A Different Take — Type-Safe and Schema-First

Prisma in NestJS

Prisma is a competing ORM with a schema file and a generated, fully-typed client. Many Nest teams prefer it for the type safety alone.

4 min read Level 2/5 #nestjs#prisma#database
What you'll learn
  • Install Prisma and define schema.prisma
  • Generate the client
  • Wrap PrismaClient in a Nest service

Prisma takes a different approach from TypeORM. Instead of decorating classes, you write a schema.prisma file and Prisma generates a typed client from it. The result is a smaller surface area and noticeably better autocomplete.

The Schema File

// prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id    Int    @id @default(autoincrement())
  email String @unique
  name  String
  posts Post[]
}

model Post {
  id      Int    @id @default(autoincrement())
  title   String
  userId  Int
  user    User   @relation(fields: [userId], references: [id])
}

Run npx prisma generate and Prisma emits a typed client at node_modules/@prisma/client. Run npx prisma migrate dev and it diffs the schema against the database and writes a migration.

Wrap the Client as a Nest Service

There’s no official @nestjs/prisma package — you write a tiny service. That’s deliberate: PrismaClient is already a great abstraction.

import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  async onModuleInit() {
    await this.$connect();
  }
}

Export it from a PrismaModule and you can inject it anywhere:

@Injectable()
export class UsersService {
  constructor(private readonly prisma: PrismaService) {}

  findAll() {
    return this.prisma.user.findMany({ include: { posts: true } });
  }

  create(email: string, name: string) {
    return this.prisma.user.create({ data: { email, name } });
  }
}

Notice the autocomplete: this.prisma.user is typed from your schema, not a generic Repository<User>.

TypeORM vs Prisma

A rough rule of thumb:

  • Pick Prisma if you want first-class types, a schema you can read at a glance, and a tight, opinionated API.
  • Pick TypeORM if you need to model existing complex schemas, drop into hand-tuned SQL often, or use database features Prisma hasn’t surfaced yet (some Postgres extensions, exotic joins).

Both are excellent. Most teams pick one and never look back.

MongoDB With Mongoose →