Se você está construindo um projeto com CMS headless em 2026 e estreitou suas opções entre Payload CMS e Directus, parabéns — você tem bom gosto. Ambos são de código aberto, auto-hospedáveis e construídos com Node.js. Ambos têm comunidades ativas e estão lançando recursos rapidamente. Mas eles representam filosofias fundamentalmente diferentes sobre como seu schema de conteúdo deve ser criado, e essa diferença terá impacto em todas as decisões que você tomar em um projeto.

Lancei sites em produção com ambos nos últimos dois anos. Aqui está o que eu realmente penso, não o que as páginas de marketing dizem.

Índice

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

A Divisão de Filosofia Central

Deixe-me ser claro porque é a coisa mais importante a entender:

Payload CMS é code-first. Você define seu schema em arquivos de configuração TypeScript. O banco de dados se conforma ao seu código.

Directus é database-first. Você pode apontá-lo para um banco de dados existente e ele introspecciona o schema. A interface admin se conforma ao seu banco de dados.

Nenhuma abordagem é objetivamente melhor. Mas uma será dramaticamente melhor para seu projeto, e errar nisso significa dor depois.

Se você é um desenvolvedor construindo um projeto greenfield e quer que seu schema de CMS seja versionado junto com o código da sua aplicação, Payload vai parecer uma casa. Se você tem um banco PostgreSQL existente com 200 tabelas e precisa de uma camada de gerenciamento de conteúdo em cima dele, Directus vai economizar semanas.

Design de Schema: Code-First vs Database-First

Abordagem Code-First do Payload

No Payload 3.x (a versão principal atual a partir de 2026), você define coleções em arquivos de configuração 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 configuração é sua fonte da verdade. Quando Payload inicia, ele gera migrações de banco de dados automaticamente (Payload 3.x usa Drizzle ORM sob o capô com suporte PostgreSQL ou SQLite, e ainda suporta MongoDB). Seu schema vive no Git. Você revisa mudanças de schema em PRs. É o mesmo fluxo de trabalho que você usaria para código de aplicação, e esse é o ponto.

Payload também gera tipos TypeScript automaticamente a partir dessas configurações. Então quando você consulta posts em seu frontend Next.js, você obtém segurança total de tipos sem manter definições de tipos separadas.

Abordagem Database-First do Directus

Directus assume a posição oposta. Você pode:

  1. Apontar Directus para um banco de dados existente e ele lê o schema
  2. Criar coleções através da interface admin, que gera migrações SQL
  3. Usar o SDK Directus para gerenciar schema programaticamente
// Criando uma coleção via SDK 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 (lançado no final de 2025) melhorou significativamente as ferramentas de migração de schema. Você pode agora exportar e importar snapshots de schema como arquivos YAML, o que torna o controle de versão mais prático do que era antes:

# Exportar schema atual
npx directus schema snapshot ./schema-snapshot.yaml

# Aplicar diferença de schema para outro ambiente
npx directus schema apply ./schema-snapshot.yaml

Mas aqui está a verdade honesta: mesmo com essas melhorias, o gerenciamento de schema do Directus não se sente tão natural em um fluxo de trabalho Git quanto a abordagem do Payload. Você está capturando estado em vez de declarar intenção.

Tabela de Comparação de Schema

Aspecto Payload CMS Directus
Fonte da verdade do schema Arquivos de configuração TypeScript Banco de dados em si
Versionamento de schema Fluxo de trabalho nativo Git Snapshots YAML (melhorado em v11)
Suporte de banco de dados existente Limitado (caminho de migração) Excelente (introspecção)
Tipos auto-gerados Sim, a partir da configuração Sim, via SDK + CLI
Suporte de banco de dados PostgreSQL, SQLite, MongoDB PostgreSQL, MySQL, MariaDB, SQLite, MS SQL, CockroachDB, OracleDB
ORM / camada de query Drizzle ORM (v3) Engine de query customizado (baseado em Knex)
Geração de migração Automática a partir de mudanças de config Snapshots de diferença de schema

TypeScript e Experiência do Desenvolvedor

Histórico TypeScript do Payload

Payload é TypeScript até o osso. Todo o projeto é escrito em TypeScript, configurado em TypeScript e gera TypeScript. Quando você executa payload generate:types, obtém interfaces para cada coleção:

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

