zanith

CRUD Operations

The everyday operations — create, read, update, delete. Every method is fully typed — TypeScript knows the exact shape of inputs and outputs.

findMany

Retrieve multiple records matching a filter. Returns a typed array. Without a where clause, returns all records in the table.

TSfind users
const users = await db.user.findMany({
where: { role: 'ADMIN' }, // filter
orderBy: { createdAt: 'desc' }, // sort
take: 10, // LIMIT
skip: 20, // OFFSET (pagination)
});
// users: Array<{ id: string, email: string, name: string | null, ... }>

All arguments are optional. db.user.findMany() with no arguments returns every record in the table.

findFirst

Returns the first record matching the filter, or nullif none found. Useful when you expect zero or one result but don't have a unique identifier.

TS
const user = await db.user.findFirst({
where: { email: { contains: 'admin' } },
});
// user: { id: string, email: string, ... } | null
 
if (user) {
console.log(user.email); // TypeScript knows this is safe
}

findUnique

Like findFirst, but semantically intended for unique field lookups — by ID, email, or any other unique column. Returns null if not found.

TS
const user = await db.user.findUnique({
where: { id: 'abc-123-def' },
});

create

Insert a new record and return it with all fields populated (uses PostgreSQL'sRETURNING *). Fields with defaults (like id, createdAt) are optional in the input.

TS
const user = await db.user.create({
data: {
email: '[email protected]',
name: 'Alice',
role: 'ADMIN',
},
});
// user.id → 'generated-uuid' (auto-created)
// user.createdAt → 2026-04-09T... (auto-set)

update

Update an existing record. Only the fields you include in data are changed — everything else stays the same. Fields with autoUpdate() (like updatedAt) are automatically set to the current time.

TS
const user = await db.user.update({
where: { id: 'abc-123' },
data: { name: 'Alice Updated', role: 'MODERATOR' },
});
// user.updatedAt → automatically set to now

delete

Remove a record from the database. Returns the deleted record so you can confirm what was removed or log it.

TS
const deleted = await db.user.delete({
where: { id: 'abc-123' },
});
// deleted: { id: 'abc-123', email: '...', ... }

count

Count records matching a filter. Returns a plain number.

TS
const total = await db.user.count(); // all users
const admins = await db.user.count({ where: { role: 'ADMIN' } }); // filtered

Method summary

MethodReturnsUse case
findMany(args?)PromiseGet multiple records with filters, sorting, pagination
findFirst(args?)PromiseGet first matching record
findUnique(args)PromiseGet by unique field (ID, email)
create(args)PromiseInsert a new record
update(args)PromiseUpdate an existing record
delete(args)PromiseRemove a record
count(args?)PromiseCount matching records