Backend Architecture

Boring Technology Scales: Choosing PHP 8 Over Node.js for a Headless CMS

TL;DR: We evaluated Node.js ecosystems (Prisma, TypeORM) but found they struggle violently with dynamic polymorphism. We chose Laravel and PHP 8 to get a mature ORM and a "batteries included" enterprise ecosystem. 

The JavaScript Obsession 

The headless CMS space is completely saturated with Node.js and React. If you want funding right now, you build your backend in TypeScript. When we started StakCMS, we looked closely at Prisma and TypeORM.

We rejected them. We chose PHP 8 and Laravel instead.

The ORM Dealbreaker

Here is the honest reason: Prisma struggles violently with deeply nested polymorphic mutations. Our ContentBlock architecture relies entirely on dynamic polymorphism to link structured JSON schemas to arbitrary pages. Doing this in Node often forces you down into raw SQL to avoid massive N+1 bottlenecks.

Laravel’s Eloquent ORM handles polymorphic relationships flawlessly out of the box. More importantly, we didn’t want to spend our first six months stitching together a franken-stack of express, bullmq, multer, and nodemailer.

Batteries Included

Laravel gives us a battle-tested queue (Illuminate\Queue) and filesystem abstraction (Illuminate\Filesystem) by default. We didn't have to reinvent background jobs; we just wrote them.

Does Node have better cold-start times for serverless edge functions? Yes. But for a stateful CMS application processing thousands of concurrent API reads and queued webhook dispatches, PHP 8 with OPcache and Laravel Octane easily competes with Express, and gives us a significantly more resilient data model.

Summary: Choosing PHP 8 and Laravel wasn't a nostalgic choice; it was a pragmatic engineering decision to leverage the most mature ORM and ecosystem available for complex relational applications.
Tags
PHP 8 vs Node.js
Laravel vs Express
Prisma polymorphic relations
Eloquent ORM
headless CMS backend
backend architecture
Share