Why your CMS schema should live in code, not a GUI
Most headless CMSes let you define your content structure by clicking buttons in a dashboard. That feels fast — until you need to review a change, roll it back, or onboard a new engineer.
Priya M.
Engineering
Most headless CMSes let you define your content structure by clicking buttons in a dashboard. That feels fast — until you need to review a change, roll it back, or onboard a new engineer who has no idea why a field exists.
The GUI schema problem
When your schema lives in a database, it is invisible to your version control. You can't see the diff when someone renames a field. You can't review it in a pull request. You can't roll it back without writing a migration by hand. And when something breaks in production, you're squinting at a timestamp in the CMS audit log trying to figure out what changed.
This is the standard experience with most popular headless CMSes — Contentful, Sanity, even Strapi's older GUI mode. The schema is stored as data, not code.
Code as the source of truth
When the schema is a TypeScript config file that lives in your repository, all of that changes.
Every field definition, validation rule, and access control policy is a line of code. You commit it. You review it. You diff it. If you rename a field from `body` to `content`, the change appears in your pull request like any other change. A reviewer can catch it before it ships.
defineCollection({
slug: 'posts',
fields: [
{ name: 'title', type: 'text', required: true },
{ name: 'content', type: 'richText' }, // renamed from 'body'
{ name: 'status', type: 'select', options: ['draft', 'published'] },
],
})Type safety as a side effect
When the schema is code, generating types from it is trivial. Dyrected generates TypeScript types from your collection definitions — which means your editor knows what fields exist, what types they are, and when you're querying something that doesn't exist.
No more `doc.body as string`. No more runtime surprises when a field was renamed six months ago and nobody updated the frontend.
What this looks like in practice
The workflow looks like this: you open your config file, add a field, commit the change, open a pull request. Your teammate reviews it. It merges. Dyrected picks up the schema change and updates the admin UI and the database automatically.
No separate migration step. No clicking through a dashboard. No schema state that exists somewhere outside your repo.
The tradeoff
The obvious tradeoff is that non-technical teammates can't change the schema themselves. A content editor can't add a new field by clicking a button.
But that's the point. Schema changes are engineering decisions. They affect the database, the API, the frontend, and the types. They deserve a code review. Content editors should own the *content inside the structure* — not the structure itself.
Dyrected draws that line explicitly: engineering defines the schema in code, marketing and content teams edit what's inside it. Clear separation. No surprises.
Try Dyrected free
Self-host free or start a cloud trial. No credit card required.