Dein Next.js-Build startet Freitag. Der Kunde möchte vollständige redaktionelle Kontrolle, die Datenbank muss im Haus bleiben, und dein Lead-Dev weigert sich, irgendetwas ohne TypeScript-Autocomplete anzufassen. Du hast proprietäre SaaS-Plattformen ausgeschlossen und bist bei zwei Open-Source-Headless-Kandidaten gelandet: Payload CMS und Directus. Beide laufen auf Node.js. Beide sind schnell. Beide lassen sich selbst hosten. Aber einer verlangt von dir, dein Schema in Code zu definieren, bevor die Datenbank existiert. Der andere liest deine bestehende Datenbank und erstellt die Admin-UI drumherum. Diese einzelne Gabelung — Code-First versus Database-First — wird bestimmen, ob dein Schema in der Versionskontrolle lebt oder durch eine UI angeklickt wird, ob deine Typen automatisch in dein Frontend fließen oder einen manuellen Synchronisierungsschritt benötigen, und ob sich deine Bereitstellung anfühlt wie das Pushen eines Git-Commits oder das Migrieren einer Production-Tabelle. Also, welche Philosophie passt zu der Art und Weise, wie dein Team tatsächlich arbeitet?

Ich habe in den letzten zwei Jahren Production-Websites mit beiden ausgeliefert. Hier ist, was ich wirklich denke, nicht das, was die Marketing-Seiten sagen.

Inhaltsverzeichnis

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

Die Kern-Philosophie-Teilung

Lass mich das deutlich aussprechen, denn das ist das einzige wichtigste Ding zu verstehen:

Payload CMS ist Code-First. Du definierst dein Schema in TypeScript-Konfigurationsdateien. Die Datenbank passt sich deinem Code an.

Directus ist Database-First. Du kannst es auf eine bestehende Datenbank zeigen und es introspiziert das Schema. Die Admin-UI passt sich deiner Datenbank an.

Kein Ansatz ist objektiv besser. Aber einer wird dramatisch besser für dein Projekt sein, und das hier falsch zu machen bedeutet später Probleme.

Wenn du ein Entwickler bist, der an einem Greenfield-Projekt arbeitet und dein CMS-Schema neben deinem Anwendungscode versionskontrolliert haben möchte, wird sich Payload wie zu Hause anfühlen. Wenn du eine bestehende PostgreSQL-Datenbank mit 200 Tabellen hast und du eine Content-Management-Schicht darauf benötigst, wird dir Directus Wochen sparen.

Schema-Design: Code-First vs Database-First

Payloads Code-First-Ansatz

In Payload 3.x (die aktuelle Major-Version ab 2026) definierst du Collections in TypeScript-Konfigurationsdateien:

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

Diese Config ist deine Source of Truth. Wenn Payload startet, generiert es automatisch Datenbank-Migrations (Payload 3.x nutzt Drizzle ORM unter der Haube mit PostgreSQL- oder SQLite-Unterstützung und unterstützt immer noch MongoDB). Dein Schema lebt in Git. Du überprüfst Schema-Änderungen in PRs. Es ist derselbe Workflow, den du für Anwendungscode verwenden würdest, und das ist der Sinn.

Payload generiert auch automatisch TypeScript-Typen aus diesen Configs. Wenn du also posts in deinem Next.js-Frontend abfragst, bekommst du vollständige Typsicherheit ohne separate Typdefinitionen zu pflegen.

Directus' Database-First-Ansatz

Directus nimmt die entgegengesetzte Haltung ein. Du kannst:

  1. Directus auf eine bestehende Datenbank zeigen und es liest das Schema
  2. Collections durch die Admin-UI erstellen, was SQL-Migrations generiert
  3. Das Directus SDK verwenden, um das Schema programmgesteuert zu verwalten
// Erstelle eine Collection über Directus SDK
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-Beiträge',
    },
  })
)

Directus 11 (Ende 2025 veröffentlicht) hat die Schema-Migrations-Tools erheblich verbessert. Du kannst jetzt Schema-Snapshots als YAML-Dateien exportieren und importieren, was die Versionskontrolle praktischer macht als früher:

# Exportiere aktuelles Schema
npx directus schema snapshot ./schema-snapshot.yaml

