Skip to content

4 min read

Cheap enough to be custom

Why I relaunched this site around an AI-first way of building, and why this post doesn't use the blog template.

This website is my playground. I try out new technology on it, host the tools I use myself, and share some of what I do: posts, hot sauces and the books I'm reading.

Until now it ran on Payload, a headless CMS. That was far more than a personal blog needs. I picked it because I wanted to get to know Payload. The site also had one blog template. Every post got the same title block, the same column of text, the same footer. Anything else cost too much. A custom page for a single post took a week of evenings, for something most people read once.

That math has changed. Coding agents now write most of my code. The part that used to take longest was turning an idea into a page that works on every screen, and that part got cheaper by orders of magnitude. This relaunch is the next experiment. It tests what follows from that. If a page costs half an hour instead of a week, does a blog still need a template? Or can every post be its own small website, built around what it has to say?

This post is the first one built that way. To see how far the idea goes, each of its six chapters gets a design of its own.

the-old-math.sheet

01The old math

For as long as I've built websites, implementation was the expensive part. You could sketch a page in an afternoon. Making it responsive, accessible, fast and the same in every browser took a week. So we built templates. You paid that cost once and poured every post into the same mould. Nobody wanted a template for its own sake. It kept the work within budget.

With an agent writing the code, that budget changed. I still decide what a page should do and how it should look, and I still judge whether the result is any good. But the time between that decision and a working page shrank from days to under an hour.

The whole relaunch, from the first commit to the last one before this post, took two days. Most of that time went into looking at screenshots and deciding what to change next.

One custom page, before30 h1 every 3 months
One custom page, now0.5 h20 a month

My Blog

Just another blog

A template is a compromise

Posted on October 8, 2026 by admin in Uncategorized

A template answers "what does a post look like?" once, for every post. That's efficient, and it's why most blogs look the same. A post about animation can't use animation to make its point. A post about hot sauce looks exactly like a post about type systems. The writing has to fit the layout, and the layout never changes for the writing.

When building is cheap, that trade-off stops being worth it. The layout can follow the story instead. Here, the old math runs in a spreadsheet, the chapter about editing is a book, and this one sits in the theme it argues against. None of the visuals on this page exist anywhere else on the site, and none of them had to be general enough for the next post.

cheap-enough-to-be-custom · editor

index.mdx

