
Si escribiste "supabase vs drizzle" esperando encontrar un ganador, aquí va el giro: no existe ninguno, porque Supabase es un backend de Postgres (un Backend-as-a-Service) y Drizzle es un ORM de TypeScript que corre encima de una conexión de base de datos — incluyendo una de Supabase. Viven en capas diferentes de tu stack, así que en realidad no compiten. No te preocupes, esto es más sencillo de lo que suena.
TL;DR: Usa Supabase para el backend (base de datos, autenticación, almacenamiento, tiempo real). Añade Drizzle si quieres SQL con tipos seguros en tus consultas más complejas. La mayoría de las aplicaciones en producción terminan usando ambos — piensa en "casa y caja de herramientas", no "casa o caja de herramientas".
Supabase vs Drizzle de un vistazo
Aquí está la comparación lado a lado que la mayoría de páginas de "vs" omiten. Fíjate en lo poco que se solapan estos dos — ese es precisamente el punto.
| Dimensión | Supabase | Drizzle |
|---|---|---|
| Qué es | Backend-as-a-Service sobre Postgres | ORM / query builder de TypeScript |
| Capa | Plataforma backend | Librería de acceso a datos |
| Base de datos | Postgres gestionado | Se conecta a cualquier Postgres (incl. Supabase) |
| Auth / Storage / Realtime | Sí (integrado) | No (fuera de su ámbito) |
| Consultas con tipos seguros | Parcial (tipos generados) | Sí (de primera clase, inferidos) |
| Migraciones | Editor SQL / CLI | drizzle-kit (schema-as-code) |
| Edge / serverless | Edge Functions (Deno) | ~7.4 kb, nativo para edge |
| Precio | Gratis / $25 / $599 | Gratis (open-source) |
| Competidores reales | vs Firebase, otros BaaS | vs Prisma, otros ORMs |
¿Ves cómo las filas apenas colisionan? Supabase responde "¿dónde vive mi aplicación?"; Drizzle responde "¿cómo la consulto en TypeScript?". Tanto si buscas supabase vs drizzle como drizzle vs supabase, esa diferencia define cada decisión que tomamos a continuación.
Qué es Supabase en realidad
Supabase es un backend de Postgres gestionado que incluye prácticamente todo lo que una aplicación típica necesita desde el primer día. BaaS — Backend-as-a-Service — significa que obtienes un backend real (base de datos más servicios) sin necesidad de levantar servidores tú mismo. La palabra clave es real: por debajo corre PostgreSQL auténtico, no una abstracción propietaria de la que no puedes escapar más tarde.
Esto es lo que obtienes de forma inmediata:
- Auth — email/contraseña, magic links, logins sociales, SSO, passwordless.
- Storage — almacenamiento de archivos respaldado por S3 con políticas de Row Level Security y transformaciones de imágenes.
- Realtime — escucha cambios en la base de datos, presencia y canales de broadcast.
- Edge Functions — funciones TypeScript sobre Deno, distribuidas globalmente.
- API REST automática vía PostgREST (convierte tus tablas en una API REST al instante) más GraphQL a través de
pg_graphql. - Soporte para vectores de embeddings, así las funciones de IA tienen un hogar.
La forma predeterminada de comunicarte con todo esto desde tu aplicación es supabase-js, la librería cliente oficial. Gestiona lecturas y escrituras en la base de datos (enrutadas a través de PostgREST), sesiones de autenticación, suscripciones en tiempo real y subidas de archivos — un solo cliente para toda la plataforma. Si estás evaluando backends, nuestro análisis completo de Supabase vs Firebase cubre ese lado de la decisión con detalle.
Qué es Drizzle en realidad
Drizzle es un ORM de TypeScript ligero y un query builder. Un ORM (object-relational mapper) es simplemente una librería que te permite escribir consultas de base de datos en tu lenguaje de programación en lugar de cadenas SQL crudas — pero Drizzle se mantiene sorprendentemente cerca del SQL, así que nunca estás peleando contra una abstracción pesada.
Lo que lo hace destacar:
- Huella diminuta — alrededor de 7.4 kb min+gzip sin dependencias externas, lo que lo hace nativo para edge.
drizzle-kit— la CLI que gestionagenerate,migrateypull(introspección de una base de datos existente en TypeScript).- Drizzle Studio — un explorador visual de base de datos gratuito para desarrollo local.
- Inferencia de tipos — define tu schema una vez en TypeScript y los resultados de tus consultas quedan completamente tipados de forma automática.
- Multi-base de datos — funciona con Postgres, MySQL, SQLite y más.
- Completamente open-source — cuesta $0.
Ahora, lo importante: Drizzle no es un backend — no tiene auth, storage, realtime ni servidor API. Hace exactamente una cosa: hablar con una base de datos de forma type-safe. Llamarlo un "ORM" responde la búsqueda común de "supabase orm" — Supabase no incluye un ORM pesado propio, así que los desarrolladores recurren a Drizzle (o Prisma) cuando quieren uno.
supabase-js vs Drizzle: la misma consulta, escrita de dos formas
La diferencia entre supabase-js y Drizzle: supabase-js es el cliente completo de la plataforma (base de datos vía PostgREST, más auth, realtime y storage), mientras que Drizzle es un ORM de Postgres directo y type-safe que solo hace consultas a la base de datos. Para que quede concreto, aquí está exactamente la misma consulta — "obtener posts publicados con su autor" — escrita primero en supabase-js y luego en Drizzle.
Primero, la versión con supabase-js (PostgREST):
import { createClient } from "@supabase/supabase-js";
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
// Get published posts with their author
const { data, error } = await supabase
.from("posts")
.select("id, title, author:authors(name)")
.eq("published", true);
if (error) throw error;
// data: { id, title, author: { name } }[]Ahora la versión Drizzle de la consulta idéntica:
import { drizzle } from "drizzle-orm/postgres-js";
import { eq } from "drizzle-orm";
import postgres from "postgres";
import { posts, authors } from "./schema";
const client = postgres(DATABASE_URL, { prepare: false });
const db = drizzle(client);
// Get published posts with their author
const data = await db
.select({
id: posts.id,
title: posts.title,
authorName: authors.name,
})
.from(posts)
.innerJoin(authors, eq(posts.authorId, authors.id))
.where(eq(posts.published, true));
// data is fully typed from your schema — no codegen step¿Notas la diferencia de estilo? supabase-js usa encadenamiento de PostgREST — .from().select().eq() — y expresa los joins mediante esa sintaxis de cadena anidada author:authors(name), que resulta muy legible para estructuras simples. Drizzle se lee como SQL con superpoderes de TypeScript: joins explícitos, condiciones explícitas, y el tipo del resultado se infiere directamente de tu schema sin ningún paso separado de generación de tipos.
Ninguno es "mejor" en términos absolutos: la consulta de supabase-js es más corta y viene con la plataforma, mientras que la consulta de Drizzle te da seguridad en tiempo de compilación sobre el join y se vuelve más clara a medida que las consultas se complican — tres joins, filtros condicionales, agregaciones. Ese es el trade-off real.

