I built a CMS this morning. The whole thing. Architecture, manifesto, deployment, first post — between coffee and lunch, in Phoenix, Arizona.

It started with a simple observation: the browser is for consuming. Not creating. Every CMS from WordPress to Ghost to Substack puts the editor in the browser. But authoring left the browser years ago. It moved to Apple Notes, to Obsidian, to Bear, to whatever app you think in. The browser didn’t earn the right to be your editor. It earned the right to render beautifully.

So I built note2cms.

What It Is

Four API endpoints. That’s the whole CMS.

You push Markdown — from curl, from an iOS Shortcut, from an Android share intent, from wherever. Two pipelines fire in parallel: one builds a static HTML page with beautiful typography, the other updates a lightweight taxonomy database. You get a permalink back. Share it with the world.

That’s the entire publishing flow. No admin panel. No login screen. No rich text editor that fights you. No draft state management. No plugin ecosystem. No theme marketplace. No monthly fee.

What Died So This Could Live

Static site generators have existed since the stone age. Hugo, Jekyll, Gatsby — they all rebuild your entire blog every time you fix a typo. Five hundred posts? Rebuild all five hundred. That’s not architecture, that’s a lack of it.

note2cms builds one post when you publish one post. O(1). The other four hundred ninety-nine posts sitting in static HTML are untouched. Their cache headers stay valid. Their directories don’t get rewritten.

The reason nobody built this before is historical. When static generators were being designed, CI/CD was practically nonexistent. To trigger a build, you sat at a desktop and ran a command. Nobody would trigger two parallel builder pipelines in the cloud, performed by absolutely headless stateless workers. The workers that built this post you’re reading will be dead and replaced by the time I write the next one.

Times changed. The tools caught up. The CMS paradigm didn’t.

The Architecture

The FastAPI process is the only living thing, and its job is tiny — authenticate, accept, dispatch, respond. It’s a valve. Everything upstream is your notes app. Everything downstream is static HTML on a CDN. The dynamic surface area is four endpoints and a PostgreSQL table. That’s the smallest possible living footprint for a publishing system that can receive input.

A theme is two files. A React component for the post page, a React component for the index page. They share one CSS file. That’s the entire theming API. Want to change your blog’s visual identity? Replace two files. A bootcamp grad can build a production theme in an afternoon.

The Markdown files are the system of record. The database is derived. The static HTML is derived. Delete everything except the Markdown, run one rebuild script, and the entire blog reconstructs itself in seconds. Your words are the only thing that matters. Your words are the only thing that survives.

The Deployment

This blog runs on Leapcell’s free tier for the Python runtime and GitHub Pages for the static output. The PostgreSQL database is free. The CDN is free. The SSL is free.

Total cost of this entire publishing infrastructure: a domain name. Twelve dollars a year.

How We Built It

Here’s the part that’s hard to believe: we built this entire system in one morning. Architected it in conversation, coded it in a sandbox, pushed it blind to GitHub, deployed it to cloud infrastructure we’d never configured before, and debugged the production issues live — PgBouncer connection pooling, async database drivers, read-only filesystems — with real curl commands against the real endpoint.

No local staging environment. No Docker compose dry run. No “let me set up a test instance first.” Straight to production, fix forward, ship it.

The development workflow matched the product philosophy. No ceremony. No unnecessary infrastructure. Just push and it’s there.

The Thesis

Modern developers forgot that the complexity of frameworks and workflows was born out of necessity. These tools were solving problems as it was possible at the time. With stateless worker pipelines today, layers of that complexity can be discarded for good — if you think creatively first.

In the end there will be a new thinking paradigm: what in your framework actually serves the result to the intended recipient, and what is just builder toolkit that’s not needed once the job is done — but somehow it persists, it’s heavyweight, and its burly silhouette deters junior developers from the craft of building things.

note2cms is open source. Self-hosted. Four endpoints. Your words, your server, your domain, nobody’s platform.

You are not gifting your writings to some dirty SaaS. You own it.


Write where you think. Publish where they look. Own everything in between.