---title: "Cheap enough to be custom"description: >-  Why I relaunched this site around an AI-first way of building, and why  this post doesn't use the blog template.publishedAt: 2026-10-08tags: [meta, ai, design]layout: customart: { ink: red }--- import { Book } from "./book";import { chapters } from "./chapters";import { Editor } from "./editor";import { Flyer } from "./flyer";import { Hero } from "./hero";import { Lead } from "./lead";import { Proofs } from "./proofs";import { Till } from "./receipt";import { Sheet } from "./sheet";import { Story } from "./story";import { Theme } from "./theme"; <Story> <Hero post={props.post} minutes={props.minutes} /> <Lead title={props.post.data.title}> This website is my playground. I try out new technology on it, host the [tools](/tool-box) I use myself, and share some of what I do: posts, [hot sauces](/chili-corner) and the [books](/book-shelf) I'm reading. Until now it ran on [Payload](https://payloadcms.com), a headless CMS. That was far more than a personal blog needs. I picked it because I wanted to get to know Payload. The site also had one blog template. Every post got the same title block, the same column of text, the same footer. Anything else cost too much. A custom page for a single post took a week of evenings, for something most people read once. That math has changed. Coding agents now write most of my code. The part that used to take longest was turning an idea into a page that works on every screen, and that part got cheaper by orders of magnitude. This relaunch is the next experiment. It tests what follows from that. If a page costs half an hour instead of a week, does a blog still need a template? Or can every post be its own small website, built around what it has to say? This post is the first one built that way. To see how far the idea goes, each of its six chapters gets a design of its own. </Lead> <Sheet {...chapters[0]}> For as long as I've built websites, implementation was the expensive part. You could sketch a page in an afternoon. Making it responsive, accessible, fast and the same in every browser took a week. So we built templates. You paid that cost once and poured every post into the same mould. Nobody wanted a template for its own sake. It kept the work within budget. With an agent writing the code, that budget changed. I still decide what a page should do and how it should look, and I still judge whether the result is any good. But the time between that decision and a working page shrank from days to under an hour. The whole relaunch, from the first commit to the last one before this post, took two days. Most of that time went into looking at screenshots and deciding what to change next. </Sheet> <Theme {...chapters[1]} postTitle={props.post.data.title}> A template answers "what does a post look like?" once, for every post. That's efficient, and it's why most blogs look the same. A post about animation can't use animation to make its point. A post about hot sauce looks exactly like a post about type systems. The writing has to fit the layout, and the layout never changes for the writing. When building is cheap, that trade-off stops being worth it. The layout can follow the story instead. Here, the old math runs in a spreadsheet, the chapter about editing is a book, and this one sits in the theme it argues against. None of the visuals on this page exist anywhere else on the site, and none of them had to be general enough for the next post. </Theme> <Editor {...chapters[2]} post={props.post}> I didn't go all the way to hand-built pages, though. The words still live in a text file, `index.mdx`, right next to the code that lays them out. Text diffs cleanly and survives redesigns, and it's the format an agent reads and edits most reliably. What changed is the code next to it. The components in this folder belong to this post. Nothing else on the site imports them, so they can be as specific as the story needs. I'm not fully happy with that split yet. MDX still assumes one column of prose. To get around that, every chapter in this post is a component wrapped around a bit of Markdown. If the experiment works out, the words might move into plain data, and each post would become a small app that renders them. The editor here shows that folder as it was when this page was built. </Editor> <Book {...chapters[3]} number="Four" book={props.post.data.title} after={<Proofs />}> My part of the relaunch looked a lot like an editor's. I described what I wanted, looked at the result, and marked it up. Most features on this site started as a single sentence typed into a chat, and most of the work was deciding what to say next. That changes which skills matter. Typing speed and knowing every API by heart matter less. Knowing what you want matters more, and so does noticing when something is off and saying why. This post went through the same process. Here is its first draft, marked up: </Book> <Till {...chapters[4]}> Cheap to build doesn't mean cheap to maintain. Every custom post is code that has to keep building next year, and still work on a phone, in dark mode, with reduced motion and with a screen reader. A template gets those right once. A custom page has to get them right every time. So the agent works under rules. It reads a written brief in the repository before every change, and every change has to pass the checks on this receipt before it ships. I don't know yet whether that holds up over a few dozen posts. Finding out is the experiment. </Till> <Flyer {...chapters[5]}> Older posts keep their print runs, with an ink and an opening chosen per post on a shared layout. That's still a template, just a looser one, and for plenty of writing it's the right one. New posts get a site of their own when the story needs one, and the plain layout when it doesn't. If you want to see where this goes, the newsletter sends a short note when the next one is out. </Flyer> </Story>

MDX · UTF-8 · 92 lines92 lines of words, 2021 lines of design

Preview

Words stay in text

I didn't go all the way to hand-built pages, though. The words still live in a text file, index.mdx, right next to the code that lays them out. Text diffs cleanly and survives redesigns, and it's the format an agent reads and edits most reliably. What changed is the code next to it. The components in this folder belong to this post. Nothing else on the site imports them, so they can be as specific as the story needs.

I'm not fully happy with that split yet. MDX still assumes one column of prose. To get around that, every chapter in this post is a component wrapped around a bit of Markdown. If the experiment works out, the words might move into plain data, and each post would become a small app that renders them.

The editor here shows that folder as it was when this page was built.

Chapter Four

I mark up, the agent typesets

My part of the relaunch looked a lot like an editor's. I described what I wanted, looked at the result, and marked it up. Most features on this site started as a single sentence typed into a chat, and most of the work was deciding what to say next.

That changes which skills matter. Typing speed and knowing every API by heart matter less. Knowing what you want matters more, and so does noticing when something is off and saying why. This post went through the same process. Here is its first draft, marked up:

Galley proof · cheap-enough-to-be-custom

  1. deleted: Relaunch: content as code inserted: Cheap enough to be custom

  2. Why deleted: this site dropped its CMS for MDX files in git inserted: I relaunched this site around an AI-first way of building, and deleted: how every post can now bring its own design inserted: why this post doesn't use the blog template.

  3. deleted: For the last two years this site inserted: Until now it ran on inserted: Payload, a headless CMS.

  4. It worked, but every design idea had to squeeze through a fixed set of content blocks.

  5. The relaunch turns that around: deleted: content is code inserted: every post can be its own site.

The first draft of this post, marked up into the one you're reading.

kalleott.de

Relaunch

06.10.2026 08:58 → 07.10.2026 17:04

Commits
36
Files changed
595
Lines added
35,212
Lines removed
38,633
Posts imported
21
Hot sauces
13
Tools
10
Templates for this post
0
First → last commit32 h

*** What it costs ***

Cheap to build doesn't mean cheap to maintain. Every custom post is code that has to keep building next year, and still work on a phone, in dark mode, with reduced motion and with a screen reader. A template gets those right once. A custom page has to get them right every time.

So the agent works under rules. It reads a written brief in the repository before every change, and every change has to pass the checks on this receipt before it ships. I don't know yet whether that holds up over a few dozen posts. Finding out is the experiment.

Due on every change

Brief
AGENTS.md, passes
Content
pnpm content:check, passes
Code
pnpm check, passes
Looks
pnpm screenshot, passes
Moving parts
rendered offscreen, passes
Flows
pnpm e2e, passes
Database
migration guard, passes
TotalAll checks green

Typeset by Claude Code · Edited by Kalle Ott

*** Thank you ***

What's next

Older posts keep their print runs, with an ink and an opening chosen per post on a shared layout. That's still a template, just a looser one, and for plenty of writing it's the right one. New posts get a site of their own when the story needs one, and the plain layout when it doesn't.

If you want to see where this goes, the newsletter sends a short note when the next one is out.