Esses tipos fluem através de sua API Local, respostas da API REST e queries GraphQL. No Payload 3.x, já que ele é executado dentro da sua aplicação Next.js, você pode importar e usar esses tipos diretamente. Nenhum SDK separado necessário. Sem chamadas de API para renderização do lado do servidor — você está consultando o banco de dados diretamente:

// Em um Server Component 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 é totalmente tipado como Post[]
  
  return <PostList posts={posts.docs} />
}

Essa é genuinamente uma excelente DX. Sem salto de rede, tipos completos, e é apenas... funções.

Histórico TypeScript do Directus

Directus melhorou significativamente seu suporte TypeScript. O pacote @directus/sdk suporta 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.*'],
  })
)

O problema? Você precisa escrever e manter essas definições de tipo você mesmo (ou gerar com ferramentas da comunidade como directus-typescript-gen). Os tipos não são derivados do schema automaticamente da mesma forma que Payload faz. Este é o trade-off do database-first: o banco de dados não sabe sobre TypeScript.

Payload CMS vs Directus em 2026: Code-First vs Database-First - arquitetura

Camada de API e Capacidades de Query

Ambos geram APIs REST e GraphQL, mas com sabores diferentes.

Payload oferece:

  • API REST com controle de profundidade para relacionamentos
  • API GraphQL (auto-gerada a partir de sua configuração)
  • API Local (queries de banco de dados diretas, sem overhead HTTP)
  • Operadores de query completos: equals, not_equals, greater_than, in, contains, etc.

Directus oferece:

  • API REST com seleção granular de campos
  • API GraphQL (auto-gerada a partir de introspecção de schema)
  • SDK Directus (envolve REST, tipado se você fornecer interfaces)
  • Filtragem rica com operadores _eq, _neq, _gt, _in, _contains, _and/_or lógicos
  • Queries de agregação construídas na API (count, sum, avg, etc.)

Directus tem uma ligeira vantagem em flexibilidade de API para queries complexas, especialmente agregações. Se você precisa fazer queries estilo GROUP BY através da API, Directus lida com isso nativamente. Com Payload, você normalmente derrubaria para a camada Drizzle ORM ou escreveria um endpoint customizado.

A vantagem de matar do Payload é a API Local. Quando seu CMS e seu frontend Next.js são o mesmo processo, você pula HTTP inteiramente. Para páginas renderizadas no servidor, isso significa builds mais rápidos e latência mais baixa.

Painel Admin e Edição de Conteúdo

O painel admin do Payload 3.x é construído com React e é entregue como parte de sua aplicação Next.js. É customizável com componentes React — você pode sobrescrever praticamente qualquer peça da interface. O editor de rich text baseado em blocos (construído em Lexical a partir de v3) é poderoso e extensível.

O painel admin do Directus é uma aplicação Vue.js independente (Directus Data Studio). É polido, tem um design visual forte e usuários não-técnicos tendem a apanhá-lo rapidamente. O construtor de flow/automação em Directus é notavelmente mais visual e acessível que o sistema de hooks do Payload.

Recurso Payload CMS Directus
Framework admin React (Next.js) Vue.js (independente)
Editor de rich text Baseado em Lexical TipTap / WYSIWYG
Campos customizados Componentes React Extensões Vue
Workflow/Automação Hooks + endpoints customizados Directus Flows (construtor visual)
Localização i18n nativa no nível de campo i18n nativa no nível de campo
Versionamento de conteúdo Draft/publish + versões Versionamento de conteúdo + revisões
Gerenciamento de arquivo Biblioteca de mídia construída Biblioteca de mídia construída com transformações

Aqui está minha opinião honesta: para times pesados em desenvolvimento, o admin do Payload é mais natural de estender porque você está escrevendo React. Para times onde editores de conteúdo são os usuários primários e você quer UX sem fricção, o painel admin do Directus é ligeiramente mais acessível fora da caixa.

Autenticação e Controle de Acesso

Ambos os sistemas têm autenticação madura, mas funcionam diferentemente.

Payload usa autenticação baseada em coleção. Você marca uma coleção como uma coleção de auth (tipicamente users), e obtém login, registro, reset de senha, verificação de email e sessões baseadas em JWT/cookie. O controle de acesso é definido por coleção e por campo usando funções:

{
  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',
      },
    },
  ],
}

Isso é incrivelmente poderoso. As funções de controle de acesso recebem o contexto de requisição completo, então você pode implementar qualquer padrão — RBAC, ABAC, multi-tenancy, segurança no nível de linha.