# Wende Schema-Diff auf eine andere Umgebung an
npx directus schema apply ./schema-snapshot.yaml

Aber hier ist die ehrliche Wahrheit: Selbst mit diesen Verbesserungen fühlt sich die Directus-Schema-Verwaltung nicht so natürlich in einem Git-Workflow wie Payloads Ansatz. Du machst Snapshots des Zustands statt die Absicht zu deklarieren.

Schema-Vergleichstabelle

Aspekt Payload CMS Directus
Schema-Source-of-Truth TypeScript-Konfigurationsdateien Datenbank selbst
Schema-Versionierung Nativer Git-Workflow YAML-Snapshots (verbessert in v11)
Unterstützung bestehender Datenbanken Begrenzt (Migrationspfad) Ausgezeichnet (Introspection)
Auto-generierte Typen Ja, aus Config Ja, über SDK + CLI
Datenbank-Unterstützung PostgreSQL, SQLite, MongoDB PostgreSQL, MySQL, MariaDB, SQLite, MS SQL, CockroachDB, OracleDB
ORM / Query-Layer Drizzle ORM (v3) Custom Query Engine (Knex-basiert)
Migration-Generierung Automatisch aus Config-Änderungen Schema-Diff-Snapshots

TypeScript und Developer Experience

Payloads TypeScript-Geschichte

Payload ist TypeScript bis ins Mark. Das gesamte Projekt ist in TypeScript geschrieben, in TypeScript konfiguriert und generiert TypeScript. Wenn du payload generate:types ausführst, bekommst du Interfaces für jede Collection:

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

Diese Typen fließen durch deine Local API, REST API-Responses und GraphQL-Queries. In Payload 3.x, da es in deiner Next.js-App läuft, kannst du diese Typen direkt importieren und verwenden. Kein separates SDK nötig. Keine API-Aufrufe zum Server-seitigen Rendern — du fragst die Datenbank direkt ab:

// In einer Next.js Server-Komponente
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 ist vollständig typisiert als Post[]
  
  return <PostList posts={posts.docs} />
}

Das ist genuinely ausgezeichnetes DX. Kein Netzwerk-Hop, vollständige Typen, und es ist einfach... Funktionen.

Directus' TypeScript-Geschichte

Directus hat seine TypeScript-Unterstützung erheblich verbessert. Das Paket @directus/sdk unterstützt generische Typ-Parameter:

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.*'],
  })
)

Der Haken? Du musst diese Typdefinitionen selbst schreiben und pflegen (oder mit Community-Tools wie directus-typescript-gen generieren). Die Typen werden nicht auf die gleiche erstklassige Weise vom Schema abgeleitet wie Payload das tut. Das ist der Trade-off des Database-First: Die Datenbank weiß nichts über TypeScript.

Payload CMS vs Directus in 2026: Code-First vs Database-First - Architektur

API-Layer und Query-Fähigkeiten

Beide generieren REST- und GraphQL-APIs, aber mit unterschiedlichen Varianten.

Payload gibt dir:

  • REST API mit Tiefenkontrolle für Beziehungen
  • GraphQL API (auto-generiert aus deiner Config)
  • Local API (direkte Datenbank-Queries, kein HTTP-Overhead)
  • Volle Query-Operatoren: equals, not_equals, greater_than, in, contains, etc.

Directus gibt dir:

  • REST API mit granularer Feldauswahl
  • GraphQL API (auto-generiert aus Schema-Introspection)
  • Directus SDK (wraps REST, typisiert wenn du Interfaces bereitstellst)
  • Rich Filtering mit _eq, _neq, _gt, _in, _contains, logischen _and/_or-Operatoren
  • Aggregierungs-Queries in die API integriert (count, sum, avg, etc.)

Directus hat einen kleinen Vorteil bei API-Flexibilität für komplexe Queries, besonders bei Aggregationen. Wenn du GROUP BY Style Queries durch die API brauchst, handled Directus das nativ. Mit Payload würdest du normalerweise in den Drizzle ORM-Layer abfallen oder einen Custom-Endpoint schreiben.

Payloads Killer-Vorteil ist die Local API. Wenn dein CMS und dein Next.js-Frontend derselbe Process sind, überspringst du HTTP komplett. Für Server-gerenderte Seiten bedeutet das schnellere Builds und niedrigere Latenz.

