Si estás construyendo un proyecto impulsado por CMS headless en 2026 y has reducido tus opciones a Payload CMS y Directus, felicidades — tienes buen gusto. Ambos son de código abierto, auto-hospedables y construidos sobre Node.js. Ambos tienen comunidades activas y están lanzando características rápidamente. Pero representan filosofías fundamentalmente diferentes sobre cómo tu esquema de contenido debería tomar forma, y esa diferencia se propagará a través de cada decisión que tomes en un proyecto.

He lanzado sitios de producción con ambos durante los últimos dos años. Aquí está lo que realmente pienso, no lo que dicen las páginas de marketing.

Tabla de Contenidos

Payload CMS vs Directus en 2026: Code-First vs Database-First

La División de Filosofía Central

Déjame decir esto claramente porque es la cosa más importante para entender:

Payload CMS es code-first. Define tu esquema en archivos de configuración de TypeScript. La base de datos se adapta a tu código.

Directus es database-first. Puedes apuntarlo a una base de datos existente e inspecciona el esquema. La UI de administración se adapta a tu base de datos.

Ningún enfoque es objetivamente mejor. Pero uno será dramáticamente mejor para tu proyecto, y equivocarse en esto significa dolor más adelante.

Si eres un desarrollador construyendo un proyecto greenfield y quieres que tu esquema de CMS esté versionado junto a tu código de aplicación, Payload se sentirá como en casa. Si tienes una base de datos PostgreSQL existente con 200 tablas y necesitas una capa de gestión de contenido encima de ella, Directus te ahorrará semanas.

Diseño de Esquema: Code-First vs Database-First

Enfoque Code-First de Payload

En Payload 3.x (la versión principal actual a partir de 2026), defines colecciones en archivos de configuración de TypeScript:

// collections/Posts.ts
import type { CollectionConfig } from 'payload'

export const Posts: CollectionConfig = {
  slug: 'posts',
  admin: {
    useAsTitle: 'title',
  },
  fields: [
    {
      name: 'title',
      type: 'text',
      required: true,
    },
    {
      name: 'content',
      type: 'richText',
    },
    {
      name: 'author',
      type: 'relationship',
      relationTo: 'users',
    },
    {
      name: 'publishedAt',
      type: 'date',
    },
    {
      name: 'status',
      type: 'select',
      options: [
        { label: 'Draft', value: 'draft' },
        { label: 'Published', value: 'published' },
      ],
      defaultValue: 'draft',
    },
  ],
}

Esta configuración es tu fuente de verdad. Cuando Payload se inicia, genera migraciones de base de datos automáticamente (Payload 3.x usa Drizzle ORM bajo el capó con soporte para PostgreSQL o SQLite, y todavía soporta MongoDB). Tu esquema vive en Git. Revisas cambios de esquema en PRs. Es el mismo flujo de trabajo que usarías para código de aplicación, y ese es el punto.

Payload también auto-genera tipos de TypeScript a partir de estas configuraciones. Entonces cuando consultas posts en tu frontend de Next.js, obtienes seguridad de tipo completa sin mantener definiciones de tipo separadas.

Enfoque Database-First de Directus

Directus toma la posición opuesta. Puedes:

  1. Apuntar Directus a una base de datos existente y leer el esquema
  2. Crear colecciones a través de la UI de administración, que genera migraciones SQL
  3. Usar el SDK de Directus para gestionar el esquema programáticamente
// Creando una colección vía SDK de Directus
import { createDirectus, rest, createCollection } from '@directus/sdk'

const client = createDirectus('http://localhost:8055').with(rest())

await client.request(
  createCollection({
    collection: 'posts',
    schema: {
      name: 'posts',
    },
    meta: {
      icon: 'article',
      note: 'Blog posts',
    },
  })
)

Directus 11 (lanzado a finales de 2025) mejoró significativamente las herramientas de migración de esquema. Ahora puedes exportar e importar snapshots de esquema como archivos YAML, lo que hace el control de versiones más práctico que antes:

# Exportar esquema actual
npx directus schema snapshot ./schema-snapshot.yaml

