Prisma + Directus: Version-Controlled Schemas, Seamless Migrations, Reliable Seeds
Seed scripts, schema-as-code, and migrations that just work
Directus excels at turning any SQL database into a headless CMS—but once your project grows, ad-hoc SQL files and one-off dumps become brittle fast. Enter Prisma, a TypeScript ORM that adds order and repeatability to your data layer without getting in Directus's way.
1. The Prisma schema: your single source of truth
model Article {
id Int @id @default(autoincrement())
title String
body String
author User @relation(fields: [authorId], references: [id])
authorId Int
createdAt DateTime @default(now())
}
- Store every table, relationship, index, and enum in one declarative
.prismafile. - Commit it to Git—now the database structure is version-controlled alongside your Directus extensions and UI configs.
- Introspection (
npx prisma db pull) lets you pull existing Directus tables into the schema, so you start with what's already running.
2. Bullet-proof migrations
npx prisma migrate deploy runs the SQL steps generated from your schema differences:
- Consistent: The same migration history runs in dev, staging, and prod.
- Readable: Prisma generates descriptive SQL files (
20250805_add_article_table.sql). - Safe: Preview mode (
migrate diff) shows exactly what will change before you hit the database.
Integrate the command into your CI/CD (e.g., a Railway deploy hook) so the schema evolves automatically when you merge to develop.
3. Seeding for predictable test data
Need demo content for a Directus sandbox or Playwright tests? Create a prisma/seed.ts file:
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
await prisma.user.create({
data: { name: 'John Doe', email: 'john@example.com' }
})
await prisma.article.create({
data: { title: 'Hello Directus', body: 'Prisma FTW', authorId: 1 }
})
Run with npx prisma db seed. Because seeds compile with TypeScript, you can:
- Pull faker data or CSVs.
- Chain API calls to enrich records.
- Re-use the same seed script in Cypress e2e runs or Storybook stories.
4. Playing nicely with Directus
- Directus's data API and role system remain untouched—Prisma simply handles structural drift.
- For custom endpoints/hooks living in
directus-extensions/, swap raw SQL for Prisma Client calls; they stay type-safe and auto-update when fields change. - When you add a new table via Prisma and deploy, Directus instantly detects it and exposes it in the Admin UI.
TL;DR
By treating your schema as code, automating migrations, and scripting seeds, Prisma gives Directus projects the same engineering discipline you expect from application code—without sacrificing the low-code flexibility your content team loves.
Have you paired Prisma with Directus yet? Drop a comment—keen to hear your war stories and wins! 💬