Payload CMS vs Directus 2026: Code-First of Database-First?
Je Next.js-build start vrijdag. De client wil volledige redactionele controle, de database moet on-premises blijven, en je lead dev weigert alles aan te raken zonder TypeScript autocomplete. Je hebt propriëtaire SaaS-platforms verworpen en bent uitgekomen op twee open-source headless-tegenstanders: Payload CMS en Directus. Beide draaien op Node.js. Beide worden snel verstuurd. Beide laten je zelf hosten. Maar één vraagt je om je schema in code te definiëren voordat de database bestaat. De ander leest je bestaande database en bouwt de admin-interface eromheen. Dat ene keuzemerk — code-first versus database-first — bepaalt of je schema in versiebeheer leeft of wordt geklikt via een UI, of je typen automatisch naar je frontend vloeien of een handmatige synchronisatiestap vereisen, en of je deployment voelt als een Git-commit pushen of een productatabel migreren. Dus welke filosofie past bij de manier waarop je team eigenlijk werkt?
Ik heb in de afgelopen twee jaar productiesite met beide verstuurd. Hier is wat ik echt denk, niet wat de marketingpagina's zeggen.
Inhoudsopgave
- De kernfilosofie-splitsing
- Schemaontwerp: Code-First vs Database-First
- TypeScript en Developer Experience
- API-laag en querymogelijkheden
- Admin-panel en content-editing
- Authenticatie en toegangsbeheer
- Prestaties en schaalbaarheid
- Implementatie en hosting
- Prijzen en licenties in 2026
- Wanneer welke kiezen
- Veelgestelde vragen

