Cuando Has Superado Strapi CMS: Construyendo con Payload + Supabase
Cuando Has Superado Strapi CMS: Construyendo con Payload + Supabase
He configurado Strapi para al menos una docena de proyectos de clientes en los últimos años. Es un gran CMS para comenzar -- panel de administrador amigable, ecosistema de plugins decente, documentación sólida. Pero en algún punto alrededor de los 18 meses, casi todos los equipos con los que he trabajado se chocan con un muro. Las migraciones se vuelven dolorosas, las personalizaciones se sienten hacky, y tus desarrolladores frontend amantes de TypeScript comienzan a quejarse sobre la experiencia del desarrollador. Si eso te suena familiar, no estás solo. Déjame guiarte a través de los signos de que has superado Strapi, y más importante, qué construir en su lugar.

Tabla de Contenidos
- La Fase de Luna de Miel: Por Qué Strapi Funciona al Principio
- Seis Signos de Que Has Superado Strapi
- Entendiendo Tus Opciones: Payload vs Supabase vs Quedarte
- Por Qué Payload CMS Es el Siguiente Paso Natural
- Dónde Encaja Supabase (Y Dónde No)
- El Stack Payload + Supabase: Análisis Profundo de Arquitectura
- Estrategia de Migración: Saliendo de Strapi Sin Perder la Cabeza
- Benchmarks de Rendimiento y Números del Mundo Real
- Cuándo Este Stack No Es la Opción Correcta
- FAQ
La Fase de Luna de Miel: Por Qué Strapi Funciona al Principio
Demos crédito donde se lo merece. Strapi tiene 65K+ estrellas en GitHub por una razón. Cuando estás iniciando un nuevo proyecto impulsado por contenido, el Content-Type Builder es genuinamente útil. Haces clic en una GUI, defines algunos campos, y boom -- tienes APIs REST y GraphQL. Los editores de contenido no técnicos pueden ingresar al panel de administración y comenzar a publicar en una hora.
Para startups en etapa temprana, sitios de marketing y blogs, Strapi es una opción perfectamente razonable. Soporta PostgreSQL, MySQL, MariaDB y SQLite. El mercado de plugins tiene más de 100 extensiones de la comunidad. Y la edición comunitaria es gratuita bajo licencia MIT.
He recomendado Strapi muchas veces. No estoy aquí para criticarlo. Estoy aquí para hablar sobre qué sucede después.
Seis Signos de Que Has Superado Strapi
Estos son los patrones que veo repetidamente. Si tres o más de estos resuenan contigo, es hora de comenzar a planificar tu migración.
1. Las Migraciones Te Ponen Nervioso
La actualización de v4 a v5 es la que rompió muchos equipos. Strapi documentó 50+ cambios incompatibles. En la práctica, he visto migraciones que toman 40+ horas de tiempo de desarrollador para proyectos de complejidad media. Eso no es un lanzamiento de versión menor -- eso es una reescritura de tu capa de contenido.
Si te aterroriza la próxima versión mayor porque sabes que romperá la mitad de tus controladores personalizados, has superado la herramienta.
2. Tus Desarrolladores Están Luchando Contra el Framework
El Content-Type Builder de Strapi es excelente para usuarios no técnicos. Para desarrolladores que viven en TypeScript y desean esquemas code-first, es un cuello de botella. La GUI genera archivos que no se supone que edites. Los lifecycle hooks se sienten pegados. El soporte de TypeScript se agregó tarde en v4 y aún no es nativo -- es más bien una ocurrencia tardía.
Cuando tu equipo comienza a construir soluciones alternativas para el framework en lugar de construir características con él, esa es una señal clara.
3. El Rendimiento Se Está Convirtiendo en un Problema
Los cold starts de Strapi generalmente oscilan entre 500ms y 2000ms. La latencia global se sitúa entre 200-500ms sin caching agresivo. Para un blog, eso está bien. Para una plataforma de comercio electrónico que sirve a usuarios en múltiples regiones, no lo es.
Tuve un cliente ejecutando un catálogo de productos multilingüe en Strapi. Una vez que cruzaron ~50,000 entradas de contenido con relaciones profundas, los tiempos de respuesta de la API se acercaron a la marca de 2 segundos. Ninguna cantidad de indexación lo solucionó.
4. Necesitas Características Que Están Bloqueadas Detrás de Niveles Pagos
El plan Growth de Strapi cuesta $45/mes e incluye 3 puestos (asientos adicionales a $15/puesto cada uno). Eso desbloquea características de IA, vista previa en vivo e historial de contenido. Los precios empresariales son personalizados.
El problema no es el precio -- es el principio. Características como vista previa en vivo y versionado de contenido se sienten como lo básico para un CMS en 2025. Tenerlas bloqueadas detrás de una suscripción en una herramienta de código abierto molesta a los equipos de desarrolladores.
5. Tu Stack Ha Evolucionado Más Allá de la Arquitectura de Strapi
Si te has comprometido completamente con Next.js, Vercel y TypeScript, Strapi comienza a sentirse como un apéndice incómodo. Se ejecuta como un servicio Node.js separado. Eso significa deployments separados, monitoreo separado, preocupaciones de escalado separadas. Tu equipo frontend despliega a Vercel en segundos mientras que tu CMS necesita su propia infraestructura.
6. Las Extensiones Personalizadas Se Sienten Como una Cirugía
¿Quieres agregar lógica de campo condicional? ¿Bloques repetibles anidados con validación? ¿Componentes personalizados del panel de administración? En Strapi, cada uno de estos es posible pero doloroso. El panel de administración es una aplicación React, pero extenderlo significa navegar un sistema de extensión propietario que no se siente como desarrollo React normal.