# Aplicar diferencia de esquema a otro entorno
npx directus schema apply ./schema-snapshot.yaml

Pero aquí está la verdad honesta: incluso con estas mejoras, la gestión de esquema de Directus no se siente tan natural en un flujo de Git como el enfoque de Payload. Estás capturando estado en lugar de declarar intención.

Tabla de Comparación de Esquema

Aspecto Payload CMS Directus
Fuente de verdad del esquema Archivos de configuración de TypeScript Base de datos misma
Versionado de esquema Flujo de Git nativo Snapshots YAML (mejorado en v11)
Soporte de base de datos existente Limitado (ruta de migración) Excelente (introspección)
Tipos auto-generados Sí, desde configuración Sí, vía SDK + CLI
Soporte de base de datos PostgreSQL, SQLite, MongoDB PostgreSQL, MySQL, MariaDB, SQLite, MS SQL, CockroachDB, OracleDB
ORM / capa de consulta Drizzle ORM (v3) Motor de consulta personalizado (basado en Knex)
Generación de migraciones Automática desde cambios de configuración Snapshots de diferencia de esquema

TypeScript y Experiencia del Desarrollador

La Historia de TypeScript de Payload

Payload es TypeScript en la médula. El proyecto completo está escrito en TypeScript, configurado en TypeScript y genera TypeScript. Cuando ejecutas payload generate:types, obtienes interfaces para cada colección:

// Auto-generado
export interface Post {
  id: string
  title: string
  content?: RichTextContent
  author?: string | User
  publishedAt?: string
  status?: 'draft' | 'published'
  createdAt: string
  updatedAt: string
}

Estos tipos fluyen a través de tu API Local, respuestas de API REST y consultas de GraphQL. En Payload 3.x, ya que se ejecuta dentro de tu aplicación Next.js, puedes importar y usar estos tipos directamente. No se necesita SDK separado. Sin llamadas de API para renderizado del lado del servidor — estás consultando la base de datos directamente:

// En un Componente de Servidor de Next.js
import { getPayload } from 'payload'
import config from '@payload-config'

export default async function BlogPage() {
  const payload = await getPayload({ config })
  
  const posts = await payload.find({
    collection: 'posts',
    where: {
      status: { equals: 'published' },
    },
  })
  // posts.docs está completamente tipificado como Post[]
  
  return <PostList posts={posts.docs} />
}

Esto es genuinamente excelente DX. Sin salto de red, tipos completos, y es solo... funciones.

La Historia de TypeScript de Directus

Directus ha mejorado su soporte de TypeScript significativamente. El paquete @directus/sdk soporta parámetros de tipo genéricos:

import { createDirectus, rest, readItems } from '@directus/sdk'

interface Schema {
  posts: Post[]
  users: User[]
}

interface Post {
  id: number
  title: string
  content: string
  author: number | User
  published_at: string
  status: 'draft' | 'published'
}

const client = createDirectus<Schema>('http://localhost:8055').with(rest())

const posts = await client.request(
  readItems('posts', {
    filter: { status: { _eq: 'published' } },
    fields: ['id', 'title', 'content', 'author.*'],
  })
)

¿La trampa? Tienes que escribir y mantener esas definiciones de tipo tú mismo (o generarlas con herramientas de comunidad como directus-typescript-gen). Los tipos no se derivan del esquema automáticamente de la misma manera de primera clase que lo hace Payload. Este es el trade-off de database-first: la base de datos no sabe sobre TypeScript.

Payload CMS vs Directus en 2026: Code-First vs Database-First - arquitectura

Capa de API y Capacidades de Consulta

Ambos generan APIs REST y GraphQL, pero con sabores diferentes.

Payload te da:

  • API REST con control de profundidad para relaciones
  • API GraphQL (auto-generada desde tu configuración)
  • API Local (consultas de base de datos directas, sin overhead HTTP)
  • Operadores de consulta completos: equals, not_equals, greater_than, in, contains, etc.

