CyködCyköd
Back to all projects
golambdaaws

Headroom CMS

CMSs and I go way back. I've been working with CMSs or building CMSs for . But there's always been something missing. I've always viewed CMSs as a means to an...

Headroom CMS

CMSs and I go way back. I've been working with CMSs or building CMSs for decades now. But there's always been something missing. I've always viewed CMSs as a means to an end, so I've never been willing to spend the time to put together exactly the perfect CMS for me as always been busy building the things I use the CMSs for.

With the advent of headless CMSs, things got a lot closer. Simple editing interfaces capable of driving complex, custom front-ends became a lot easier without the "Wordpress tax" (or alternatively the SquareSpace tax if you roll that way).

But things were still not perfect. For me, I like to build lots of small custom sites for both clients and myself. Single site open-source headless CMSs that are always out of date, require constant security updates, need deployments for any collection changes and are heavy and costly to host don't cut it. Commercial headless CMSs, well, let's not even get started. Every single one appears to be subject to the forces pushing them upmarket to costly enterprise SaaS licenses. Building a simple site on any one of them, or their free plans feels like a costly time bomb. Adding collaborators generally means you're paying $10-$15 per additional user per month. Which isn't feasible if you want to run 20 small websites.

My headless CMS laundry list is pretty long:

  1. Low to $0 cost at rest
  2. Cheap and fast at scale
  3. Single auth, multi-site capable
  4. Not a glorified blog engine - real, configurable collection models
  5. A modern, block based content editor
  6. Excellent Mobile / Phone editing support.
  7. Capable of adding and configuring sites without deployment
  8. Small server footprint with minimal dependencies
  9. Flexible query support and first-class relationship support.
  10. AI-first - making LLMs first class users of the CMS, especially building front-ends
  11. Multi-user collaborative editing
  12. Support for user accounts and user content
  13. Newsletter support
  14. Extensible plug-ins for the Admin.

The question was, what would a CMS engine like this actually look like in practice and what architectural trade-offs would be needed to make this happen?

The Architecture

Architecture is all about trade-offs, and in this case I knew what I needed and what I didn't need.

I didn't need an enterprise CMS focused on Taxonomy and content scale. The target of Headroom was lots of small sites, generally not updated all that often. The sites themselves might be high traffic.

I didn't need a SaaS platform - I tried that once already - but I wanted something people could easily host and update themselves without a lot of ceremony. This led to one of the most significant decisions: Headroom would be a cloud-based CMS targeted at AWS. Targeting specifically at AWS allowed me to use AWS-specific primitives - Cloudfront, Dynamo, Lambda, S3 - to provide a complete hosting story. Headroom is both cloud-first and cloud-only. It's not something you can run local only nor on a single VPS. Keeping this restriction allows for simpler abstractions and a one-click deploy via SSTv4, while keeping razor focus on a $0-at-rest architecture.

SST has a great dev story - you're still building entirely locally without needing to deploy every change - but you're using real services and resources at almost all times which prevents post-deploy gotchas.

The Build

Using LLM Assisted development, the core Headroom CMS build was done in about a month Feb-Mar 2026. Since then I've been using, extending and tweaking the CMS and making sure it's fit for purpose. I'm building this thing for myself after all, so I want to make sure it works as I'd intended.

The backend consists of a Go lambda connected to Dynamo. The admin UI deploys as a static site on S3/Cloudfront. The content API is all routed through Cloudfront. The media store uses S3 and a Sharp-based lambda for live transformation on the front-end.

The system is intended be used alongside a SSR framework like Next.js or Astro. It's not intended to serve content directly to a front-end. Eventually as Api Keys get more granular permissions it could be used that way, but I've always found that to be a mistake. Content authors shouldn't have to think about what's public and what's private - that's the developers job.

Headroom ships via NPM packages that allow easy backend deployment and the creation of new site. It also ships with a CLI that is designed to be very LLM friendly, allowing LLMs to do anything via the CLI that you could do in the admin.