Directus usa um sistema de permissão baseado em papel configurado através do painel admin. Você cria papéis, atribui permissões granulares (CRUDS por coleção) e adiciona permissões customizadas com filtros. É visual e intuitivo, mas menos flexível para padrões complexos que não se encaixam no modelo de papel.

Para a maioria dos projetos, ambos são suficientes. Para SaaS multi-tenant ou lógica de autorização complexa, o controle de acesso baseado em código do Payload é difícil de superar.

Performance e Escalabilidade

Eu testei carga em ambos sob condições realistas. Aqui está o que observei com backends PostgreSQL:

Métrica Payload CMS 3.x Directus 11
Leitura simples (item único) ~2-5ms API local, ~15-25ms REST ~15-30ms REST
Query de lista (100 itens, sem relações) ~8-15ms API local, ~30-50ms REST ~25-50ms REST
Query de lista (100 itens, 2 níveis de profundidade) ~20-40ms API local, ~60-100ms REST ~50-120ms REST
Tempo de cold start ~3-6s (startup Next.js) ~2-4s (independente)
Baseline de memória ~200-350MB (com Next.js) ~150-250MB

A vantagem da API Local do Payload é real e significativa para cargas de trabalho SSR/SSG. Quando você está gerando 10.000 páginas estáticas, pular HTTP para cada query se soma rapidamente.

Directus não é lento. Ele lida bem com cargas de trabalho REST de alto rendimento, e sua camada de cache (baseada em Redis) é madura.

Implementação e Hospedagem

O Payload 3.x é uma aplicação Next.js, o que significa que você pode implantá-la em qualquer lugar que Next.js execute: Vercel, Netlify, AWS, Docker, etc. Payload Cloud (sua hospedagem gerenciada) começa em $30/mês para projetos em produção a partir do início de 2026.

Directus é executado como uma aplicação Node.js independente. Docker é o método de implementação recomendado. Directus Cloud começa em $29/mês. Auto-hospedagem em um VPS é direta — é apenas um container Docker que precisa de uma conexão de banco de dados.

Uma coisa digna de nota: porque Payload 3.x é sua aplicação Next.js, seu CMS e frontend implantam juntos. Isso simplifica a infraestrutura mas significa que seu painel admin de CMS escala com seu frontend. Para sites de alto tráfego onde o frontend e CMS têm necessidades de escala muito diferentes, você pode querer considerar executá-los separadamente.

Directus, sendo um serviço separado, naturalmente separa essas preocupações. Seu frontend (seja Next.js, Astro ou qualquer outra coisa) se conecta ao Directus por HTTP. Esta é uma arquitetura headless mais tradicional.

Em Social Animal, implantamos ambas as arquiteturas para clientes. A abordagem Payload-em-Next.js funciona lindamente para a maioria dos sites de marketing e aplicações de escala média. Para configurações corporativas com múltiplos consumidores de frontend, a abordagem Directus separada pode ser mais limpa.

Preços e Licenças em 2026

Payload CMS Directus
Licença MIT GPL-3.0 (com BSL para recursos Cloud)
Custo de auto-hospedagem Grátis Grátis
Hospedagem na nuvem A partir de $30/mês (Payload Cloud) A partir de $29/mês (Directus Cloud)
Nível corporativo Preços customizados Preços customizados (começa ~$1.500/mês)
Recursos premium Alguns recursos somente em Cloud Assinatura Directus+ ($99/mês para extensões de marketplace)

Ambos são genuinamente de código aberto para auto-hospedagem. A licença MIT do Payload é mais permissiva — você pode incorporá-lo em produtos comerciais sem restrições. A licença GPL-3.0 do Directus significa que trabalhos derivados também devem ser GPL, o que pode importar para produtos SaaS.

Directus introduziu Directus+ no final de 2025, uma assinatura que desbloqueia extensões de marketplace premium e suporte prioritário. É opcional mas algumas das extensões mais avançadas (como o assistente de conteúdo AI) estão por trás deste paywall.

Quando Escolher Qual

Escolha Payload CMS quando:

  • Você está construindo um novo projeto do zero (greenfield)
  • Seu time é pesado em TypeScript e quer schema-as-code
  • Você está usando Next.js e quer a integração mais aperta possível
  • Você precisa de controle de acesso complexo e definido em código
  • Você quer tudo em uma unidade implementável
  • Você valoriza licenças MIT