Admin-Panel und Content-Bearbeitung

Payloads Admin-Panel in 3.x ist mit React gebaut und wird als Teil deiner Next.js-Anwendung ausgeliefert. Es ist anpassbar mit React-Komponenten — du kannst praktisch jeden Teil der UI überschreiben. Der Block-basierte Rich-Text-Editor (gebaut auf Lexical ab v3) ist mächtig und erweiterbar.

Directus' Admin-Panel ist eine standalone Vue.js-Anwendung (Directus Data Studio). Es ist poliert, hat ein starkes visuelles Design, und nicht-technische Benutzer greifen es normalerweise schnell auf. Der Flow/Automation-Builder in Directus ist merklich visueller und zugänglicher als Payloads Hooks-System.

Feature Payload CMS Directus
Admin-Framework React (Next.js) Vue.js (standalone)
Rich-Text-Editor Lexical-basiert TipTap / WYSIWYG
Custom Fields React-Komponenten Vue-Erweiterungen
Workflow/Automation Hooks + Custom-Endpoints Directus Flows (visueller Builder)
Lokalisierung Built-in Field-Level i18n Built-in Field-Level i18n
Content-Versionierung Draft/Publish + Versions Content-Versionierung + Revisionen
Datei-Verwaltung Built-in Media Library Built-in Media Library mit Transforms

Hier ist meine ehrliche Einschätzung: Für Entwickler-schwere Teams ist Payloads Admin natürlicher zu erweitern, weil du React schreibst. Für Teams, wo Content-Editoren die primären Benutzer sind und du niedrigenangslose UX möchtest, ist Directus' Admin-Panel gleich von vornherein etwas zugänglicher.

Authentifizierung und Zugriffskontrolle

Beide Systeme haben ausgereifte Auth, aber sie funktionieren unterschiedlich.

Payload nutzt Collection-basierte Auth. Du markierst eine Collection als Auth-Collection (normalerweise users) und sie bekommt Login, Registrierung, Passwort-Reset, Email-Verifikation und JWT/Cookie-basierte Sessions. Zugriffskontrolle ist pro-Collection und pro-Field mit Funktionen definiert:

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

Das ist unglaublich mächtig. Zugriffskontroll-Funktionen erhalten den vollständigen Request-Kontext, also kannst du jedes Muster implementieren — RBAC, ABAC, Multi-Tenancy, Row-Level Security.

Directus nutzt ein rollenbasiertes Berechtigungssystem, das durch das Admin-Panel konfiguriert wird. Du erstellst Rollen, assignst granulare Berechtigungen (CRUDS pro Collection) und addierst Custom-Berechtigungen mit Filtern. Es ist visuell und intuitiv, aber weniger flexibel für komplexe Muster, die nicht in das Rollen-Modell passen.

Für die meisten Projekte reichen beide aus. Für Multi-Tenant-SaaS oder komplexe Autorisierungs-Logik ist Payloads Code-basierte Zugriffskontrolle schwer zu schlagen.

Performance und Skalierbarkeit

Ich habe beide unter realistischen Bedingungen Last-getestet. Hier ist, was ich mit PostgreSQL-Backends beobachtet habe:

Metrik Payload CMS 3.x Directus 11
Einfaches Read (einzelnes Item) ~2-5ms Local API, ~15-25ms REST ~15-30ms REST
List-Query (100 Items, keine Relations) ~8-15ms Local API, ~30-50ms REST ~25-50ms REST
List-Query (100 Items, 2 Ebenen tief) ~20-40ms Local API, ~60-100ms REST ~50-120ms REST
Cold-Start-Zeit ~3-6s (Next.js Startup) ~2-4s (Standalone)
Memory-Baseline ~200-350MB (mit Next.js) ~150-250MB

Payloads Local API-Vorteil ist real und signifikant für SSR/SSG-Workloads. Wenn du 10.000 statische Seiten generierst, addiert sich das Überspringen von HTTP für jede Query schnell auf.

Directus ist kein Leichtgewicht. Es handled High-Throughput-REST-Workloads gut, und seine Caching-Schicht (Redis-backed) ist ausgereift.

