Drizzle vs Prisma: Elegir un ORM de TypeScript sin el alboroto mediático
Compare Drizzle y Prisma en cuanto al diseño de esquemas, el estilo de consultas, las escrituras anidadas, las migraciones, las transacciones y el rendimiento, con recomendaciones sobre cuál es más adecuado para cada equipo.
Fuentes: Drizzle vs Prisma: Choosing the Right TypeScript ORM in 2026 (Deep Dive)
Drizzle ORM y Prisma son los dos nombres que más surgen al elegir un ORM para un proyecto en TypeScript. Resuelven el mismo problema, que consiste en convertir el acceso a la base de datos en código tipado, pero parten de ideas opuestas respecto a cuán cercano debería ser al SQL. Ninguno es una elección incorrecta. Si su equipo ya conoce bien uno de ellos, continúe usando ese y dedique su tiempo al producto. La comparación es más importante cuando inicia algo nuevo o debe explicar una configuración existente a sus colegas.
Las dos herramientas
Drizzle apareció en 2022 y creció rápidamente entre los desarrolladores que buscan control sin añadir carga adicional. Es de TypeScript por excelencia: las tablas, las relaciones y las consultas se declaran todas en TypeScript. Una descripción adecuada sería una capa ligera y tipada sobre SQL. Los tipos se infieren de forma nativa, el SQL en bruto mantiene la seguridad tipológica, y su diseño es adecuado para código sensible al rendimiento. Se admiten PostgreSQL, MySQL, SQLite y SQL Server.
Prisma llegó antes, en 2018, y construyó su reputación sobre la experiencia del desarrollador, la productividad y las herramientas. El modelo de datos se encuentra en un archivo .prisma escrito en Prisma Schema Language (PSL), y prisma generate lo convierte en un cliente completamente tipado con una API de alto nivel. Las relaciones se gestionan automáticamente, y el ecosistema es más amplio y maduro, incluyendo Prisma Studio, un navegador y editor visual para tus datos. Las bases de datos soportadas incluyen PostgreSQL, MySQL, SQLite y MongoDB, entre otras.
Definir el esquema
Aquí las filosofías difieren de manera más evidente, y la elección influye en el trabajo diario y en la seguridad tipológica.
Drizzle: código primero
Un esquema de Drizzle es simplemente TypeScript. Las tablas, columnas y relaciones se encuentran en el mismo lenguaje que la aplicación, por lo que no hay paso de generación y los cambios se reflejan inmediatamente en tu editor.
import { pgTable, serial, varchar, text, integer, timestamp } from "drizzle-orm/pg-core";
// Authors table
export const authors = pgTable("authors", {
id: serial("id").primaryKey(),
name: varchar("name", { length: 100 }).notNull(),
bio: text("bio"),
});
// Books table referencing Authors
export const books = pgTable("books", {
id: serial("id").primaryKey(),
title: varchar("title", { length: 150 }).notNull(),
summary: text("summary"),
authorId: integer("author_id")
.notNull()
.references(() => authors.id),
publishedAt: timestamp("published_at").defaultNow(),
});
Dado que los tipos se infieren, el resultado de una consulta tiene una estructura definida sin necesidad de ningún archivo de esquema adicional. Esto reduce las sorpresas durante la ejecución.
Prisma: el esquema primero
Prisma almacena el modelo en un archivo separado .prisma:
model Author {
id Int @id @default(autoincrement())
name String
bio String?
books Book[]
}
model Book {
id Int @id @default(autoincrement())
title String
summary String?
publishedAt DateTime @default(now())
authorId Int
author Author @relation(fields: [authorId], references: [id])
}
El esquema está claramente separado del código de la aplicación. Después de cada cambio, prisma generate reconstruye el cliente para que los tipos coincidan. Para quienes tienen poca experiencia con SQL, esta abstracción resulta más amigable, ya que se trabaja con un cliente de alto nivel generado en lugar de con lógica de estilo SQL. El precio a pagar es una capa adicional entre el código y la base de datos.
Redacción de consultas
Ambos ofrecen consultas con verificación de tipos, pero se escriben de manera diferente.
Drizzle
El generador de consultas es deliberadamente sencillo y predecible, y se lee como SQL. Si te sientes cómodo con las uniones y las cláusulas WHERE, resulta natural, y lo que escribes se corresponde estrechamente con lo que se ejecuta en la base de datos. Este ejemplo une libros con autores y filtra y ordena el resultado:
const results = await db
.select({
bookId: books.id,
title: books.title,
publishedAt: books.publishedAt,
authorName: authors.name,
})
.from(books)
.leftJoin(authors, eq(books.authorId, authors.id))
.where(eq(authors.id, authorId))
.orderBy(books.publishedAt);
Se obtiene un control detallado y un SQL altamente predecible. La diferencia notable en comparación con Prisma se manifiesta al crear filas relacionadas. Drizzle no permite escrituras anidadas, por lo que cada inserción relacional se gestiona manualmente, generalmente dentro de una transacción para que todos los elementos mantengan su consistencia:
const result = await db.transaction(async (tx) => {
const [newAuthor] = await tx.insert(authors).values({
name: "Alice",
bio: "Fantasy author",
}).returning({ id: authors.id });
const [newBook] = await tx.insert(books).values({
title: "The Dream Forest",
authorId: newAuthor.id,
}).returning();
return { newAuthor, newBook };
});
La transparencia total es la ventaja. Más código genérico es la desventaja.
Prisma
Prisma sigue un enfoque opuesto. Se llaman métodos a un cliente generado automáticamente, mientras que la base de datos permanece mediante métodos de estilo objeto. La misma búsqueda se convierte en:
const results = await prisma.book.findMany({
where: { authorId },
select: {
id: true,
title: true,
publishedAt: true,
author: {
select: { name: true },
},
},
orderBy: { publishedAt: "asc" },
});
Aquí nadie tiene que pensar en SQL, lo que explica en gran medida la popularidad de Prisma. También destaca al crear datos relacionados, ya que se admiten escrituras anidadas. Se puede crear un libro y su autor con una sola llamada:
const newBook = await prisma.book.create({
data: {
title: "The Dream Forest",
summary: "A surreal adventure.",
author: {
create: {
name: "Alice",
bio: "Fantasy author",
},
},
},
});
No es necesario conectar manualmente las claves foráneas. Lo que se pierde es la visibilidad, ya que el SQL que realmente se ejecuta está oculto, por lo que se tiene menos control que con Drizzle.
Migraciones
Cambiar el esquema con el tiempo es importante en cualquier proyecto real, y ambas herramientas lo manejan bien.
Drizzle
Dado que el esquema está en TypeScript, este es la fuente de verdad, y la CLI (drizzle-kit) deriva las migraciones a partir de las diferencias en sus definiciones. En un flujo de trabajo basado en migraciones, se comienza generando:
npx drizzle-kit generate
Eso compara el estado actual con tu esquema de TypeScript y genera un archivo de migración con los cambios en SQL, que puedes editar a mano antes de utilizarlo. Aplicarlo es un comando separado:
npx drizzle-kit migrate
Para el prototipado rápido también existe un atajo:
npx drizzle-kit push
Envía el esquema de TypeScript directamente a la base de datos sin crear un archivo de migración. Eso es rápido y práctico al principio, pero al no haber historial de migraciones, no es adecuado para entornos de producción.
Prisma
Con Prisma, el archivo .prisma es la fuente de verdad, y la herramienta genera el SQL para cada cambio. La aplicación de migraciones confirmadas a una base de datos utiliza:
npx prisma migrate deploy
Durante el desarrollo, prisma migrate dev es la orden que crea una nueva carpeta de migraciones con scripts SQL, la aplica y actualiza la tabla de historial. Esto genera un flujo de trabajo ordenado y en su mayor parte automático.
También existe un atajo para la creación de prototipos:
npx prisma db push
Actualiza la base de datos directamente, al igual que el método push de Drizzle, sin archivos de migración, por lo que está destinado únicamente para uso no de producción.
Transacciones
Ambos soportan transacciones, con algunas pequeñas diferencias en el estilo.
Drizzle utiliza db.transaction con una función de callback. Cada consulta dentro de este mecanismo tiene éxito o falla conjuntamente, y como se mantiene cerca del SQL, se puede controlar con precisión lo que ocurre dentro del bloque:
await db.transaction(async (tx) => {
const newAuthor = await tx.insert(authors).values({
name: "Alice Walker",
bio: "Pulitzer Prize-winning author",
}).returning();
await tx.insert(books).values({
title: "Journey to the Mountains",
summary: "A story about adventure and discovery.",
authorId: newAuthor[0].id,
});
});
Prisma ofrece prisma.$transaction, que acepta ya sea un array de consultas o una función de callback asíncrona. El confirmado y el deshacer son automáticos:
await prisma.$transaction(async (tx) => {
const newAuthor = await tx.author.create({
data: {
name: "Alice Walker",
bio: "Pulitzer Prize-winning author",
},
});
await tx.book.create({
data: {
title: "Journey to the Mountains",
summary: "A story about adventure and discovery.",
authorId: newAuthor.id,
},
});
});
Rendimiento
El rendimiento es donde las filosofías subyacentes son más importantes.
Drizzle es ligero y sus consultas se corresponden casi directamente con las operaciones de la base de datos, por lo que hay muy poco costo de abstracción. Esto es útil para consultas complejas, operaciones en masa y código de alto rendimiento. Al tener control total sobre las uniones, transacciones y la estructura de las consultas, es más fácil ajustarlas para lograr mayor velocidad, pero se supone que se comprende SQL y el diseño de bases de datos.
El cliente generado por Prisma oculta SQL detrás de una API de alto nivel. Esto supone una ligera pérdida de rendimiento, aunque en la mayoría de las aplicaciones comunes la diferencia es insignificante. Las relaciones, consultas anidadas y resultados tipados vienen incluidos de forma gratuita, lo que acelera el desarrollo. Esta comodidad puede ocasionalmente generar SQL menos optimizado que una consulta escrita a mano con cuidado.
Elegir entre ellos
Ambos son ORMs modernos compatibles con TypeScript que ofrecen seguridad de tipos, migraciones, relaciones y transacciones, por lo que la decisión depende de las prioridades.
Elige Drizzle si deseas mantenerte cerca de SQL, tener control total sobre las consultas y las migraciones, y necesitas un rendimiento predecible bajo cargas de trabajo intensas o complejas. TypeScript funciona como la única fuente de verdad, y nada queda oculto.
Elige Prisma si el equipo quiere actuar rápidamente, concentrarse en las funcionalidades y contar con automatización para las migraciones, consultas y relaciones. El modelo basado en esquemas y el cliente generado proporcionan una API limpia y de alto nivel, adecuada para principiantes.
En resumen:
- Esquemas: código en TypeScript (Drizzle) frente a un archivo
.prismamás generación (Prisma). - Consultas: de estilo SQL y explícitas frente a estilo de objeto y abstractas.
- Escrituras anidadas: manuales en Drizzle, integradas en Prisma.
Leer más
- Claude Code o Codex en septiembre de 2026: precios, modelos y adecuación — Local y síncrono frente a nube y asíncrono: cómo difieren Claude Code y Codex en costos, pruebas de rendimiento, flujos de trabajo y residencia de datos en la UE.
- Agentes DevOps en 2026: MCP, frameworks y qué realmente funciona — Cómo funcionan los agentes DevOps, por qué es importante MCP, qué frameworks son adecuados, dónde ayudan en CI/CD, infraestructura, monitoreo y seguridad, y qué sigue siendo solo promesa.
- Notas prácticas: Por qué las empresas de Singapur eligen React para webs escalables — Guía detallada de las Notas prácticas: Por qué las empresas de Singapur eligen React para webs escalables: contratos, verificaciones y espacios para código listo para uso para los equipos que implementan este patrón.
- Prisma 6 y 7: El compilador de consultas, paquetes más pequeños y pasos para actualizar — Cómo Prisma 7 reemplaza el motor en Rust por un compilador de consultas en TypeScript y WASM, qué se rompe al pasar de la versión v5, nuevas funciones y las mejoras de velocidad reportadas.