¿Realmente necesitas Drizzle con Supabase? (marco de decisión)
No, generalmente no necesitas Drizzle con Supabase — supabase-js lleva la mayoría de las aplicaciones a producción por sí solo. Añade Drizzle solo cuando quieras seguridad de tipos en tiempo de compilación en consultas complejas o un bundle más pequeño para edge. Antes de añadir una dependencia, repasa esta matriz de decisión honesta.
Quédate con supabase-js cuando:
- Te apoyas en suscripciones de tiempo real, operaciones de archivos/storage o flujos de autenticación.
- Tus consultas son principalmente CRUD sencillo.
- Quieres un único cliente para toda la aplicación.
- Estás prototipando y quieres máxima velocidad.
Añade Drizzle cuando:
- Tienes joins complejos o agregaciones que se vuelven incómodos con la sintaxis de PostgREST.
- Quieres seguridad de tipos en tiempo de compilación sobre SQL más directo.
- El tamaño del bundle importa porque estás desplegando en edge o entornos serverless.
- Prefieres migraciones schema-as-code que puedes revisar en un pull request.
Usa ambos (el resultado más común) cuando:
- Quieres
supabase-jspara auth, storage y realtime, más Drizzle para las consultas de datos más pesadas.
| Tu necesidad | Usa |
|---|---|
| Realtime, storage, CRUD rápido, auth | supabase-js |
| Joins complejos, SQL type-safe, tamaño de bundle en edge | Drizzle |
| Un SaaS típico en producción | Ambos |
Pro tip: Empieza con
supabase-js. Recurre a Drizzle cuando una consulta se vuelva genuinamente dolorosa — no antes. Añadir un ORM de forma prematura es algo real, y solo añade configuración que todavía no necesitas.
Si estás diseñando todo un stack en lugar de una sola consulta, elegir el tech stack adecuado para SaaS explica cómo la decisión de backend y ORM encaja en el panorama general.