De kernfilosofie-splitsing
Laten we dit duidelijk stellen omdat het het enige meest belangrijke ding is om te begrijpen:
Payload CMS is code-first. Je definiëert je schema in TypeScript-configuratiebestanden. De database past zich aan je code aan.
Directus is database-first. Je kunt het naar een bestaande database wijzen en het introspieert het schema. De admin-interface past zich aan je database aan.
Geen enkele benadering is objectief beter. Maar één zal voor je project dramatisch beter zijn, en dit verkeerd doen betekent later pijn.
Als je een ontwikkelaar bent die een greenfield-project bouwt en je wilt dat je CMS-schema naast je applicatiecode wordt versiecontroleerd, zal Payload zich thuis voelen. Als je een bestaande PostgreSQL-database hebt met 200 tabellen en je hebt een content management-laag nodig, zal Directus je weken besparen.
Schemaontwerp: Code-First vs Database-First
Payloads Code-First-benadering
In Payload 3.x (de huidige hoofdversie vanaf 2026) definieer je verzamelingen in TypeScript-configuratiebestanden:
// 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',
},
],
}
Deze configuratie is je bron van waarheid. Wanneer Payload start, genereert het automatisch databasemigraties (Payload 3.x gebruikt Drizzle ORM onder de motorkap met PostgreSQL- of SQLite-ondersteuning, en ondersteunt nog steeds MongoDB). Je schema leeft in Git. Je beoordeelt schemawijzigingen in PR's. Het is dezelfde workflow die je voor applicatiecode zou gebruiken, en dat is het punt.
Payload genereert ook automatisch TypeScript-typen uit deze configs. Dus wanneer je posts in je Next.js-frontend opvraagt, krijg je volledige typeveiligheid zonder aparte typedefinities te onderhouden.
Directus's Database-First-benadering
Directus neemt de tegengestelde positie in. Je kunt:
- Directus naar een bestaande database wijzen en het leest het schema
- Verzamelingen via de admin-interface maken, wat SQL-migraties genereert
- De Directus SDK gebruiken om het schema programmatisch te beheren
// Een verzameling maken via 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 posts',
},
})
)
Directus 11 (uitgebracht eind 2025) verbeterde de hulpmiddelen voor schemamigratie aanzienlijk. Je kunt nu schemamomentopnamen als YAML-bestanden exporteren en importeren, wat versiebeheer praktischer maakt dan voorheen:
# Huidige schema exporteren
npx directus schema snapshot ./schema-snapshot.yaml
# Schemawijziging toepassen op een ander milieu
npx directus schema apply ./schema-snapshot.yaml
Maar hier is de eerlijke waarheid: zelfs met deze verbeteringen voelt Directus-schemabeheer niet zo natuurlijk in een Git-workflow als Payloads benadering. Je maakt een momentopname van de staat in plaats van bedoeling te declareren.
Schemavergelingingtabel
| Aspect | Payload CMS | Directus |
|---|---|---|
| Schemabron van waarheid | TypeScript-configuratiebestanden | Database zelf |
| Schemaversiebeheer | Inheemse Git-workflow | YAML-momentopnamen (verbeterd in v11) |
| Ondersteuning bestaande database | Beperkt (migratiepad) | Uitstekend (introspectie) |
| Automatisch gegenereerde typen | Ja, uit configuratie | Ja, via SDK + CLI |
| Databaseondersteuning | PostgreSQL, SQLite, MongoDB | PostgreSQL, MySQL, MariaDB, SQLite, MS SQL, CockroachDB, OracleDB |
| ORM / Query-laag | Drizzle ORM (v3) | Aangepaste query-engine (op Knex gebaseerd) |
| Migratiegeneratie | Automatisch uit configuratiewijzigingen | Schemawijzigingsmomentnamen |
TypeScript en Developer Experience
Payloads TypeScript-verhaal
Payload is TypeScript tot in het bot. Het hele project is geschreven in TypeScript, geconfigureerd in TypeScript, en genereert TypeScript. Wanneer je payload generate:types uitvoert, krijg je interfaces voor elke verzameling:
// Automatisch gegenereerd
export interface Post {
id: string
title: string
content?: RichTextContent
author?: string | User
publishedAt?: string
status?: 'draft' | 'published'
createdAt: string
updatedAt: string
}
Deze typen vloeien door naar je Local API, REST API-reacties, en GraphQL-vragen. In Payload 3.x, aangezien het binnen je Next.js-app draait, kun je deze typen rechtstreeks importeren en gebruiken. Geen aparte SDK nodig. Geen API-aanroepen voor server-side rendering — je bevraagt de database rechtstreeks:
// In een Next.js Server Component
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 is volledig getypeerd als Post[]
return <PostList posts={posts.docs} />
}
Dit is echt geweldig DX. Geen netwerksprong, volledige typen, en het is gewoon... functies.
Directus's TypeScript-verhaal
Directus heeft zijn TypeScript-ondersteuning aanzienlijk verbeterd. Het pakket @directus/sdk ondersteunt generieke typeparameters:
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.*'],
})
)
De haal? Je moet die typedefinities zelf schrijven en onderhouden (of ze genereren met community-hulpmiddelen zoals directus-typescript-gen). De typen worden niet op dezelfde eerste-klasse-manier automatisch uit het schema afgeleid als Payload dat doet. Dit is de afweging van database-first: de database weet niets van TypeScript.