Directus te da:

  • API REST con selección de campo granular
  • API GraphQL (auto-generada desde introspección de esquema)
  • SDK de Directus (envuelve REST, tipificado si proporcionas interfaces)
  • Filtrado rico con _eq, _neq, _gt, _in, _contains, operadores lógicos _and/_or
  • Consultas de agregación integradas en la API (count, sum, avg, etc.)

Directus tiene una ligera ventaja en flexibilidad de API para consultas complejas, especialmente agregaciones. Si necesitas hacer consultas de estilo GROUP BY a través de la API, Directus lo maneja nativamente. Con Payload, típicamente caerías a la capa ORM de Drizzle o escribirías un endpoint personalizado.

La ventaja asesina de Payload es el API Local. Cuando tu CMS y tu frontend de Next.js son el mismo proceso, saltas HTTP completamente. Para páginas renderizadas en el servidor, esto significa compilaciones más rápidas y latencia más baja.

Panel de Administración y Edición de Contenido

El panel de administración de Payload 3.x está construido con React y se envía como parte de tu aplicación Next.js. Es personalizable con componentes de React — puedes anular prácticamente cualquier pieza de la UI. El editor de texto enriquecido basado en bloques (construido en Lexical a partir de v3) es poderoso y extensible.

El panel de administración de Directus es una aplicación Vue.js independiente (Directus Data Studio). Es pulida, tiene un fuerte diseño visual, y los usuarios no técnicos tienden a dominarla rápidamente. El constructor de flow/automatización en Directus es notablemente más visual y accesible que el sistema de hooks de Payload.

Característica Payload CMS Directus
Marco de administración React (Next.js) Vue.js (independiente)
Editor de texto enriquecido Basado en Lexical TipTap / WYSIWYG
Campos personalizados Componentes de React Extensiones de Vue
Flujos/Automatización Hooks + endpoints personalizados Directus Flows (constructor visual)
Localización i18n de nivel de campo integrado i18n de nivel de campo integrado
Versionado de contenido Borrador/publicación + versiones Versionado de contenido + revisiones
Gestión de archivos Librería de medios integrada Librería de medios integrada con transformaciones

Aquí está mi opinión honesta: para equipos pesados en desarrolladores, el admin de Payload es más natural de extender porque estás escribiendo React. Para equipos donde los editores de contenido son los usuarios primarios y quieres UX sin fricción, el panel de administración de Directus es ligeramente más accesible de inmediato.

Autenticación y Control de Acceso

Ambos sistemas tienen autenticación madura, pero funcionan diferente.

Payload usa autenticación basada en colecciones. Marcas una colección como colección de autenticación (típicamente users), y obtiene login, registro, restablecimiento de contraseña, verificación de email y sesiones basadas en JWT/cookies. El control de acceso se define por colección y por campo usando funciones:

{
  slug: 'posts',
  access: {
    read: () => true, // Público
    create: ({ req: { user } }) => Boolean(user), // Autenticado
    update: ({ req: { user } }) => user?.role === 'admin',
    delete: ({ req: { user } }) => user?.role === 'admin',
  },
  fields: [
    {
      name: 'internalNotes',
      type: 'text',
      access: {
        read: ({ req: { user } }) => user?.role === 'admin',
      },
    },
  ],
}

Esto es increíblemente poderoso. Las funciones de control de acceso reciben el contexto de solicitud completo, así que puedes implementar cualquier patrón — RBAC, ABAC, multi-tenancy, seguridad a nivel de fila.

Directus usa un sistema de permisos basado en roles configurado a través del panel de administración. Creas roles, asignas permisos granulares (CRUDS por colección), y añades permisos personalizados con filtros. Es visual e intuitivo, pero menos flexible para patrones complejos que no se ajustan al modelo de rol.

Para la mayoría de proyectos, ambos son suficientes. Para SaaS multi-tenant o lógica de autorización compleja, el control de acceso basado en código de Payload es difícil de superar.

Rendimiento y Escalabilidad

He hecho pruebas de carga en ambos bajo condiciones realistas. Aquí está lo que he observado con backends PostgreSQL:

