DEV Community

Alex Spinov
Alex Spinov

Posted on

Prisma Has a Free ORM — Here's How to Build Type-Safe Database Queries in TypeScript

A developer wrote raw SQL queries in a Node.js project. 3 months later, a column was renamed in a migration. The app didn't crash — it silently returned null for that field. Users saw blank data for 2 days before anyone noticed. Prisma catches this at build time.

What Prisma Offers

Prisma (open source, free):

  • Type-safe queries — TypeScript autocomplete for every field
  • Auto-generated client — from your database schema
  • Migrations — version-controlled database changes
  • Prisma Studio — visual database browser
  • Any database — PostgreSQL, MySQL, SQLite, MongoDB, SQL Server, CockroachDB
  • Relations — joins, nested writes, eager loading
  • Edge-ready — works in Vercel Edge, Cloudflare Workers (with Accelerate)

Quick Start

npm install prisma @prisma/client
npx prisma init
Enter fullscreen mode Exit fullscreen mode

Define Schema

// prisma/schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id        String   @id @default(cuid())
  email     String   @unique
  name      String
  role      Role     @default(USER)
  posts     Post[]
  profile   Profile?
  createdAt DateTime @default(now())
}

model Post {
  id        String   @id @default(cuid())
  title     String
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  String
  tags      Tag[]
  createdAt DateTime @default(now())
}

model Tag {
  id    String @id @default(cuid())
  name  String @unique
  posts Post[]
}

model Profile {
  id     String @id @default(cuid())
  bio    String?
  avatar String?
  user   User   @relation(fields: [userId], references: [id])
  userId String @unique
}

enum Role {
  USER
  ADMIN
  EDITOR
}
Enter fullscreen mode Exit fullscreen mode
# Generate client + push to database
npx prisma db push
# Or create a migration
npx prisma migrate dev --name init
Enter fullscreen mode Exit fullscreen mode

CRUD Operations (Fully Typed)

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

// Create
const user = await prisma.user.create({
  data: {
    email: 'alice@example.com',
    name: 'Alice',
    profile: {
      create: { bio: 'Full-stack developer' }
    }
  },
  include: { profile: true }
});

// Read with relations
const posts = await prisma.post.findMany({
  where: { published: true },
  include: {
    author: { select: { name: true, email: true } },
    tags: true
  },
  orderBy: { createdAt: 'desc' },
  take: 10
});

// Update
const updated = await prisma.post.update({
  where: { id: 'post_123' },
  data: {
    published: true,
    tags: {
      connect: [{ id: 'tag_1' }, { id: 'tag_2' }]
    }
  }
});

// Delete
await prisma.post.delete({ where: { id: 'post_123' } });

// Aggregate
const stats = await prisma.post.aggregate({
  where: { published: true },
  _count: true,
  _avg: { views: true }
});

// Group by
const postsByAuthor = await prisma.post.groupBy({
  by: ['authorId'],
  _count: true,
  orderBy: { _count: { id: 'desc' } }
});
Enter fullscreen mode Exit fullscreen mode

Transaction

const [post, notification] = await prisma.$transaction([
  prisma.post.create({ data: { title: 'New Post', authorId: userId } }),
  prisma.notification.create({ data: { userId, message: 'Your post was created' } })
]);
Enter fullscreen mode Exit fullscreen mode

Prisma Studio (Visual Database Browser)

npx prisma studio
# Opens visual database browser at http://localhost:5555
# View, edit, create, delete records with a UI
Enter fullscreen mode Exit fullscreen mode

Why Prisma

Prisma Raw SQL / Knex
Type-safe queries Runtime errors
Auto-complete String SQL
Schema migrations Manual DDL
Visual browser CLI only
Relation handling Manual JOINs

Need to scrape data into your database? Check out my web scraping actors on Apify — structured data from any website.

Need database consulting? Email me at spinov001@gmail.com.

Top comments (0)