Most CMS tools make assumptions I don’t agree with. REST APIs on the write path, tight coupling between storage and delivery, opinionated data models. I wanted something different.
Why write your own?
The honest answer is that I wanted to think hard about event-driven architecture, and a CMS is a good excuse to do it with something real.
Every off-the-shelf CMS I’ve used routes mutations through a synchronous HTTP API. You POST a document, it gets written to the database, you get a 200 back. Simple, but it means the editor and the storage layer are tightly coupled. If you want to add a webhook, a search index update, or a cache invalidation, you’re patching it into the same synchronous path.
The architecture
Conduit routes every mutation through RabbitMQ instead. There is no HTTP write API. Content changes are events.
editor ──→ RabbitMQ ──→ conduit engine ──→ postgres
│
read API (HTTP)
The editor publishes a content.create or content.update message. The engine consumes it, validates it, writes to Postgres, and publishes a content.indexed event. Anything that needs to react to content changes subscribes to that event. The read side is a fast, dumb HTTP query layer. No business logic, no write path.
What this buys you
The editor and the storage engine are completely decoupled. You can swap either without touching the other. The message bus is the contract.
Adding a search indexer is a new consumer, not a patch to the write path. Adding a cache invalidation hook is the same. The core engine doesn’t know or care that these things exist.
Current state
Phase 0 (RabbitMQ connection foundation) is done. Phase 1 is the core content engine: modelling documents, revisions, and publishing state as event streams. It’s slow going because I’m doing this properly.
You can follow the progress in the conduit repo.