Do you need a CMS? How I decide
Markdown files, a headless CMS, or a database. Where your content should live depends on one question: who edits it, and how often?
Every project has content, and that content has to live somewhere. Clients often assume they need a CMS because that's what websites have. Developers often assume they need one because that's what tutorials use. Both assumptions cost money. The real question is simpler: who edits this content, and how often?
Files in the repo: the default
If the developer is the only person editing, content belongs in the repository. Markdown or MDX files, typed data in TypeScript, images in the public folder. This blog works exactly that way:
src/
content/posts/*.mdx (one file per post)
data/projects.ts (typed project content)
The benefits are hard to beat. Content is versioned with the code, so every change has a diff and a rollback. There's no external service to pay for, secure, or watch go down. And because the content is available at build time, every page can be fully static.
// gray-matter reads frontmatter straight from the filesystem
const posts = fs.readdirSync("src/content/posts")
.map((file) => matter.read(`src/content/posts/${file}`));The cost is that editing requires a code editor and a deploy. For a developer, that's no cost at all. For a client, it's a dealbreaker.
Headless CMS: when the client edits
The moment a non-developer needs to change copy, publish articles, or swap images, a headless CMS earns its place. Sanity, Contentful, Payload, Strapi: the differences matter less than the shape they share. Content lives in a hosted editor, and the site fetches it through an API at build time or on request.
// Fetch at build time, revalidate hourly
const page = await client.fetch(query, params, {
next: { revalidate: 3600 },
});Two warnings from experience. First, model the content around what the client actually edits, not around what the CMS can do. Five well-named fields beat a flexible page builder that produces broken layouts. Second, the CMS is a monthly cost and a dependency. Put that in the quote, because the client pays it long after launch.
A database: when content is data
Some content isn't really content. Product inventory, bookings, user accounts, anything with quantities and relations: that's application data, and it belongs in a database with proper constraints, not in a CMS designed for marketing pages.
The tell is the shape of the editing. If changes come from application logic (an order reduces stock, a booking blocks a slot), it's a database. If changes come from a person typing in a text field, it's content.
The decision in one question
Who edits this, and how often?
Only the developer → files in the repo. A client, on their own schedule → headless CMS. The application itself → database.
Most small business sites answer "the developer, twice a year". Those projects don't need a CMS; they need an honest developer who doesn't sell them one. The CMS is for the projects where the client publishing independently is the point.
Got a project in mind?
I build fast, production-grade sites for freelance clients. Let’s talk.