typescript · nestjs · supabase · drizzleorm
Un repaso sencillo de lo esencial de Supabase
Imaginemos la situación: estamos construyendo nuestro próximo proyecto y sabemos que necesitamos autenticación, una base de datos y tal vez almacenamiento. Podríamos pasar días configurando Postgres, montando la autenticación desde cero y gestionando el deploy… o podríamos tenerlo todo funcionando en menos de 5 minutos.
En la era del vibe coding, herramientas como Supabase y Firebase se imponen porque resuelven exactamente este problema. Permiten lanzar rápido sin pelearse con la infraestructura.
Pero aquí es donde se pone interesante: al combinar Supabase con un backend propio en NestJS, no se sacrifica control a cambio de velocidad — se obtienen ambas cosas. Control total sobre la lógica de la base de datos, reglas de negocio personalizadas, un flujo de auth propio y la capacidad de escalar exactamente como se quiera. Sin vendor lock-in, sin el típico “esta función no está soportada”.
En este artículo veremos cómo configurar Supabase como base de una API en NestJS que ofrece lo mejor de ambos mundos.
Entendiendo Postgres + Auth
Esto es lo que hace especial a Supabase: no se trata solo de tener una base de datos y un sistema de auth como herramientas separadas. Se obtiene una base de datos que sabe quiénes son los usuarios.
Base de datos Postgres
Supabase ofrece una base de datos PostgreSQL de nivel de producción, con tres formas de acceder a ella:
-
Conexión directa: conectarse con cualquier cliente de Postgres usando el connection string (esto es lo que usaremos con Drizzle)
-
REST API: PostgREST genera automáticamente una API RESTful para las tablas, sin necesidad de backend
-
Suscripciones en tiempo real (Realtime): permiten escuchar cambios en la base de datos en tiempo real (por ejemplo, documentos colaborativos o dashboards en vivo)
¿Por qué importa esto? Flexibilidad. Se puede empezar con la conexión directa para la API de NestJS, pero si hace falta prototipar una función rápida, se puede llamar directamente a la REST API desde el frontend. ¿Se necesitan actualizaciones en vivo? Se activan las suscripciones en tiempo real. La misma base de datos, múltiples patrones de acceso.
Sistema de autenticación
Supabase Auth se encarga de todo lo esperable:
-
Email/contraseña y magic links
-
Proveedores OAuth (Google, GitHub, etc.)
-
Generación y validación de tokens JWT
-
Gestión de usuarios y sesiones
Imaginemos que existe una tabla transactions. Normalmente, habría que escribir lógica en el backend para asegurarse de que cada usuario solo vea sus propias transacciones. Con RLS, esa regla se escribe una sola vez a nivel de base de datos:
Pero aquí es donde se pone potente: Row Level Security (RLS).
CREATE POLICY "Users can only see their own transactions"
ON transactions FOR SELECT
USING (auth.uid() = user_id);
Ahora la base de datos aplica esto automáticamente. Ya sea que se acceda a través de la API de NestJS, de la REST API o directamente, cada usuario solo puede ver sus propios datos. Sin queries que dejen escapar datos, sin comprobaciones de permisos olvidadas en el código.
Y como Supabase almacena los datos de auth en el schema auth de la misma base de datos, se pueden hacer joins con las tablas de auth en las queries, extender los perfiles de usuario o añadir custom claims — todo dentro de Postgres.
Creación del proyecto de Supabase
Bien, manos a la obra. Vamos a supabase.com y creamos un nuevo proyecto. El proceso toma unos 5 minutos en total, y esto es lo que hay que hacer:
1. Iniciar sesión y crear un nuevo proyecto
-
Iniciar sesión en la cuenta de Supabase (o crear una si aún no se tiene)
-
Hacer clic en “New Project”
-
Elegir la organización o crear una nueva
2. Configurar el proyecto
- Nombrar el proyecto (por ejemplo, “Finance-API”)

-
Configurar una contraseña de base de datos: hacer clic en el botón “Generate a password”. Esta es la contraseña de la base de datos Postgres, así que hay que guardarla en un lugar seguro (gestor de contraseñas, archivo
.env, o donde se guarden los secretos). Se necesitará más adelante. -
Elegir la región: seleccionar la más cercana a los usuarios. Esto afecta la latencia: un proyecto en
us-east-1será notablemente más lento para usuarios en Europa o Asia. Si no se está seguro, por ahora conviene elegir la región más cercana a uno mismo.

3. Esperar el aprovisionamiento
Hacer clic en “Create new project” y esperar entre 2 y 3 minutos. Supabase está levantando la instancia de Postgres, configurando auth y ajustando todo detrás de escena.
Una vez listo, aparecerá el dashboard del proyecto con todos los detalles de conexión, las API keys y la información de la base de datos. Sin embargo, antes de conectar nada, hace falta entender cómo funcionan las API keys de Supabase, porque usar la incorrecta puede generar problemas de seguridad.
Una breve nota sobre las API keys
Antes de seguir, es posible notar que Supabase ofrece dos API keys en el dashboard: una publishable key y una secret key. La cuestión es esta: no se va a usar ninguna de las dos en este proyecto.
La conexión a Supabase se hará mediante el connection string directo de Postgres, con Drizzle. Esto da control total sobre las queries de la base de datos y permite usar el ORM type-safe de Drizzle en lugar de las client libraries de Supabase.
Entonces, ¿para qué mencionar las API keys? Porque igualmente conviene entender para qué sirven:
Publishable Key (anon key)
-
Segura para exponer en código client-side (React, Vue, apps móviles)
-
Respeta las políticas de Row Level Security
-
Ideal si el frontend necesita hablar directamente con Supabase
Secret Key (service_role key)
-
Se salta TODAS las políticas de seguridad: actúa como admin
-
Solo para backend, nunca debe exponerse
-
Útil para migrations, scripts de administración o background jobs
Bien, con esto aclarado, repasemos lo que realmente se cubrió en este artículo.
Cierre
Llegados a este punto, ya se tiene un proyecto de Supabase listo para producción, con Postgres y Auth configurados. Esto es lo que ya queda claro:
-
Por qué Supabase + NestJS es potente: se obtiene la velocidad de un BaaS con el control de un backend propio
-
Cómo se integran Postgres y Auth: Row Level Security permite que la base de datos aplique los permisos automáticamente, eliminando categorías enteras de bugs de seguridad
-
Las opciones de conexión: conexión directa (la que se usará), REST API o Realtime, cada una pensada para casos de uso distintos
-
La base ya está lista: el proyecto de Supabase está activo y esperando una conexión
¿El siguiente paso? Conectar la app de NestJS a esta instancia de Supabase usando Drizzle. Eso implica configurar un módulo de configuración que maneje las credenciales de la base de datos de forma segura.
¡Nos vemos ahí! 🚀