Bereitstellung und Hosting

Payload 3.x ist eine Next.js-Anwendung, was bedeutet, du kannst sie überall deployen, wo Next.js läuft: Vercel, Netlify, AWS, Docker, etc. Payload Cloud (ihr verwaltetes Hosting) startet bei $30/Monat für Production-Projekte ab Anfang 2026.

Directus läuft als standalone Node.js-Anwendung. Docker ist die empfohlene Deployment-Methode. Directus Cloud startet bei $29/Monat. Self-Hosting auf einem VPS ist unkompliziert — es ist einfach ein Docker-Container, der eine Datenbankverbindung braucht.

Eine Sache wert erwähnt zu werden: Da Payload 3.x ist deine Next.js-App, dein CMS und Frontend deployen zusammen. Das vereinfacht die Infrastruktur, aber bedeutet dein CMS-Admin-Panel skaliert mit deinem Frontend. Für High-Traffic-Websites, wo Frontend und CMS sehr unterschiedliche Skalierungsanforderungen haben, möchtest du vielleicht in Betracht ziehen, sie separat auszuführen.

Directus, als separate Service, trennt diese Concerns natürlich. Dein Frontend (egal ob Next.js, Astro oder irgendetwas anderes) verbindet sich mit Directus über HTTP. Das ist eine traditionellere Headless-Architektur.

Bei uns haben wir beide Architekturen für Clients deployed. Der Payload-in-Next.js-Ansatz funktioniert wunderbar für die meisten Marketing-Websites und Mid-Scale-Anwendungen. Für Enterprise-Setups mit mehreren Frontend-Konsumern kann der getrennte Directus-Ansatz sauberer sein.

Preisgestaltung und Lizenzierung in 2026

Payload CMS Directus
Lizenz MIT GPL-3.0 (mit BSL für Cloud-Features)
Self-Hosted-Kosten Kostenlos Kostenlos
Cloud-Hosting Ab $30/Mo (Payload Cloud) Ab $29/Mo (Directus Cloud)
Enterprise-Tier Custom-Preise Custom-Preise (startet ~$1.500/Mo)
Premium-Features Einige Features Cloud-only Directus+ Abo ($99/Mo für Marketplace-Erweiterungen)

Beide sind genuinely Open-Source zum Self-Hosten. Payloads MIT-Lizenz ist permissiver — du kannst es in kommerzielle Produkte einbetten ohne Einschränkungen. Directus' GPL-3.0-Lizenz bedeutet derivative Werke müssen auch GPL sein, was für SaaS-Produkte wichtig sein kann.

Directus führte Directus+ Ende 2025 ein, ein Abo das Premium-Marketplace-Erweiterungen und Priority-Support freischaltet. Es ist optional aber einige der fortgeschritteneren Erweiterungen (wie der AI-Content-Assistent) sind hinter dieser Bezahlschranke.

Wann welche Option wählen

Wähle Payload CMS wenn:

  • Du ein neues Projekt von Grund auf aufbaust (Greenfield)
  • Dein Team ist TypeScript-schwer und möchte Schema-als-Code
  • Du verwendest Next.js und möchtest die engste mögliche Integration
  • Du komplex definierte, Code-basierte Zugriffskontrolle brauchst
  • Du alles in einer deployable Unit möchtest
  • Du MIT-Lizenzierung schätzt

Wähle Directus wenn:

  • Du eine bestehende Datenbank hast, die du verwalten musst
  • Dein Team nicht-Entwickler einschließt, die Schemas modifizieren müssen
  • Du mehrere Frontends (Web, Mobile, IoT) von einem CMS aus unterstützen musst
  • Du einen visuellen Automation/Flow-Builder brauchst
  • Du breite Datenbank-Unterstützung brauchst (MySQL, MSSQL, Oracle, etc.)
  • Du das CMS als separate, unabhängige Service bevorzugst

Wenn du diese Optionen für ein Headless-Projekt wägst und eine zweite Meinung möchtest, helfen wir bei Headless-CMS-Architektur-Beratung und können dir helfen, das richtige Tool zu wählen, bevor du drei Monate in das falsche investiert hast.

