← Back to Blog

Building a CMS from Scratch in 2026

Why Another CMS?

I've been building websites since 1995. I've used Drupal, WordPress, Joomla, custom PHP systems, and even built a CMS called ODEUM back in the early 2000s. Every single one eventually hit a wall — either too opinionated about the frontend, too complex for simple sites, or too simple for complex ones.

In 2026, with AI as a development partner, I realized I could build the CMS I always wanted. Not a page builder. Not a monolithic platform. A headless, plugin-based content engine that an AI agent could understand, extend, and build sites with.

The Architecture

@webhouse/cms is a pnpm monorepo with 8 publishable npm packages:

- cms — the core engine with collection definitions, field types, and storage adapters
- cms-admin — a Next.js admin UI with rich text editing, media management, and AI assistance
- cms-ai — AI agents that can generate content, optimize SEO, and scaffold entire sites
- cms-cli — command-line tools for building and deploying
- cms-mcp-server — Model Context Protocol server so AI assistants can manage content directly

The key design decision was storage adapters. The same CMS config works with a filesystem adapter (JSON files in a content/ directory) or a GitHub adapter (content lives in a repo, changes go through PRs). This means a developer can start locally and move to GitHub-backed content without changing their schema.

> "The architecture you'll be proud of in five years is the one that was obvious to understand on day one."

What 30 Years Taught Me

The biggest lesson from three decades of CMS work: content modeling is the hard part. Not routing, not rendering, not auth. Getting the data model right — the collections, the field types, the relationships — determines whether the system scales or collapses under its own weight.

That's why @webhouse/cms starts with defineConfig and defineCollection. Everything flows from the schema. The admin UI, the API, the build output — all generated from the same source of truth. It's the pattern I wish every CMS I used in the past had followed.