Entendiendo Tus Opciones: Payload vs Supabase vs Quedarte
Antes de continuar, seamos claros sobre qué son realmente estas herramientas, porque veo que se confunden constantemente.
| Herramienta | Qué Realmente Es | Mejor Para | No Es Excelente Para |
|---|---|---|---|
| Strapi | CMS headless de código abierto con GUI de administración | Editores de contenido, generación rápida de API | Equipos code-first, aplicaciones de alto rendimiento |
| Payload CMS | Framework CMS code-first que se ejecuta dentro de Next.js | Desarrolladores de TypeScript, aplicaciones de contenido personalizadas | Operadores solo no técnicos |
| Supabase | Plataforma de backend de código abierto (BD, auth, almacenamiento, realtime) | Datos de aplicación, auth, almacenamiento de archivos | Flujos de trabajo de edición de contenido |
| Directus | CMS headless SQL-first con APIs auto-generadas | Equipos con bases de datos existentes | Integración profunda con Next.js |
| Sanity | CMS headless gestionado con colaboración en tiempo real | Equipos editoriales, contenido estructurado | Autohospedaje consciente del presupuesto |
Payload y Supabase no son competidores -- son complementarios. Payload maneja tu modelado de contenido, UI de administración y APIs de contenido. Supabase maneja el alojamiento de tu base de datos, autenticación, almacenamiento de archivos y suscripciones en tiempo real. Juntos, reemplazan Strapi y luego algunos.
Por Qué Payload CMS Es el Siguiente Paso Natural
Payload ha estado haciendo olas serias durante 2025 y en 2026. MG Software la llamó un "disruptor de mercado" para la integración TypeScript/Next.js, y creo que eso es preciso.
Aquí está la diferencia arquitectónica fundamental: Payload se ejecuta dentro de tu aplicación Next.js. No al lado de ella. No como un servicio separado. Dentro de ella. Tu CMS y tu frontend comparten el mismo deployment, los mismos tipos de TypeScript, el mismo proceso de compilación.
Definición de Esquema Code-First
En lugar de hacer clic a través de una GUI para crear tipos de contenido, escribes TypeScript:
import { CollectionConfig } from 'payload';
export const Products: CollectionConfig = {
slug: 'products',
admin: {
useAsTitle: 'name',
defaultColumns: ['name', 'price', 'status'],
},
access: {
read: () => true,
create: ({ req: { user } }) => user?.role === 'admin',
},
fields: [
{
name: 'name',
type: 'text',
required: true,
},
{
name: 'price',
type: 'number',
min: 0,
},
{
name: 'description',
type: 'richText',
},
{
name: 'category',
type: 'relationship',
relationTo: 'categories',
hasMany: false,
},
{
name: 'variants',
type: 'array',
fields: [
{ name: 'sku', type: 'text', required: true },
{ name: 'color', type: 'select', options: ['red', 'blue', 'green'] },
{
name: 'stock',
type: 'number',
admin: {
condition: (data, siblingData) => siblingData?.sku !== undefined,
},
},
],
},
],
hooks: {
afterChange: [
async ({ doc, operation }) => {
if (operation === 'update' && doc.stock === 0) {
// Trigger restock notification
}
},
],
},
};
Ese es un tipo de contenido real con lógica de campo condicional, arrays anidados, campos de relación, control de acceso basado en roles y lifecycle hooks. Todo en un archivo. Todo type-safe. Todo versionado en Git.
Intenta hacer eso en Strapi sin tocar tres archivos diferentes y el sistema de extensión de administración.
Tres Capas de API
Payload genera automáticamente APIs REST y GraphQL a partir de tu esquema. Pero la característica asesina es la Local API -- consultas de base de datos directas desde tu código del lado del servidor sin sobrecarga HTTP:
// Dentro de un Componente de Servidor de Next.js
import { getPayload } from 'payload';
import config from '@payload-config';
export default async function ProductPage({ params }) {
const payload = await getPayload({ config });
const product = await payload.findByID({
collection: 'products',
id: params.id,
depth: 2, // Populate relationships 2 levels deep
});
return <ProductDetail product={product} />;
}
Sin llamadas fetch. Sin rutas API. Sin sobrecarga de serialización. Esta es la razón por la que Payload tiene un benchmark de aproximadamente 7x más rápido que Strapi para recuperación de contenido en configuraciones comparables.
Dónde Encaja Supabase (Y Dónde No)
Supabase no es un CMS. Quiero ser realmente claro al respecto. Es una plataforma de backend construida sobre PostgreSQL. Pero resuelve varios problemas que Strapi maneja mal y que Payload no maneja en absoluto.
Qué Supabase Aporta al Stack
- PostgreSQL Gestionado: El adaptador PostgreSQL de Payload se conecta directamente a una base de datos de Supabase. Obtienes connection pooling, copias de seguridad automáticas y un dashboard para consultas SQL directas. El plan Pro comienza en $25/mes y se escala con el uso.
- Autenticación: Supabase Auth soporta email/contraseña, magic links, proveedores OAuth y seguridad a nivel de fila. Si tu aplicación tiene características de cara al usuario más allá del administrador del CMS, esto es enorme.
- Almacenamiento de Archivos: Almacenamiento de objetos compatible con S3 con CDN. Payload puede manejar cargas de medios, pero Supabase Storage maneja archivos de aplicación, cargas de usuarios y cualquier cosa fuera del contexto del CMS.
- Suscripciones en Tiempo Real: LISTEN/NOTIFY de PostgreSQL envuelto en una API WebSocket limpia. Combina esto con la vista previa en vivo de Payload para experiencias de edición de contenido en tiempo real.
- Edge Functions: Funciones serverless basadas en Deno para manejadores de webhooks, trabajos en segundo plano e integraciones.
Qué Supabase No Hace
No te da un panel de administración para editores de contenido. No genera APIs de contenido con campos de texto enriquecido y gestión de medios. No maneja localización de contenido o historial de versiones. Ese es el trabajo de Payload.
El Stack Payload + Supabase: Análisis Profundo de Arquitectura
Así es como configuro esto para equipos que migran de Strapi. Esta es la arquitectura que típicamente recomendamos en Social Animal para proyectos de desarrollo Next.js donde la gestión de contenido es un requisito central.
Estructura del Proyecto
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── (frontend)/ # Páginas públicas
│ │ └── (payload)/ # Rutas de administración de CMS (auto-generadas)
│ ├── collections/ # Configs de colección de Payload
│ │ ├── Posts.ts
│ │ ├── Products.ts
│ │ └── Users.ts
│ ├── globals/ # Configs globales de Payload
│ │ └── SiteSettings.ts
│ ├── lib/
│ │ └── supabase.ts # Inicialización del cliente Supabase
│ └── payload.config.ts # Config principal de Payload
├── supabase/
│ └── migrations/ # Migraciones de BD de Supabase
├── .env.local
└── package.json
Conectando Payload a PostgreSQL de Supabase
// payload.config.ts
import { buildConfig } from 'payload';
import { postgresAdapter } from '@payloadcms/db-postgres';
import { lexicalEditor } from '@payloadcms/richtext-lexical';
import { Posts } from './collections/Posts';
import { Products } from './collections/Products';
export default buildConfig({
db: postgresAdapter({
pool: {
connectionString: process.env.SUPABASE_DB_URL,
// Usa el connection pooler de Supabase para serverless
max: 10,
},
}),
editor: lexicalEditor(),
collections: [Posts, Products],
secret: process.env.PAYLOAD_SECRET,
typescript: {
outputFile: path.resolve(__dirname, 'payload-types.ts'),
},
});
Una nota importante: usa la URL del connection pooler de Supabase (puerto 6543), no la URL de conexión directa, cuando despliegues a entornos serverless como Vercel. Las conexiones directas funcionan bien para desarrollo local.
Agregando Autenticación de Supabase para Usuarios de Aplicación
Payload maneja autenticación de administrador de CMS. Supabase maneja todo lo demás:
// lib/supabase.ts
import { createClient } from '@supabase/supabase-js';
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
// En un Componente de Servidor o ruta API
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';
export async function getServerSupabase() {
const cookieStore = await cookies();
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
);
},
},
}
);
}
Esta separación es limpia: Payload es propietario del contenido. Supabase es propietario de los datos de aplicación e identidad del usuario. Comparten la misma instancia de PostgreSQL pero se mantienen en sus respectivos carriles.
Estrategia de Migración: Saliendo de Strapi Sin Perder la Cabeza
No voy a endulzar esto -- la migración requiere trabajo. Pero es dramáticamente menos dolorosa que una actualización de Strapi v4 a v5, porque te estás moviendo a un sistema que respeta tus modelos mentales existentes.
Enfoque Paso a Paso
- Audita tus tipos de contenido de Strapi. Expórtalos como JSON desde el Content-Type Builder. Mapea cada uno a una config de colección de Payload.
- Configura Payload en un nuevo proyecto Next.js. Ejecuta
npx create-payload-app@latesty selecciona el adaptador PostgreSQL. - Apunta Payload a tu base de datos de Supabase. Crea un nuevo proyecto de Supabase, obtén la cadena de conexión, configura el adaptador.
- Recrea esquemas en TypeScript. Este es el grueso del trabajo. Cada tipo de contenido de Strapi se convierte en una colección de Payload. Los campos mapean casi 1:1 -- texto, número, richtext, relación, media.
- Exporta datos de Strapi. Usa
pg_dumpsi estabas en PostgreSQL, o escribe un script contra la API REST de Strapi para extraer todo el contenido. - Importa a Payload. Usa la Local API de Payload en un script seed para crear contenido en bloque.
- Actualiza tu frontend. Cambia las llamadas a la API de Strapi por llamadas a la Local API de Payload (en Componentes de Servidor) o llamadas REST/GraphQL (en componentes cliente).
- Despliega. Como Payload se ejecuta dentro de Next.js, despliegas una aplicación en lugar de dos.
Para migraciones complejas, nuestro equipo de desarrollo de CMS headless puede ayudar a planificar la transición. Hemos hecho esto suficientes veces para saber dónde están las minas terrestres.
Benchmarks de Rendimiento y Números del Mundo Real
Aquí están los números que importan, recopilados de benchmarks publicados y nuestras propias pruebas en 2025:
| Métrica | Strapi v5 | Payload 3.x | Payload + Supabase |
|---|---|---|---|
| Tiempo de cold start | 500-2000ms | 100-300ms | 150-350ms |
| Consulta simple (elemento único) | 45-80ms | 8-15ms | 10-20ms |
| Consulta compleja (poblada, 3 niveles) | 200-500ms | 30-80ms | 40-100ms |
| Carga del panel de administración | 2-4s | 1-2s | 1-2s |
| Tiempo de compilación (500 páginas, ISR) | N/A (separado) | 45-90s | 50-100s |
| Latencia global (sin CDN) | 200-500ms | 50-150ms | 60-160ms |
El connection pooler de Supabase agrega una pequeña sobrecarga en comparación con una conexión PostgreSQL directa, típicamente 5-15ms. Eso es negligible en la práctica.
Una salvedad: Las consultas de campos poblados de Payload (resolución de relaciones profundas) han sido señaladas como más lentas que consultas de base de datos sin procesar -- aproximadamente 15x más lentas que llamadas directas de Mongoose/Drizzle según el problema de GitHub #11325. Para páginas de lectura intensiva, recomiendo usar ISR de Next.js o cachear resultados poblados en lugar de golpear la base de datos en cada solicitud.
Cuándo Este Stack No Es la Opción Correcta
Te haría un flaco favor si no mencionara los escenarios donde Payload + Supabase es excesivo o simplemente incorrecto.
- Tu equipo no escribe TypeScript. Payload es code-first. Si tu equipo de contenido gestiona todo y no tienes desarrolladores manteniendo el CMS, la GUI de Strapi es genuinamente mejor. O mira Sanity o Contentful.
- Necesitas un ecosistema de plugins masivo hoy. El ecosistema de Payload está creciendo pero es más pequeño que los 100+ extensiones de Strapi. Si necesitas una integración específica que existe como un plugin de Strapi pero no para Payload, factoriza el tiempo de compilación.
- Estás construyendo un blog simple o un sitio de marketing. Strapi funciona bien para esto. También lo hace Astro con un CMS headless. No lo sobre-ingenierices.
- Necesitas rendimiento edge-first. Si la latencia global sub-50ms es un requisito difícil, mira SonicJS en Cloudflare Workers. Payload se ejecuta en Node.js -- es rápido, pero no es edge-nativo.
¿Quieres hablar si esta migración tiene sentido para tu proyecto específico? Comunícate con nosotros -- te daremos una evaluación honesta, no un discurso de ventas.
FAQ
¿Es Payload CMS realmente gratuito?
Sí. Payload tiene licencia MIT y es gratuito para auto-hospedarse sin restricciones de características. Hay un servicio de alojamiento opcional de Payload Cloud para equipos que no quieren gestionar infraestructura, pero todas las características del CMS -- vista previa en vivo, control de acceso, localización, versionado -- están disponibles en la versión de código abierto. Compara eso con Strapi, que bloquea la vista previa en vivo y el historial de contenido detrás del plan Growth de $45/mes.
¿Puedo usar Supabase como un CMS por sí solo?
Técnicamente, podrías construir una interfaz de gestión de contenido sobre Supabase utilizando sus APIs auto-generadas y Row Level Security. Pero estarías reconstruyendo lo que Payload te da listo para usar: un panel de administración, edición de texto enriquecido, gestión de medios, versionado de contenido y control de acceso. Supabase es una plataforma de backend, no un CMS. Úsalo para lo que es bueno -- alojamiento de base de datos, auth, almacenamiento -- y deja que Payload maneje la capa de contenido.
¿Cuánto tiempo tarda migrar de Strapi a Payload?
Para un proyecto típico con 10-20 tipos de contenido y algunos miles de entradas, espera 2-4 semanas de tiempo de desarrollador. La recreación de esquemas es el elemento más grande -- traducir tipos de contenido de Strapi a configs de TypeScript de Payload. La migración de datos generalmente es un día o dos con un buen script. Las actualizaciones de frontend dependen de qué tan acoplado esté tu código al formato de respuesta de la API de Strapi. Los equipos que utilizaron una capa de acceso a datos o abstracción tendrán un tiempo más fácil.
¿Funciona Payload con bases de datos distintas a PostgreSQL?
Payload soporta tanto MongoDB como PostgreSQL a través de adaptadores de base de datos oficiales. Para el stack de Supabase descrito en este artículo, usarías el adaptador PostgreSQL. Si vienes de un trasfondo de MongoDB, el adaptador MongoDB de Payload es realmente más maduro ya que MongoDB fue la base de datos original de Payload. Ambos están listos para producción en 2025.
¿Qué pasa con Directus como alternativa a Strapi?
Directus es una opción sólida, especialmente si tienes una base de datos SQL existente que quieres exponer a través de una interfaz de CMS. Auto-genera un panel de administración y APIs a partir de tu esquema de base de datos, lo cual es inteligente. La principal desventaja en comparación con Payload es la falta de integración profunda con Next.js -- Directus se ejecuta como un servicio separado, similar a Strapi. Si tu equipo no está en el stack de Next.js/Vercel, Directus merece seria consideración.
¿Puedo desplegar Payload + Supabase en Vercel?
Absolutamente -- esto es realmente el objetivo de deployment ideal. Como Payload se ejecuta dentro de tu aplicación Next.js, desplegar a Vercel es tan simple como hacer push a tu repositorio Git. Supabase se ejecuta como un servicio gestionado, así que no hay nada que desplegar de ese lado. Tu infraestructura total se convierte en: Vercel para compute y CDN, Supabase para base de datos y auth. Dos servicios, un pipeline de deployment. Frecuentemente configuramos esto para clientes a través de nuestra práctica de desarrollo Next.js.
¿Es el panel de administración de Payload personalizable?
Muy. La UI de administración está construida con React y soporta componentes personalizados, vistas personalizadas y campos personalizados. Puedes agregar widgets de dashboard, crear elementos de navegación personalizados y anular cualquier elemento de UI por defecto. Desde Payload 3.x, la personalización de administración usa React Server Components, lo que significa que tu código de administración personalizado puede obtener datos del lado del servidor sin llamadas API. Es un mundo diferente del sistema de extensión de administración de Strapi, que requiere eyecciones y parches.
¿Cuánto cuesta ejecutar este stack en producción?
Para un proyecto pequeño a mediano: Vercel Pro a $20/mes + Supabase Pro a $25/mes = $45/mes total. Eso te da compute serverless, una base de datos PostgreSQL gestionada con almacenamiento de 8GB, almacenamiento de archivos de 250MB, 50,000 usuarios activos mensuales de auth y copias de seguridad automáticas. Escala desde allí según sea necesario. Compara eso con auto-hospedaje de Strapi en un VPS ($20-50/mes) más la gestión de tu propia base de datos, o el plan Growth de Strapi Cloud a $45/mes con puestos limitados. La combinación Payload + Supabase es competitiva en costos y dramáticamente más fácil de operar. Para estimaciones de proyectos detalladas, consulta nuestra página de precios.