I built an open-source CMS for agencies in two months, with AI agents
Our clients kept asking if they could change their website content after launch. So I built Areca CMS, an open-source CMS for agencies, in my free time over two months, with AI agents writing most of the code. Here is what it does, how it was built, and what I learned.
7 min read
"Can we add content later, or change things ourselves?"
At MINIMA we hear that question on almost every project. A client wants to post news, add a vacancy, or fix a typo on the team page, long after we hand the site over. We build every site in code with TanStack Start, so every one of those changes used to land on our desk as a small code change.
Friends I built sites for asked the same thing. So I built the thing I kept wishing we had: Areca CMS, an open-source CMS for agencies that run many client websites. I built it alone, in my free time after work, over about two months. Most of the code was written by AI agents. I wrote the specs, reviewed everything, and tested it.
It is MIT licensed, self-hosted, and early (v0.x). You can try the live demo or read the code on GitHub.
The problem
Most headless CMSs are built for one company with one website. An agency has the opposite shape: dozens of clients, each with a site or two, and each with people who should only ever see their own content.
What we needed:
- One installation for all our clients, with roles per client (owners and editors) and an agency view across everything.
- An editor simple enough for a client who has never heard the word "headless".
- An approval step, so a client can draft, someone approves, and only then does it go live.
- Fast static sites that never call the CMS at runtime, so a CMS outage can never take a client site down.
- First-class TanStack Start support, because that is what we build everything with.
- Content on our own servers.
Why not Payload, Sanity, Strapi or Directus?
These are all good tools, and I looked at each of them. They just did not fit how we work.
- Payload is MIT licensed and has a multi-tenant plugin, but since version 3 it runs inside a Next.js app. We do not use Next.js. Everything we build is TanStack, and I did not want a second framework to maintain for every client.
- Sanity is hosted. Every client editor is a paid seat (about $15 per seat per month on the Growth plan), the content lives in their cloud instead of on our servers, and single sign-on is an Enterprise feature. For an agency with many small clients that adds up fast.
- Strapi is free to self-host, but there is no built-in multi-tenancy, so you end up running one instance per client. Review workflows and SSO are paid features.
- Directus is a great data platform, but it is source-available rather than open source, and it is a database UI more than an editor. Our clients need a simple write, approve, publish flow.
What Areca CMS does
Built for agencies. One installation holds all your clients. Each client gets its own sites, owners and editors. Agency admins see everything, and you can put your own branding on the CMS.
A visual editor. Clients edit next to a live preview of their real site, and can click any part of the page to jump to its field.
A safe publishing flow. Editors write drafts, owners mark them ready, and Go live freezes the approved content into a snapshot and builds the site. The website pulls that snapshot during its build, so visitors get static pages and never touch the CMS. Releases have history, rollback and health checks. A failed deploy never replaces the live site.
SEO and AI answers built in. Every entry has search, social and structured-data fields, with optional AI suggestions through OpenRouter.
Made for AI. Every site has its own MCP server. Claude, ChatGPT, Cursor and other AI apps can write drafts with exactly the same permissions as the person who connected them. An AI can draft, but it cannot skip the approval step unless you let it.
And the rest: multilingual content, rich text with code blocks, a media library, site-wide content such as company info, scheduling, deploy adapters for Dokploy and Cloudflare, a throwaway development environment per site, two-factor authentication, and Google and Microsoft sign-in.
Built on TanStack
The CMS, the docs site and the landing page are all TanStack Start apps. Areca uses TanStack Start, Router and Query throughout, and TanStack AI for the AI features. While building, the agents loaded the TanStack libraries' own skills through TanStack Intent, which helped a lot with getting the newest APIs right.
On the website side, you describe your content in areca.config.ts:
import { defineSiteContent } from '@areca-cms/site-sdk'
export default defineSiteContent({
siteKey: 'my-client-site',
collections: {
posts: {
label: 'Posts',
route: '/posts/$slug',
fields: [
{ key: 'title', label: 'Title', type: 'text', required: true },
{ key: 'slug', label: 'Slug', type: 'slug', required: true },
{ key: 'body', label: 'Body', type: 'richtext', required: true },
],
},
},
})Then areca pull writes the published content and generated types into your project during the build, so every collection is typed from the schema all the way to the page. If you use an AI coding agent, npx @areca-cms/skills teaches it to wire up a new site for you.
How I built it with AI agents
This project was also an experiment. I wanted to see how large a system one person can build and maintain with today's AI tools, and whether that could be useful for our company and for the wider community.
The tools: Claude Code, Codex, Cursor, T3 Code and Claude Design. My role was everything except most of the typing: writing specs, reviewing, testing, and deciding.
The numbers, from 7 September to 6 November 2026:
- 589 commits and 120 merged pull requests
- About 233,000 lines of TypeScript
- 387 test files, 40 of them end-to-end browser tests
- About 4.2 billion tokens across all tools (97% of that is the model re-reading cached context)
- Around $500 to $650 if I had paid API prices. I paid for three $20 a month subscriptions: Claude, Codex and Cursor.
What did not work at first
Two problems showed up early.
Agents did whatever they wanted with the UI. I wanted a premium, smooth experience, and an agent left alone will happily invent its own spacing, colours and interactions. Every feature looked a little different.
Agents said they were done when they were not. Missed edge cases, half-finished features, missing options, and now and then a potential security hole. The agent sincerely believed the job was finished.
The workflow that fixed it
Over time this became the process for every feature:
- Grill first. Before any code, an agent interviews me about the feature, question by question, until we agree on every decision. That becomes a written spec.
- Build. Claude Opus 5.5 is the main developer agent and works from the spec.
- Show me. Every change comes with a temporary preview URL and screenshots, so I can check it myself before the agent continues. Nothing moves on until I have seen it.
- Prove it. Every change needs the full test suite to pass, plus end-to-end tests for new behaviour. Agents also open the app in a headless browser and click through the feature, to check that someone new would understand what was built.
- Cross-model review. When the developer agent thinks it is done, a different model reviews everything with fresh eyes: Codex with GPT 6.1 Sol. It reports issues ranked from Nitpick through Low, Medium and High to Critical.
- Verify the review. Reviewers also hallucinate, so two more agents (Grok 4.6 and another Opus 5.5) check each finding: is this a real problem, or something that is impossible to hit in the real world? They return a summary with action points: what to fix, how, why, and how important it is.
- I decide. I pick the findings that actually matter for the project, and the developer agent fixes those.
The review step caught a lot. Before it, features shipped incomplete or with clumsy UX. After it, most of what reached me was already solid, and my time went into product decisions instead of bug hunting.
What I took away
- The bottleneck moves from writing code to deciding what to build and checking that it is right. Specs and review are now the main work.
- Never trust "done". Make the agent show proof: screenshots, a preview URL, passing tests, a browser walkthrough.
- A second model is a much better reviewer than the model that wrote the code. A third check on the review keeps the noise down.
- Context is everything. Short specs, clear rules in the repo, and skills for the agents mattered more than which model I used.
Status and what is next
Areca CMS is early, version 0.x. It is running for real sites, but expect rough edges. Next on my list are more deploy targets, more content field types, and smoothing everything the first users run into.
If you build sites for clients, especially with TanStack Start, I would love your feedback. Try the live demo, read the docs, or open an issue on GitHub.
A small proof that the AI part works: Claude wrote this article straight into my own Areca CMS through its MCP server, as a draft. I then reviewed it, edited it, and pressed Go live myself. Also, my whole personal site and blog uses a self-hosted Areca CMS instance, so this is all in production.
Frequently asked questions
Why not use Payload, Sanity, Strapi or Directus?
Payload runs inside a Next.js app and we build everything with TanStack. Sanity charges per editor seat and hosts the content in its cloud. Strapi has no built-in multi-tenancy and puts review workflows and SSO behind paid plans. Directus is source-available rather than open source and is more a database UI than an editor.
How much did building it with AI agents cost?
About 4.2 billion tokens over two months, mostly cached context. At API prices that would be around $500 to $650, but it ran on three $20 a month subscriptions: Claude, Codex and Cursor.
- Areca CMS
- TanStack
- Open source
- AI
- Claude Code