Cómo usar Supabase y Drizzle juntos (la configuración correcta)
Sí, puedes usar Supabase y Drizzle juntos — y la mayoría de equipos en producción lo hacen. Mantén supabase-js para auth, storage y realtime, y apunta Drizzle a la misma conexión de Postgres de Supabase para consultas de datos con tipos seguros. Sin embargo, algunos detalles de corrección hacen tropezar a la gente, así que vamos a resolverlos todos en un solo lugar.
Instalación y conexión (el driver postgres-js)
Instala los tres paquetes que necesitas:
npm install drizzle-orm postgres
npm install -D drizzle-kitLuego conéctate usando el driver postgres-js y pásale el cliente a Drizzle:
import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
// prepare: false es OBLIGATORIO con el pooler de transacciones de Supabase
const client = postgres(process.env.DATABASE_URL!, { prepare: false });
export const db = drizzle(client);Ese flag prepare: false no es opcional — sigue leyendo, porque es la razón más común por la que falla una configuración de Supabase + Drizzle.
Pooler vs conexión directa: ¿qué string usas?
Supabase te da dos strings de conexión, y la correcta depende de tu entorno de ejecución:
- Pooler (puerto 6543, modo transacción) — úsalo para funciones serverless y edge. Cada invocación es de corta duración, así que quieres una conexión en pool que se entregue por transacción.
- Conexión directa (puerto 5432) — úsala para servidores de larga duración que mantienen una conexión abierta.
Elige la incorrecta y o bien agotarás conexiones (directa en serverless) o añadirás overhead innecesario. El pooler es también exactamente lo que hace necesario el siguiente gotcha.
El gotcha de prepare: false
Necesitas prepare: false porque el pooler en modo transacción de Supabase no soporta prepared statements, que el driver postgres-js de Drizzle usa por defecto. Junta esos dos hechos y, sin el flag, tus consultas lanzarán errores en el momento en que pasen por el pooler — que en serverless es siempre.
En producción, esta es la línea que muerde a la gente: todo funciona contra una conexión directa localmente, y luego cada consulta falla después de desplegar a Vercel o a una Edge Function de Supabase. La solución es un solo flag:
const client = postgres(DATABASE_URL, { prepare: false });Gotcha: Si tus consultas de Drizzle funcionan en local pero fallan en el despliegue, comprueba este flag primero. Nueve de cada diez veces, eso es todo.
Mantener RLS intacto
Row Level Security (RLS) es una de las mejores características de Supabase, y no tienes que renunciar a ella para usar Drizzle — pero sí debes ser deliberado. Hay dos tipos de cliente:
- Un cliente admin que usa la clave service-role omite RLS completamente. Es poderoso y peligroso — mantenlo estrictamente en el lado servidor, nunca cerca del navegador.
- Un cliente que respeta RLS envuelve cada consulta en una transacción que establece el contexto de auth de Postgres (el rol y las claims del usuario actual) para que tus políticas RLS existentes se apliquen exactamente como lo harían a través de
supabase-js.
Aquí está la forma de una consulta que respeta RLS — establece el contexto de auth y luego ejecuta tu consulta de Drizzle dentro de la misma transacción:
import { sql } from "drizzle-orm";
async function rlsQuery(userJwtClaims: { sub: string; role: string }) {
return db.transaction(async (tx) => {
// Tell Postgres who's asking, so RLS policies kick in
await tx.execute(
sql`select set_config('request.jwt.claims', ${JSON.stringify(
userJwtClaims
)}, true)`
);
await tx.execute(sql`set local role authenticated`);
// This query now runs under the user's RLS policies
return tx.select().from(posts);
});
}Drizzle también incluye una API nativa de RLS y una importación drizzle-orm/supabase con los roles predefinidos de Supabase (authenticated, anon), lo que hace más limpia la definición de políticas como schema-as-code. El resumen clave: mantén RLS activado en Supabase y deja que tu cliente de Drizzle que respeta RLS lo honre.
¿Debes desactivar la Data API / PostgREST?
Solo si consultas exclusivamente a través de Drizzle. Supabase te permite desactivar la Data API (PostgREST) en la configuración de API, lo que reduce tu superficie de ataque. Pero si alguna parte de tu aplicación todavía usa supabase-js para datos — y generalmente lo hace, para realtime o lecturas rápidas — deja PostgREST activo. No hay penalización por mantenerlo.
Si tu aplicación vive en Next.js (un emparejamiento muy común aquí), elegir tu configuración de framework Next.js cubre el lado de enrutamiento y renderizado que envuelve esta capa de datos.
Configurar correctamente Drizzle + Supabase con RLS y pooling hace tropezar a muchos equipos. ¿Necesitas un segundo par de ojos en tu backend? Solicita una consulta gratuita →
Edge y serverless: donde Drizzle toma la delantera
Si estás desplegando en edge, aquí es donde Drizzle se gana su lugar. Con aproximadamente 7.4 kb y sin binarios nativos, se cuela en entornos de ejecución restringidos donde los ORMs más pesados tienen problemas — Cloudflare Workers, Vercel Edge, AWS Lambda e incluso Supabase Edge Functions sobre Deno.
¿Por qué importa tanto el tamaño? Las funciones edge son penalizadas por cold starts y límites de bundle, así que una librería ligera sin dependencias significa arranques en frío más rápidos y bundles que realmente caben. supabase-js también funciona en edge, pero para acceso a datos puro, la huella de Drizzle es difícil de superar.
Un par de cosas a tener en cuenta en edge:
- Usa el string de conexión del pooler en modo transacción (con
prepare: false). - Mantén tu lógica de consulta ligera para que la función permanezca pequeña y rápida.
El entorno de ejecución donde despliegas también influye — comparativa de plataformas de despliegue para funciones edge compara las opciones para que puedas ajustar tu capa de datos al host correcto.
Migrar de supabase-js a Drizzle sin una reescritura completa
¿Ya tienes algo desplegado con supabase-js y ahora quieres Drizzle para algunas consultas complicadas? Buenas noticias: no necesitas una reescritura completa. Puedes ejecutar ambos en el mismo archivo. Aquí está el camino incremental que los equipos realmente usan.
- Mantén
supabase-jsexactamente donde está — auth, storage, realtime y el CRUD simple que ya gestiona bien. No lo toques. - Introspecta tu schema existente en TypeScript para que Drizzle conozca tus tablas (incluida la referencia al schema
authsi la necesitas):
npx drizzle-kit pull- Añade el cliente de Drizzle junto a tu cliente de Supabase existente — misma base de datos, segunda conexión, con
prepare: falseincorporado. - Migra una consulta pesada a la vez. Elige tu join o agregación más dolorosa, reescribe solo esa en Drizzle y despliégala.
- Deja todo lo demás en
supabase-js. No hay ningún premio por convertir consultas que ya funcionaban bien.
No te preocupes: Puedes llamar a
supabase-jsy Drizzle en la misma función. Nada te obliga a elegir globalmente — migra al ritmo que tenga sentido.
Reescribir consultas a mano es la parte lenta, y es exactamente el tipo de trabajo mecánico que los agentes de codificación con IA que aceleran este proceso manejan bien — apunta uno a una consulta de PostgREST y deja que redacte el equivalente en Drizzle para que tú lo revises.
Precios en 2026: cuánto cuesta realmente cada uno
Drizzle es gratuito — es completamente open-source, así que cuesta $0. Supabase tiene un nivel gratuito, luego planes de pago a $25/mes (Pro) y $599/mes (Team) en 2026. Así que la única factura que pagas por este stack es Supabase; añadir Drizzle no cuesta nada.
| Nivel | Supabase | Drizzle |
|---|---|---|
| Gratis | $0 (500 MB BD, 50k MAU; pausa tras 1 semana de inactividad, límite de 2 proyectos) | $0 — completamente open-source |
| Pro | $25/mes + uso (8 GB BD, 100k MAU, $10 crédito de cómputo) | — (gratis) |
| Team | $599/mes (SOC2/ISO, copias de seguridad 14 días, soporte prioritario) | — (gratis) |
| Enterprise | Personalizado (HIPAA, BYO cloud) | — (la versión B2B embebible de Studio es la única pieza de pago) |
Drizzle es $0 y completamente open-source (Drizzle Studio incluido), así que tu única factura de la capa de datos es Supabase — el ORM va de propina, gratis.
Una advertencia: el nivel gratuito de Supabase pausa los proyectos tras una semana de inactividad y te limita a dos — perfecto para prototipos, pero querrás Pro para cualquier cosa seria. Si eres consciente de los costes y construyes de forma lean, nuestro resumen de herramientas que realmente valen la pena para startups mantiene la misma perspectiva pragmática.
¿Qué pasa con Prisma?
La pregunta natural de seguimiento: si quieres un ORM, ¿por qué Drizzle y no Prisma? Ambos funcionan perfectamente bien con Supabase, así que esto sí es una comparación justa — a diferencia de Supabase vs Drizzle.
- Drizzle — ~7.4 kb, nativo para edge, sintaxis parecida a SQL, más joven pero creciendo rápido (aproximadamente 900k descargas semanales en npm). Ideal cuando el tamaño del bundle y los entornos edge importan.
- Prisma — más pesado, pero una experiencia de desarrollo famosamente fluida y mayor adopción (alrededor de 2.5M descargas semanales). Ideal en servidores de larga duración tradicionales donde el bundle no es una restricción.
(Trata esos números como aproximados — cambian constantemente.) El resumen honesto: elige Drizzle para edge y tamaño de bundle, elige Prisma para ergonomía en un servidor convencional. Cualquiera encaja perfectamente en una conexión de Supabase Postgres sin drama.
Cómo enfoca esto Techsy
En Techsy desplegamos aplicaciones probadas en producción con Supabase, Next.js y PostgreSQL cada día, así que esta no es una opinión sacada de leer documentación. Nuestro enfoque por defecto: supabase-js** para las funciones de la plataforma** (auth, storage, realtime) y Drizzle en los caminos de datos pesados donde la seguridad de tipos y los joins complejos pagan dividendos — RLS activado, prepare: false incorporado desde la primera línea.
¿Y honestamente? Muchos proyectos que desplegamos nunca necesitan Drizzle. Si una aplicación es principalmente CRUD con realtime, supabase-js solo es la respuesta más limpia — y te lo diremos en lugar de añadir una dependencia por el simple hecho de añadirla.
¿Quieres una segunda opinión sobre tu backend de Supabase — schema, RLS y configuración de conexión incluidos? Habla con nuestro equipo →
Preguntas frecuentes
¿Es Drizzle un reemplazo de Supabase?
No. Viven en capas distintas — Supabase es tu backend (base de datos, auth, storage, realtime), mientras que Drizzle es simplemente un ORM que consulta una base de datos. No reemplazas uno con el otro; si acaso, Drizzle consulta la base de datos Postgres que Supabase aloja.
¿Necesito Drizzle si ya uso Supabase?
No — es completamente opcional. supabase-js gestiona la mayoría de las aplicaciones perfectamente bien. Añade Drizzle cuando quieras seguridad de tipos en tiempo de compilación en consultas complejas o cuando estés desplegando en entornos edge donde el tamaño del bundle importa.
¿Puedo usar Supabase y Drizzle juntos?
Sí, y es la configuración más común en la práctica. Mantén supabase-js para auth, storage y realtime, y apunta Drizzle a la misma conexión de Postgres de Supabase para tus consultas de datos. Coexisten felizmente en el mismo codebase.
¿Cuál es la diferencia entre supabase-js y Drizzle?
supabase-js es un cliente completo — acceso a la base de datos vía PostgREST más auth, realtime y storage. Drizzle es un ORM de Postgres directo y type-safe sin auth ni realtime; simplemente hace SQL en TypeScript. Uno es el cliente de toda la plataforma, el otro es puramente una capa de consultas.
¿Funciona Drizzle con Row Level Security (RLS) de Supabase?
Sí. Mantén RLS activado y usa un cliente que respete RLS, que envuelve las consultas en una transacción que establece el contexto de auth de Postgres. Un cliente admin con clave service-role omite RLS, así que úsalo solo en el lado servidor y nunca lo expongas al navegador.
¿Por qué necesito prepare: false con Supabase y Drizzle?
El pooler de conexiones en modo transacción de Supabase no soporta prepared statements, que el driver postgres-js de Drizzle usa por defecto. Establecer prepare: false evita los errores resultantes. Omítelo y tus consultas fallarán en configuraciones con pooling o serverless — a menudo solo después de desplegar.
¿Debo usar el pooler o la cadena de conexión directa?
Usa el pooler (modo transacción, puerto 6543) para funciones serverless y edge, y la conexión directa (puerto 5432) para servidores de larga duración. El pooler es también lo que hace necesario prepare: false, así que ambas elecciones van de la mano.
¿Es Drizzle gratuito? ¿Es Supabase gratuito?
Drizzle es completamente open-source — $0, incluyendo Drizzle Studio para desarrollo local. Supabase tiene un nivel gratuito, luego Pro a $25/mes y Team a $599/mes (precios 2026). En resumen: tu única factura es Supabase, y Drizzle no añade nada a ella.
Drizzle vs Prisma para Supabase — ¿qué ORM debo elegir?
Ambos funcionan con Supabase, así que no te irá mal con ninguno de los dos. Drizzle es más ligero (~7.4 kb) y nativo para edge; Prisma tiene una experiencia de desarrollo más madura y mayor adopción. Elige Drizzle para edge y tamaño de bundle, Prisma para ergonomía en servidores tradicionales.
La conclusión final
Entonces, ¿Supabase vs Drizzle? Nunca fue realmente una competición. Esto es lo que debes llevarte:
- No son competidores. Supabase es tu backend; Drizzle es un ORM opcional type-safe que se sitúa encima de él.
- Usar ambos es la respuesta habitual —
supabase-jspara auth/storage/realtime, Drizzle para las consultas de datos más pesadas. - Acierta con los detalles de corrección:
prepare: false, el string de conexión adecuado y un cliente que respete RLS. Estos son los que hacen tropezar a los equipos en producción. - Drizzle es gratuito, así que añadirlo no cuesta nada — tu única factura es Supabase.
- Empieza simple. Recurre a Drizzle cuando una consulta realmente duela, no antes.

¿Dudas entre supabase-js, Drizzle o ambos para tu stack? Solicita una consulta de backend gratuita →