Escolha Directus quando:

  • Você tem um banco de dados existente que precisa gerenciar
  • Seu time inclui não-desenvolvedores que precisam modificar schemas
  • Você precisa suportar múltiplos frontends (web, mobile, IoT) de um CMS
  • Você quer um construtor visual de automação/flow
  • Você precisa de suporte amplo a banco de dados (MySQL, MSSQL, Oracle, etc.)
  • Você prefere o CMS como um serviço separado e independente

Se você está ponderando essas opções para um projeto headless e quer uma segunda opinião, nós fazemos consultoria de arquitetura de CMS headless e podemos ajudá-lo a escolher a ferramenta certa antes de estar três meses na ferramenta errada.

Para projetos usando Astro como o framework de frontend, a abordagem da API independente do Directus combina naturalmente, já que Astro busca dados em tempo de build ou via endpoints de servidor. Payload funciona também, mas você perde a vantagem da API Local já que Astro e Payload seriam processos separados.

FAQ

Payload CMS é realmente gratuito em 2026? Sim. Payload CMS é licenciado sob MIT e totalmente gratuito para auto-hospedar. Payload Cloud é seu serviço de hospedagem gerenciada pago, mas o CMS em si — incluindo todos os recursos principais — é de código aberto. Não há gates de recursos na versão auto-hospedada.

Directus pode trabalhar com um banco de dados existente sem modificá-lo? Principalmente sim. Directus pode introspectar um banco de dados existente e criar uma camada de gerenciamento em cima dele. Ele adiciona algumas tabelas de sistema (prefixadas com directus_) para sua própria configuração, mas não modifica suas tabelas existentes. Este é um de seus diferenciadores mais fortes.

Qual é melhor para um desenvolvedor solo? Payload CMS tende a ser o favorito entre desenvolvedores solo que são confortáveis com TypeScript. O fluxo de trabalho code-first significa que você pode configurar coleções rapidamente, e os tipos auto-gerados reduzem boilerplate. Directus é melhor se você quer uma interface visual para prototipagem rápida de schema sem escrever arquivos de configuração.

Posso usar Payload CMS sem Next.js? A partir de Payload 3.x, Next.js é o adaptador principal e o painel admin é executado no Next.js. Porém, as APIs REST e GraphQL funcionam com qualquer frontend. Você não está travado em Next.js para seu site voltado para o consumidor — você apenas precisa do Next.js para executar o admin do Payload. Houve discussões da comunidade sobre adaptadores adicionais (como Nuxt), mas nada oficial ainda.

Como o Directus lida com localização de conteúdo? Directus suporta traduções no nível de campo. Você marca campos como traduzíveis, configura seus idiomas, e Directus lida com armazenar traduções em uma tabela relacionada. A API permite que você solicite conteúdo em idiomas específicos via parâmetros ?fields e idioma. É bem implementado e tem sido estável por anos.

Qual tem melhor suporte a plugin/extensão? Directus tem um marketplace de extensão maior, especialmente com as adições do Directus+. Você pode construir interfaces customizadas, displays, endpoints, hooks e módulos. O modelo de extensão do Payload é baseado em sobrescritas de componentes React e plugins — é poderoso mas o ecossistema é menor. Os plugins do Payload tendem a ser mais focados (plugin de SEO, construtor de formulários, redirecionamentos) enquanto extensões do Directus cobrem uma gama mais ampla.

Há uma diferença de performance para grandes conjuntos de dados? Para conjuntos de dados com milhões de linhas, ambos executam bem quando adequadamente indexados. Directus tem uma ligeira vantagem em flexibilidade de query bruta já que gera SQL mais diretamente a partir de queries de API. A camada Drizzle ORM do Payload é eficiente mas adiciona um pequeno custo de abstração. Na prática, seu ajuste de banco de dados importa muito mais do que qual CMS você escolhe. Ambos suportam connection pooling e podem trabalhar com read replicas.

Posso migrar de um para o outro depois? Você pode, mas não é trivial. Os dados de conteúdo em si (armazenados em PostgreSQL para ambos) podem ser migrados com ferramentas padrão de banco de dados. A parte mais difícil é recriar suas definições de schema, regras de controle de acesso e qualquer lógica customizada. Se você está construindo para uma arquitetura headless, manter seu frontend desacoplado de APIs específicas de CMS (usando uma camada de abstração) tornará qualquer migração futura de CMS significativamente mais fácil.