DEV Community

Raşit
Raşit

Posted on

Why I Ended Up Building My Own Headless CMS

For almost twenty years, my work revolved around client projects. Every new website, app, or internal tool had one thing in common: I had to build some kind of CMS backend for it.

Sometimes it was custom Laravel panels, sometimes it was WordPress with custom post types, sometimes hybrid setups. Over time, the problems repeated themselves.

Here are the main pain points that pushed me to build my own headless CMS.

1. Every project needed a CMS, but every CMS had to be rebuilt

Even when the requirements were similar, I kept writing the same migrations, controllers, CRUD logic, validation, media handling, user management, and API endpoints.

I tried to template it, but templates always drift. They solve the first few steps but not the ongoing complexity.

I wanted a backend where:

  • projects could be created in minutes
  • collections and fields didn’t require writing migrations
  • APIs were generated automatically
  • I could skip the entire “bootstrap phase” of backend development

2. WordPress and traditional CMSs didn’t fit modern workflows

WordPress can do a lot, but once you’re working with Vue, React, or a custom single page app, the friction grows.

I wanted a backend that didn’t care about what frontend framework I chose.

Use React? Fine.

Use Vue? Fine.

Use Next, Nuxt, Svelte, plain JS, or even mobile apps? Same API.

A single backend powering any frontend with no extra plugins, no weird data structures, no custom routing hacks.

3. Multi project support is rare

Most CMS solutions assume one site per install.

My workflow never worked like that. I often needed:

  • multiple client projects
  • a shared admin user system
  • isolated data per project
  • the ability to quickly create, test, or destroy projects

A multi project architecture was essential for me, and almost no lightweight CMS offered it.

4. I wanted consistency in API design

Every custom API I built had slightly different patterns. Different naming, different filtering operators, different pagination logic.

Over time this creates chaos.

I wanted:

  • consistent REST endpoints
  • predictable filtering and sorting
  • predictable responses
  • token-based access control that didn’t require rewriting policies every time

5. Speed of setup matters

When you work on client projects, the faster you get to “working prototype,” the better.

A backend setup that takes an hour is already too slow.

I wanted something I could install on shared hosting, VPS, or anything that runs PHP, and start building immediately.

After repeating the same frustrations over many years, I started building a tool for myself. It grew, improved, and eventually became ElmapiCMS.

I’ll share more about the architecture and decisions behind it in follow-up posts, but this post captures the core reasons it exists.

Top comments (0)