La Mayoría Usa Supabase Como si Fuera un Google Sheets con API
Conectas la base de datos. Haces un select('*') desde el cliente. Y llamas eso producción.
Es el error más común — y el más caro en términos de seguridad y rendimiento.
El verdadero Supabase no es tu base de datos. Es tu backend completo.
Postgres + autenticación + Realtime + Storage + Edge Functions. Todo integrado. Todo tipado. Todo con RLS nativo.
Si solo usas Supabase para hacer queries desde el cliente sin Row Level Security activado, estás exponiendo tu base de datos entera a cualquier usuario autenticado.
Este artículo te muestra la arquitectura correcta.
---
El Error Arquitectónico que Destruye Proyectos en Producción
El patrón malo es sorprendentemente común:
❌ Approach incorrecto:
✅ Approach correcto con RLS:
Row Level Security es la característica más importante de Supabase. Y la más ignorada.
No es opcional. No es una optimización. Es la diferencia entre una app segura y una brecha de datos.
---
La Arquitectura de Autenticación que Realmente Funciona
La mayoría implementa auth de Supabase como si fuera Firebase Auth: login, logout, y poco más.
El auth real de Supabase es un sistema de identidad completo con JWT custom claims.
Paso 1: Configura el cliente con tipado completo
Paso 2: Genera los tipos automáticamente
Esto es crítico. Con los tipos generados, TypeScript te avisa en compile time cuando una query es incorrecta.
Paso 3: Server-side auth en Next.js con SSR
El patrón de createRouteHandlerClient vs createClient no es un detalle menor. Es la diferencia entre auth que funciona en producción y auth que falla silenciosamente con SSR.
---
Realtime: El Caso de Uso Correcto (y los Incorrectos)
Supabase Realtime es potente. También es el origen del 80% de los problemas de rendimiento en apps de producción.
El real problema del Realtime no es técnico. Es que los developers lo usan para todo cuando debería usarse para poco.
❌ Cuándo NO usar Realtime:
→ Dashboards con datos que cambian cada hora
→ Perfiles de usuario que el propio usuario edita
→ Listas de productos en un e-commerce
→ Cualquier cosa que no necesite actualización en tiempo real
✅ Cuándo SÍ usar Realtime:
→ Chat y mensajería
→ Notificaciones push en tiempo real
→ Colaboración simultánea (tipo Figma o Notion)
→ Indicadores de presencia ("3 usuarios leyendo esto")
El filter en Realtime no es opcional. Sin filtro, cada INSERT en la tabla dispara el listener para todos los usuarios conectados. Eso es un problema de rendimiento garantizado.
---
Edge Functions: Tu Backend Sin Servidor
Las Supabase Edge Functions corren en Deno. No en Node.js. Ese detalle importa.
El caso de uso correcto: lógica que no debe ejecutarse en el cliente y no necesita un servidor dedicado.
Nota el uso de SUPABASE_SERVICE_ROLE_KEY en las Edge Functions. Esta key bypassa RLS intencionalmente — úsala solo en server-side, nunca en el cliente.
---
Optimización de Queries: Postgres es tu Ventaja
El real Supabase no es Firebase con SQL. Es Postgres completo.
Eso significa que puedes usar todo lo que Postgres ofrece: índices parciales, funciones, triggers, views materializadas.
La mayoría de developers que usan Supabase nunca toca SQL directo. Dejan rendimiento enorme sobre la mesa.
---
El Stack Completo: Cómo Conectar Todo
Supabase funciona mejor como núcleo de un stack específico:
→ Next.js 15+ para el frontend con App Router
→ Supabase Auth para autenticación con OAuth y magic links
→ Supabase Storage para archivos con políticas RLS nativas
→ Supabase Edge Functions para webhooks y lógica server-side
→ Resend para emails transaccionales desde Edge Functions
→ Supabase Realtime solo donde necesites updates en tiempo real
Este stack elimina la necesidad de un backend separado en el 90% de los proyectos SaaS.
---
Takeaways Clave
RLS no es opcional. Actívalo en cada tabla desde el primer día.
Genera los tipos con `supabase gen types`. TypeScript te salva de errores en producción antes de que lleguen a producción.
Usa `createRouteHandlerClient` en Next.js. El cliente genérico no funciona correctamente con SSR.
Filtra siempre en Realtime. Un listener sin filtro en una tabla grande destruye el rendimiento.
`SUPABASE_SERVICE_ROLE_KEY` solo en server-side. Nunca en el cliente. Nunca en variables NEXT_PUBLIC_.
Aprovecha Postgres completo. Índices, triggers, views materializadas. Eso es lo que te diferencia de Firebase.
Supabase no es una base de datos en la nube. Es el backend completo que no tienes que construir.
La diferencia entre un proyecto que escala y uno que colapsa bajo carga está en estos patrones. No en el framework. No en el hosting. En cómo usas las herramientas que ya tienes.