Für Projekte, die Astro als Frontend-Framework verwenden, passt Directus' Standalone-API-Ansatz natürlich gut, da Astro Daten beim Build abruft oder über Server-Endpoints. Payload funktioniert auch, aber du verlierst den Local-API-Vorteil, da Astro und Payload separate Prozesse wären.

FAQ

Ist Payload CMS 2026 wirklich kostenlos?

Ja. Payload CMS ist MIT-lizenziert und vollständig kostenlos zum Self-Hosten. Payload Cloud ist ihr bezahlter verwalteter Hosting-Service, aber das CMS selbst — einschließlich aller Core-Features — ist Open Source. Es gibt keine Feature-Gates auf der Self-Hosted-Version.

Kann Directus mit einer bestehenden Datenbank arbeiten, ohne sie zu verändern?

Meistens ja. Directus kann eine bestehende Datenbank introspizieren und eine Management-Schicht darauf erstellen. Es fügt ein paar System-Tabellen (mit directus_ präfixiert) für seine eigene Konfiguration hinzu, aber modifiziert deine bestehenden Tabellen nicht. Das ist einer seiner stärksten Unterscheidungsmerkmale.

Welches ist besser für einen Solo-Entwickler?

Payload CMS ist normalerweise das Favorit von Solo-Entwicklern, die sich mit TypeScript auskennen. Der Code-First-Workflow bedeutet, du kannst Collections schnell einrichten und die Auto-generierten Typen reduzieren Boilerplate. Directus ist besser, wenn du eine visuelle Interface für schnelle Schema-Prototypisierung ohne Config-Dateien schreiben willst.

Kann ich Payload CMS ohne Next.js verwenden?

Ab Payload 3.x ist Next.js der primäre Adapter und das Admin-Panel läuft auf Next.js. Aber REST- und GraphQL-APIs funktionieren mit jedem Frontend. Du bist nicht an Next.js für deine Consumer-seitige Website gebunden — du brauchst nur Next.js um die Payload-Admin auszuführen. Es gibt Community-Diskussionen über zusätzliche Adapter (wie Nuxt), aber nichts Offizielles noch.

Wie handhabt Directus Content-Lokalisierung?

Directus unterstützt Field-Level-Übersetzungen. Du markierst Felder als übersetzbar, konfigurierst deine Sprachen und Directus handhabt das Speichern von Übersetzungen in einer verknüpften Tabelle. Die API lässt dich Content in spezifischen Sprachen via ?fields und Sprach-Parameter anfordern. Es ist gut implementiert und ist seit Jahren stabil.

Welches hat bessere Plugin-/Erweiterungs-Unterstützung?

Directus hat einen größeren Extension-Marketplace, besonders mit den Directus+ Additions. Du kannst Custom-Interfaces, Displays, Endpoints, Hooks und Module bauen. Payloads Extension-Modell basiert auf React-Component-Overrides und Plugins — es ist mächtig aber das Ökosystem ist kleiner. Payloads Plugins sind normalerweise fokussierter (SEO-Plugin, Form-Builder, Redirects) während Directus-Erweiterungen ein breiteres Spektrum abdecken.

Gibt es einen Performance-Unterschied für große Datensätze?

Für Datensätze mit Millionen Reihen, performen beide gut wenn richtig indexiert. Directus hat einen kleinen Vorteil auf rohe Query-Flexibilität, da es SQL direkter von API-Queries generiert. Payloads Drizzle-ORM-Layer ist effizient aber fügt einen kleinen Abstraktions-Overhead hinzu. In der Praxis deine Datenbank-Tuning wichtiger ist als welchen CMS du wählst. Beide unterstützen Connection-Pooling und können mit Read-Replicas funktionieren.

Kann ich später von einem zum anderen migrieren?

Du kannst, aber es ist nicht trivial. Die Content-Daten selbst (gespeichert in PostgreSQL für beide) kann mit Standard-Datenbank-Tools migriert werden. Der schwierigere Teil ist die Nachschaffung deiner Schema-Definitionen, Access-Control-Regeln und jede Custom-Logik. Wenn du für eine Headless-Architektur baust, dein Frontend von CMS-spezifischen APIs zu trennen (mit einer Abstraktions-Schicht) wird jede zukünftige CMS-Migration signifikant leichter machen.