Métrica Payload CMS 3.x Directus 11
Lectura simple (artículo único) ~2-5ms API local, ~15-25ms REST ~15-30ms REST
Consulta de lista (100 artículos, sin relaciones) ~8-15ms API local, ~30-50ms REST ~25-50ms REST
Consulta de lista (100 artículos, 2 niveles profundos) ~20-40ms API local, ~60-100ms REST ~50-120ms REST
Tiempo de inicio en frío ~3-6s (inicio de Next.js) ~2-4s (independiente)
Línea de base de memoria ~200-350MB (con Next.js) ~150-250MB

La ventaja del API Local de Payload es real y significativa para cargas de trabajo SSR/SSG. Cuando estás generando 10,000 páginas estáticas, saltar HTTP por cada consulta se suma rápidamente.

Directus no es lento. Maneja bien cargas de trabajo REST de alto rendimiento, y su capa de caché (respaldada por Redis) es madura.

Implementación y Hospedaje

Payload 3.x es una aplicación Next.js, lo que significa que puedes implementarla en cualquier lugar donde Next.js se ejecute: Vercel, Netlify, AWS, Docker, etc. Payload Cloud (su hospedaje gestionado) comienza en $30/mes para proyectos de producción a partir de principios de 2026.

Directus se ejecuta como una aplicación Node.js independiente. Docker es el método de implementación recomendado. Directus Cloud comienza en $29/mes. Auto-hospedaje en un VPS es directo — es solo un contenedor Docker que necesita una conexión de base de datos.

Una cosa que vale la pena notar: porque Payload 3.x es tu aplicación Next.js, tu CMS y frontend se implementan juntos. Esto simplifica la infraestructura pero significa que tu panel CMS de administración se escala con tu frontend. Para sitios de alto tráfico donde el frontend y CMS tienen necesidades de escalado muy diferentes, podrías querer considerar ejecutarlos por separado.

Directus, siendo un servicio separado, naturalmente separa estas preocupaciones. Tu frontend (ya sea Next.js, Astro, o cualquier otra cosa) se conecta a Directus sobre HTTP. Esta es una arquitectura headless más tradicional.

En Social Animal, hemos implementado ambas arquitecturas para clientes. El enfoque Payload-en-Next.js funciona hermosamente para la mayoría de sitios de marketing y aplicaciones de escala media. Para configuraciones empresariales con múltiples consumidores de frontend, el enfoque Directus separado puede ser más limpio.

Precios y Licencias en 2026

Payload CMS Directus
Licencia MIT GPL-3.0 (con BSL para características de Cloud)
Costo auto-hospedado Gratis Gratis
Hospedaje en cloud Desde $30/mes (Payload Cloud) Desde $29/mes (Directus Cloud)
Nivel empresarial Precios personalizados Precios personalizados (comienza ~$1,500/mes)
Características premium Algunas características solo en Cloud Suscripción Directus+ ($99/mes para extensiones del marketplace)

Ambos son genuinamente de código abierto para auto-hospedaje. La licencia MIT de Payload es más permisiva — puedes incrustarlo en productos comerciales sin restricciones. La licencia GPL-3.0 de Directus significa que los trabajos derivados también deben ser GPL, lo que puede importar para productos SaaS.

Directus introdujo Directus+ a finales de 2025, una suscripción que desbloquea extensiones premium del marketplace y soporte prioritario. Es opcional pero algunas extensiones más avanzadas (como el asistente de contenido impulsado por IA) están detrás de este paywall.

Cuándo Elegir Cuál

Elige Payload CMS cuando:

  • Estás construyendo un nuevo proyecto desde cero (greenfield)
  • Tu equipo es pesado en TypeScript y quiere esquema-como-código
  • Estás usando Next.js y quieres la integración más cercana posible
  • Necesitas control de acceso complejo definido en código
  • Quieres todo en una unidad implementable
  • Valoras licencias MIT

Elige Directus cuando:

  • Tienes una base de datos existente que necesitas gestionar
  • Tu equipo incluye no desarrolladores que necesitan modificar esquemas
  • Necesitas soportar múltiples frontends (web, móvil, IoT) desde un CMS
  • Quieres un constructor visual de automatización/flow
  • Necesitas soporte amplio de base de datos (MySQL, MSSQL, Oracle, etc.)
  • Prefieres el CMS como un servicio separado e independiente

