Prisma 6 released on November 11, 2024 alongside a rebrand from “Prisma ORM” to just “Prisma”. The release promotes TypedSQL from Preview to Generally Available, adds multi-schema support for multi-tenant and multi-database platforms, and ships the omit API for fine-grained field exclusion.
>TypedSQL — type-safe raw queries
TypedSQL lets you write raw SQL in .sql files and automatically generates fully typed TypeScript functions from them.
# Enable in schema.prisma
generator client {
provider = "prisma-client-js"
previewFeatures = [] # TypedSQL is GA — no preview flag needed in Prisma 6
}
# Create a SQL file
mkdir -p prisma/sql
touch prisma/sql/getUsersWithRevenue.sql
# Regenerate client after adding SQL files
npx prisma generate --sql-- prisma/sql/getUsersWithRevenue.sql
SELECT
u.id,
u.name,
u.email,
COALESCE(SUM(o.total), 0)::int AS total_revenue
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.created_at > $1
GROUP BY u.id
ORDER BY total_revenue DESC
LIMIT $2;// Generated function — fully typed, no any
import { PrismaClient } from '@prisma/client';
import { getUsersWithRevenue } from '@prisma/client/sql';
const prisma = new PrismaClient();
const result = await prisma.$queryRawTyped(
getUsersWithRevenue(new Date('2024-01-01'), 10),
);
// result: Array<{ id: string; name: string; email: string; total_revenue: number }>>omit — exclude sensitive fields
// Exclude password globally in the client
const prisma = new PrismaClient().$extends({
result: {
user: {
password: { needs: {}, compute: () => undefined },
},
},
});
// Or per-query
const user = await prisma.user.findUnique({
where: { id },
omit: { password: true, internalNotes: true },
});
// user.password is undefined — TypeScript knows this too
// In a findMany
const users = await prisma.user.findMany({
omit: { password: true },
});>Multi-schema support (GA)
// schema.prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["multiSchema"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["public", "auth", "billing"]
}
model User {
id String @id @default(uuid())
email String @unique
@@schema("public")
}
model Subscription {
id String @id @default(uuid())
plan Plan
userId String
@@schema("billing")
}>Query extensions — reusable query logic
const prisma = new PrismaClient().$extends({
model: {
$allModels: {
// Add a findOrCreate method to every model
async findOrCreate<T>(
this: T,
args: { where: object; create: object },
) {
const ctx = Prisma.getExtensionContext(this) as any;
return (
(await ctx.findFirst({ where: args.where })) ??
(await ctx.create({ data: args.create }))
);
},
},
},
});
// Works on any model
const tag = await prisma.tag.findOrCreate({
where: { slug: 'typescript' },
create: { slug: 'typescript', label: 'TypeScript' },
});>Breaking changes in Prisma 6
npm install prisma@6 @prisma/client@6
# After upgrading, run:
npx prisma generateNOTEThe rejectOnNotFound option was removed. Replace with findUniqueOrThrow() / findFirstOrThrow(). The jsonProtocol preview feature is now the default and the flag can be removed.