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
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
}
# Generate client + push to database
npx prisma db push
# Or create a migration
npx prisma migrate dev --name init
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' } }
});
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' } })
]);
Prisma Studio (Visual Database Browser)
npx prisma studio
# Opens visual database browser at http://localhost:5555
# View, edit, create, delete records with a UI
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)