+--------------------------------------+-------+-------+
| Package / Description                |   LOC | Tests |
+--------------------------------------+-------+-------+
| [Go] api (core Lambda)               | 87031 |  1455 |
|   Handlers, services, repos, DDB/S3  |       |       |
| admin                                | 51820 |  1588 |
|   React admin UI (Vite+shadcn)       |       |       |
| @headroom-cms/api                    |  6440 |   220 |
|   Public TS SDK (client+blocks)      |       |       |
| @headroom-cms/admin-api              |  5871 |   117 |
|   Admin TS SDK (auth+seed)           |       |       |
| @headroom-cms/cli                    |  5064 |   184 |
|   CLI for managing sites             |       |       |
| headroom-cms                         |  3613 |     0 |
|   Packaged CMS distribution          |       |       |
| @headroom/sample-site                |  1776 |     0 |
|   Astro sample site                  |       |       |
| create-headroom-site                 |  1182 |    52 |
|   Scaffold frontend (Astro/Next)     |       |       |
| @headroom-cms/image-lambda           |   940 |    46 |
|   Sharp image-transform Lambda       |       |       |
| create-headroom                      |   327 |     7 |
|   Scaffold a new CMS project         |       |       |
+--------------------------------------+-------+-------+
| TOTAL (13 packages)                  |164958 |  3669 |
+--------------------------------------+-------+-------+

Writing about Headroom in Headroom

The Target

Headroom CMS is targeted at technically competent individuals and small agencies that want a deploy-once backend for small, content driven sites.

Front-end hosting on sites like Vercel or Cloudflare (or straight AWS via SST) is now a low cost commodity, but a stable, fast, cost-efficient backend that can be used universally across many different sites is still a hassle. Each cloud provider has their own custom offerings, and sites like Supabase start at $25/mo for a production database.

Wordpress self-hosting is a cluster**ck - with new vulnerabilities, especially in plugins, requiring constant care and attention. Ghost is great - but it's not headless and wholly blog-centric. If you don't want to go SaaS and want to be in control of your own destiny, you're looking at either entirely static sites or a per-site maintenance burden that tough to swallow.

Headroom addresses all these problems with self-hosted, multi-site CMS that's infinitely scalable to whatever volume of traffic you throw at it.

The Future

Headroom is not "production ready" in the typical sense - I wouldn't use it for a mission critical project. It has a lot of LLM-written code that hasn't been exercised on a real site and so it will be getting updates and tweaks as I run through the gamut of sites I've got in the hopper with it.

As of right now, 12/14 of my bucket list-the remaining big items are to finish newsletter support in a sane way for a headless CMS and to implement the plugin design. I'm holding off on the plugin system until I have a few more real use cases for it. I'll be writing about the importance of each of the bucket list items, why they matter and how Headroom solves them in a novel manner.

My hope is to continue to build and use Headroom over the next 6 or so months to get it into "production" shape and smooth some of the rough edges and then figure out next steps for a commercial push, likely in 2027-ish.

Give it a try

Getting started is as easy as (assuming AWS credentials in your CLI - warning this will deploy to AWS and create a number of cloud resources, but will be $0/mo in actual costs):

npm create headroom my-cms
cd my-cms
npx sst deploy --stage production
./scripts/create-admin.sh admin@example.com 'YourPassword123!'

... and bang! you'll have a working Headroom installation at the Cloudfront URL listed in .sst/outputs.json. Jump into the admin interface, create a site via the UI and then you can create a new headroom site from the command line:

npx create-headroom-site my-site
cd my-site
npx headroom login # login to the admin interface CLI

(You'll need some of your sst details and to create an API Key)

After that, you can fire up Claude or your favorite Coding Agent, and let it go to town. It'll be able to use the CLI to create collections, content, block types, and use the API to integrate that content into your front-end seamlessly. That's how Cykod.com was rebuilt in a day.

The Plan

As odd as it might sound - the plan right now is to keep headroom as a commercial CMS and keep the core go backend code off the internet. Open-source is in a weird space right now, with "clean room" AI-built copies. Source will be available for people who happen to want to purchase a source-available commercial license. Still working on pricing.

It's being released under a PolyForm Noncommercial 1.0.0 license which allows you to use and deploy headroom on your own AWS account with one click. If you want to help me beta-test this thing, feel free to reach out for a free perpetual, commercial license.

If you're interested in partnering to help scale and sell Headroom - please let me know, I'm all ears. In the meantime I'll just be here dog-fooding away.