API-laag en querymogelijkheden
Beiden genereren REST- en GraphQL-API's, maar met verschillende smaken.
Payload geeft je:
- REST API met dieptebeheer voor relaties
- GraphQL API (automatisch gegenereerd uit je configuratie)
- Local API (directe databasevragen, geen HTTP-overhead)
- Volledige queryoperators: equals, not_equals, greater_than, in, contains, enz.
Directus geeft je:
- REST API met granulaire veldelectie
- GraphQL API (automatisch gegenereerd uit schemaïntrospectie)
- Directus SDK (hulsmiddel REST, getypeerd als je interfaces biedt)
- Rijke filtering met
_eq,_neq,_gt,_in,_contains, logische_and/_or-operators - Aggregatievragen ingebouwd in de API (count, sum, avg, enz.)
Directus heeft een klein voordeel op API-flexibiliteit voor complexe vragen, vooral aggregaties. Als je GROUP BY-stijlvragen via de API moet doen, behandelt Directus dat inheems. Met Payload zou je meestal naar de Drizzle ORM-laag afdalen of een aangepast eindpunt schrijven.
Payloads killer-voordeel is de Local API. Wanneer je CMS en je Next.js-frontend hetzelfde proces zijn, sla je HTTP over. Voor server-gerenderde pagina's betekent dit snellere builds en lagere latentie.
Admin-panel en content-editing
Payloads admin-panel voor 3.x is gebouwd met React en wordt als onderdeel van je Next.js-applicatie verstuurd. Het is aanpasbaar met React-componenten — je kunt vrijwel elk deel van de UI overschrijven. De op blokken gebaseerde rich-text-editor (gebouwd op Lexical vanaf v3) is krachtig en uitbreidbaar.
Directus's admin-panel is een zelfstandige Vue.js-applicatie (Directus Data Studio). Het is gepolijst, heeft een sterk visueel ontwerp, en niet-technische gebruikers pakken het meestal snel op. De flow/automation-builder in Directus is opmerkelijk visueler en toegankelijker dan Payloads hooks-systeem.
| Functie | Payload CMS | Directus |
|---|---|---|
| Admin-framework | React (Next.js) | Vue.js (zelfstandig) |
| Rich text editor | Lexical-gebaseerd | TipTap / WYSIWYG |
| Aangepaste velden | React-componenten | Vue-extensies |
| Workflow/Automatisering | Hooks + aangepaste eindpunten | Directus Flows (visuele builder) |
| Lokalisatie | Ingebouwde veld-niveau i18n | Ingebouwde veld-niveau i18n |
| Content-versiering | Concept/publicatie + versies | Content-versiering + herzieningen |
| Bestandsbeheer | Ingebouwde mediabibliotheek | Ingebouwde mediabibliotheek met transformaties |
Hier is mijn eerlijke mening: voor developer-zware teams is Payloads admin meer natuurlijk uit te breiden omdat je React schrijft. Voor teams waarbij content-editors de primaire gebruikers zijn en je lage-wrijving UX wilt, is Directus's admin-panel enigszins beter toegankelijk uit het vak.
Authenticatie en toegangsbeheer
Beiden systemen hebben rijpe auth, maar ze werken anders.
Payload gebruikt verzamelingsgebaseerde auth. Je markeert een verzameling als een auth-verzameling (meestal users), en het krijgt login, registratie, wachtwoord reset, e-mailverificatie, en JWT/cookie-gebaseerde sessies. Toegangsbeheer wordt per verzameling en per veld gedefinieerd met functies:
{
slug: 'posts',
access: {
read: () => true, // Public
create: ({ req: { user } }) => Boolean(user), // Authenticated
update: ({ req: { user } }) => user?.role === 'admin',
delete: ({ req: { user } }) => user?.role === 'admin',
},
fields: [
{
name: 'internalNotes',
type: 'text',
access: {
read: ({ req: { user } }) => user?.role === 'admin',
},
},
],
}
Dit is ongelooflijk krachtig. Toegangsbeheerfuncties ontvangen de volledige verzoekcontext, dus je kunt elk patroon implementeren — RBAC, ABAC, multi-tenancy, rij-level-veiligheid.
Directus gebruikt een op rollen gebaseerd toestemmingssysteem dat via de admin-interface is geconfigureerd. Je maakt rollen, wijst granulaire toestemmingen toe (CRUDS per verzameling), en voegt aangepaste toestemmingen toe met filters. Het is visueel en intuïtief, maar minder flexibel voor complexe patronen die niet in het rolmodel passen.
Voor de meeste projecten zijn beide voldoende. Voor multi-tenant SaaS of complexe autorisatielogica is Payloads code-gebaseerde toegangsbeheer moeilijk te verslaan.
Prestaties en schaalbaarheid
Ik heb beide onder realistische omstandigheden belast getest. Dit is wat ik met PostgreSQL-backends heb opgemerkt:
| Metriek | Payload CMS 3.x | Directus 11 |
|---|---|---|
| Eenvoudig lezen (enkel item) | ~2-5ms local API, ~15-25ms REST | ~15-30ms REST |
| Lijstquery (100 items, geen relaties) | ~8-15ms local API, ~30-50ms REST | ~25-50ms REST |
| Lijstquery (100 items, 2 niveaus diep) | ~20-40ms local API, ~60-100ms REST | ~50-120ms REST |
| Koud startmoment | ~3-6s (Next.js-opstart) | ~2-4s (zelfstandig) |
| Geheugenbasislijn | ~200-350MB (met Next.js) | ~150-250MB |
Payloads Local API-voordeel is echt en significant voor SSR/SSG-werklasten. Wanneer je 10.000 statische pagina's genereert, voegt het overslaan van HTTP voor elke query snel op.
Directus is geen slak echter. Het behandelt hoge-doorvoerpassings REST-werklasten goed, en de caching-laag (Redis-gesteund) is volwassen.
Implementatie en hosting
Payload 3.x is een Next.js-applicatie, wat betekent dat je het overal kunt implementeren waar Next.js draait: Vercel, Netlify, AWS, Docker, enz. Payload Cloud (hun beheerde hosting) start vanaf $30/maand voor productieprojecten vanaf begin 2026.
Directus draait als een zelfstandige Node.js-applicatie. Docker is de aanbevolen implementatiemethode. Directus Cloud start vanaf $29/maand. Zelf hosten op een VPS is eenvoudig — het is gewoon een Docker-container die een databaseverbinding nodig heeft.
Eén ding dat de moeite waard is: omdat Payload 3.x is je Next.js-app, implementeert je CMS en frontend samen. Dit vereenvoudigt de infrastructuur maar betekent dat je CMS-admin-panel schaalt met je frontend. Voor sites met veel verkeer waarbij frontend en CMS zeer verschillende schaalbehoeften hebben, wil je misschien overwegen ze apart uit te voeren.
Directus, zijnde een aparte service, scheidt deze problemen natuurlijk. Je frontend (of het nu Next.js, Astro of iets anders is) maakt via HTTP verbinding met Directus. Dit is een meer traditionele headless-architectuur.
Bij Social Animal hebben we beide architecturen voor clients geïmplementeerd. De Payload-in-Next.js-benadering werkt prachtig voor de meeste marketing-sites en mid-scale toepassingen. Voor enterprise-setups met meerdere frontend-consumenten kan de gescheiden Directus-benadering schoner zijn.
Prijzen en licenties in 2026
| Payload CMS | Directus | |
|---|---|---|
| Licentie | MIT | GPL-3.0 (met BSL voor Cloud-functie) |
| Zelf gehost kostprijs | Gratis | Gratis |
| Cloud hosting | Van $30/mo (Payload Cloud) | Van $29/mo (Directus Cloud) |
| Enterprise-tier | Aangepaste prijzen | Aangepaste prijzen (~$1.500/mo) |
| Premium-functie | Sommige functies alleen Cloud | Directus+ abonnement ($99/mo voor marketplace-extensies) |
Beiden zijn echt open-source voor zelf hosten. Payloads MIT-licentie is permissiever — je kunt het insluiten in commerciële producten zonder beperkingen. Directus's GPL-3.0-licentie betekent dat afgeleide werken ook GPL moeten zijn, wat belangrijk kan zijn voor SaaS-producten.
Directus introduceerde Directus+ eind 2025, een abonnement dat marketplace-extensies en prioriteitsondersteuning ontgrendelt. Het is optioneel, maar sommige meer geavanceerde extensies (zoals de AI-content-assistent) zijn achter deze betaalmuur.
Wanneer welke kiezen
Kies Payload CMS wanneer:
- Je bouwt een nieuw project vanaf nul (greenfield)
- Je team is TypeScript-zwaar en wil schema-als-code
- Je gebruikt Next.js en wilt de nauwste mogelijke integratie
- Je hebt complexe, code-gedefinieerde toegangscontrole nodig
- Je wilt alles in één implementeerbare eenheid
- Je waardeert MIT-licenties
Kies Directus wanneer:
- Je hebt een bestaande database die je moet beheren
- Je team bevat niet-ontwikkelaars die schema's moeten kunnen wijzigen
- Je moet meerdere frontends (web, mobiel, IoT) van één CMS ondersteunen
- Je hebt een visuele automation/flow-builder nodig
- Je hebt brede databaseondersteuning nodig (MySQL, MSSQL, Oracle, enz.)
- Je geeft er de voorkeur aan dat de CMS een aparte, onafhankelijke service is
Als je deze opties weegt voor een headless-project en je wilt een tweede mening, doen we headless CMS-architectuurconsultatie en kunnen we je helpen de juiste tool te kiezen voordat je drie maanden in de verkeerde bent.
Voor projecten die Astro als het frontend-framework gebruiken, past Directus's zelfstandige API-benadering natuurlijk, aangezien Astro gegevens bij het bouwen ophaalt of via server-eindpunten. Payload werkt ook, maar je verliest het Local API-voordeel aangezien Astro en Payload aparte processen zouden zijn.
Veelgestelde vragen
Is Payload CMS echt gratis in 2026? Ja. Payload CMS is MIT-gelicentieerd en volledig gratis om zelf te hosten. Payload Cloud is hun betaalde beheerde hosting-service, maar de CMS zelf — inclusief alle kernfunctie — is open-source. Er zijn geen functiepoorten op de zelf gehoste versie.
Kan Directus werken met een bestaande database zonder deze te wijzigen?
Meestal ja. Directus kan een bestaande database introspectteren en een beheerlaag erop maken. Het voegt enkele systeemtabellen toe (voorafgegaan door directus_) voor zijn eigen configuratie, maar het wijzigt je bestaande tabellen niet. Dit is een van zijn sterkste onderscheidende kenmerken.
Welke is beter voor een solo-ontwikkelaar? Payload CMS is meestal de favoriet van solo-ontwikkelaars die vertrouwd zijn met TypeScript. De code-first-workflow betekent dat je verzamelingen snel kunt opzetten, en de automatisch gegenereerde typen verminderen boilerplate. Directus is beter als je een visuele interface wilt voor snelle schemaprototyping zonder configuratiebestanden te schrijven.
Kan ik Payload CMS zonder Next.js gebruiken? Vanaf Payload 3.x is Next.js de primaire adapter en draait het admin-panel op Next.js. De REST- en GraphQL-API's werken echter met elke frontend. Je bent niet vergrendeld in Next.js voor je consumentengerichte site — je hebt gewoon Next.js nodig om het Payload-beheer uit te voeren. Er zijn community-discussies geweest over aanvullende adapters (zoals Nuxt), maar niets officieel nog.
Hoe gaat Directus om met inhoudslocalisatie?
Directus ondersteunt veld-niveau vertalingen. Je markeert velden als vertaalbaar, configureert je talen, en Directus verwerkt het opslaan van vertalingen in een gerelateerde tabel. De API laat je inhoud in specifieke talen aanvragen via de ?fields- en taalparameters. Het is goed geïmplementeerd en is al jaren stabiel.
Welke heeft betere plugin/extensieondersteuning? Directus heeft een grotere extensiemarketplace, vooral met de Directus+ toevoegingen. Je kunt aangepaste interfaces, displays, eindpunten, hooks en modules bouwen. Payloads extensiemodel is gebaseerd op React-componentoverschrijvingen en plug-ins — het is krachtig maar het ecosysteem is kleiner. Payloads plug-ins zijn meestal meer gericht (SEO-plug-in, formulairenbouwer, omleidingen) terwijl Directus-extensies een breder bereik hebben.
Is er een prestatieverschil voor grote datasets? Voor datasets met miljoenen rijen presteren beide goed als ze correct zijn geïndexeerd. Directus heeft een klein voordeel op ruwe queryflexibiliteit aangezien het SQL directer uit API-vragen genereert. Payloads Drizzle ORM-laag is efficiënt maar voegt een kleine abstractiekosten toe. In de praktijk is je database-afstemming veel belangrijker dan welke CMS je kiest. Beiden ondersteunen verbindingspooling en kunnen met read-replicas werken.
Kan ik later van de ene naar de ander migreren? Je kunt het doen, maar het is niet triviaal. De inhoud zelf (opgeslagen in PostgreSQL voor beiden) kan worden gemigreerd met standaard database-hulpmiddelen. Het moeilijkere deel is het recreëren van je schemadefinities, toegangsbeheersregels en aangepaste logica. Als je voor een headless-architectuur bouwt, het uw frontend gescheiden van CMS-specifieke API's (met een abstractielaag) zal elke toekomstige CMS-migratie aanzienlijk gemakkelijker maken.