Si estás considerando estas opciones para un proyecto headless y quieres una segunda opinión, hacemos consultoría de arquitectura de CMS headless y podemos ayudarte a elegir la herramienta correcta antes de estar tres meses en la herramienta incorrecta.

Para proyectos usando Astro como marco de frontend, el enfoque API independiente de Directus se empareja naturalmente, ya que Astro obtiene datos en tiempo de compilación o vía endpoints de servidor. Payload funciona también, pero pierdes la ventaja del API Local ya que Astro y Payload serían procesos separados.

Preguntas Frecuentes

¿Payload CMS es realmente gratis en 2026? Sí. Payload CMS está bajo licencia MIT y es completamente gratis para auto-hospedaje. Payload Cloud es su servicio de hospedaje gestionado pagado, pero el CMS mismo — incluyendo todas las características principales — es de código abierto. No hay compuertas de características en la versión auto-hospedada.

¿Puede Directus funcionar con una base de datos existente sin modificarla? Principalmente sí. Directus puede introspeccionar una base de datos existente y crear una capa de gestión encima de ella. Añade algunas tablas del sistema (prefijadas con directus_) para su propia configuración, pero no modifica tus tablas existentes. Este es uno de sus diferenciadores más fuertes.

¿Cuál es mejor para un desarrollador solitario? Payload CMS tiende a ser el favorito entre desarrolladores solitarios que son cómodos con TypeScript. El flujo de trabajo code-first significa que puedes configurar colecciones rápidamente, y los tipos auto-generados reducen el boilerplate. Directus es mejor si quieres una interfaz visual para prototipado rápido de esquema sin escribir archivos de configuración.

¿Puedo usar Payload CMS sin Next.js? A partir de Payload 3.x, Next.js es el adaptador principal y el panel de administración se ejecuta en Next.js. Sin embargo, las APIs REST y GraphQL funcionan con cualquier frontend. No estás bloqueado en Next.js para tu sitio de consumidor — solo necesitas Next.js para ejecutar el admin de Payload. Ha habido discusiones de comunidad sobre adaptadores adicionales (como Nuxt), pero nada oficial todavía.

¿Cómo maneja Directus la localización de contenido? Directus soporta traducciones a nivel de campo. Marcas campos como traducibles, configuras tus idiomas, y Directus maneja el almacenamiento de traducciones en una tabla relacionada. La API te deja solicitar contenido en idiomas específicos vía los parámetros ?fields e idioma. Está bien implementado y ha sido estable durante años.

¿Cuál tiene mejor soporte de plugin/extensión? Directus tiene un marketplace de extensiones más grande, especialmente con las adiciones de Directus+. Puedes construir interfaces personalizadas, displays, endpoints, hooks y módulos. El modelo de extensión de Payload se basa en anulaciones de componentes de React y plugins — es poderoso pero el ecosistema es más pequeño. Los plugins de Payload tienden a ser más enfocados (plugin SEO, constructor de formularios, redirecciones) mientras que las extensiones de Directus cubren un rango más amplio.

¿Hay una diferencia de rendimiento para datasets grandes? Para datasets con millones de filas, ambos funcionan bien cuando están debidamente indexados. Directus tiene una ligera ventaja en flexibilidad de consulta cruda ya que genera SQL más directamente desde consultas de API. La capa ORM de Drizzle de Payload es eficiente pero añade un pequeño costo de abstracción. En práctica, tu sintonización de base de datos importa mucho más que cuál CMS elijas. Ambos soportan connection pooling y pueden funcionar con réplicas de lectura.

¿Puedo migrar de uno a otro después? Puedes, pero no es trivial. Los datos de contenido en sí (almacenados en PostgreSQL para ambos) pueden migrarse con herramientas de base de datos estándar. La parte más difícil es recrear tus definiciones de esquema, reglas de control de acceso y cualquier lógica personalizada. Si estás construyendo para una arquitectura headless, mantener tu frontend desacoplado de APIs específicas de CMS (usando una capa de abstracción) hará cualquier migración futura de CMS significativamente más fácil.