DEV Community

Alex Spinov
Alex Spinov

Posted on

Prisma Has a Free ORM: Type-Safe Database Access With Auto-Generated Queries, Migrations, and Studio

Raw SQL gives you control but no type safety. TypeORM uses decorators and class inheritance. Knex.js is a query builder without schema management. You want to define your schema once and get types, queries, and migrations automatically.

That's Prisma — the TypeScript ORM that generates a fully typed client from your schema.

Quick Start

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

Schema Definition

// 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?
  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 Profile {
  id     String @id @default(cuid())
  bio    String?
  user   User   @relation(fields: [userId], references: [id])
  userId String @unique
}

model Tag {
  id    String @id @default(cuid())
  name  String @unique
  posts Post[]
}
Enter fullscreen mode Exit fullscreen mode
npx prisma migrate dev --name init  # Creates tables + generates client
Enter fullscreen mode Exit fullscreen mode

Type-Safe Queries

import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();

// Find with relations
const user = await prisma.user.findUnique({
  where: { email: "dev@example.com" },
  include: { posts: true, profile: true },
});
// user.posts is typed as Post[] — autocomplete works!

// Create with nested relations
const newUser = await prisma.user.create({
  data: {
    email: "new@example.com",
    name: "Aleksej",
    profile: { create: { bio: "Developer" } },
    posts: {
      create: [
        { title: "First Post", content: "Hello!" },
        { title: "Second Post", published: true },
      ],
    },
  },
  include: { posts: true, profile: true },
});

// Complex filtering
const publishedPosts = await prisma.post.findMany({
  where: {
    published: true,
    author: { email: { endsWith: "@gmail.com" } },
    tags: { some: { name: "typescript" } },
  },
  orderBy: { createdAt: "desc" },
  take: 20,
  select: { id: true, title: true, author: { select: { name: true } } },
});

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

// Transaction
const [deletedPosts, deletedUser] = await prisma.$transaction([
  prisma.post.deleteMany({ where: { authorId: userId } }),
  prisma.user.delete({ where: { id: userId } }),
]);
Enter fullscreen mode Exit fullscreen mode

Prisma Studio — Visual Database Browser

npx prisma studio
# Opens browser at localhost:5555 — browse/edit data visually
Enter fullscreen mode Exit fullscreen mode

Prisma vs Drizzle vs TypeORM vs Kysely

Feature Prisma Drizzle TypeORM Kysely
Approach Schema-first ORM Code-first ORM Decorator ORM Query builder
Type safety Generated client Inferred Decorators Manual schema
Migrations Built-in (auto) Built-in Built-in Via plugin
Raw SQL control Limited High Medium Full
Bundle size Heavy (~7MB) Light (~50KB) Medium (~2MB) Light (~30KB)
Studio/GUI Prisma Studio Drizzle Studio None None

Choose Prisma for rapid development, auto-generated types, and Prisma Studio.
Choose Drizzle/Kysely for smaller bundles and more SQL control.

Start here: prisma.io


Need custom data extraction, scraping, or automation? I build tools that collect and process data at scale — 78 actors on Apify Store and 265+ open-source repos. Email me: Spinov001@gmail.com | My Apify Actors

Top comments (0)