Skip to content
KHEN / ES
Menu
All posts

Published Sep 25, 2026

Rebuilding kennyhorna.com in about an hour

From idea to a first version in about an hour with AI agents. The polish took longer, and now the whole thing runs on Cloudflare for zero dollars a month.

The first version of this site took about an hour, from “I should redo my website” to something I could click through. I’m not saying that to brag (fine, a little). I’m saying it because the hour is not the interesting part.

What I brought

A brief. Who I am, what I’ve shipped, and how the site should feel: brutalist, light, a bit funny, but still showing results. Three colors. A running joke to hang everything on: every section answers with an HTTP status, my career is a list of database migrations, the side projects are a process table, and the dead ones rest in a cemetery. And a list of things that must never be published, which matters more than it sounds when an agent is doing the typing.

The three colors didn’t survive the week. It started as paper, cacao and ají amarillo, the Peruvian chili. It’s now paper, olive and bubblegum pink. Same energy, fewer people asking if the site is a menu.

What the agents brought

Speed. Astro, Tailwind, two languages with their own URLs, SEO, structured data, RSS, and a hidden kitchen behind the Konami code. My favorite part is the portrait: a script cuts me out of a photo with Apple’s Vision framework, and the build bakes it twice, once as a three-color dither and once as a smooth duotone. In your browser, a band of live ASCII sweeps across it and swaps one for the other.

I didn’t write most of that code. I reviewed it, argued with it, and decided what stayed.

Then the polish, which took a lot longer

An hour gets you a first version. Then you open it on your phone.

  • A case study title, INTEGRATIONS, was wider than the screen and dragged the whole page sideways. Fifteen pages had the same problem.
  • The career timeline had an animation that waited until 35% of the list was on screen. On a small phone the list is so tall that it never happens, so every job stayed PENDING forever. Very on brand for a migration, less so for a CV.
  • The two buttons in the header had different heights. Nobody would have noticed. I noticed.
  • The menu said HELLO for the page about me, which sounded odd. It says ABOUT now.

None of that is hard. It’s the work that only shows up when a person actually uses the thing, and that part is still mine.

I also brought back the best of my old blog: six agents in parallel, each migrating a post, each dropping the screenshots that showed a real server IP or a password, and one of them politely pointing out that a naming convention I published in 2020 was wrong. (It was. Pivot tables go in alphabetical order.)

Where it lives: Cloudflare, for zero dollars

The old kennyhorna.com was a Laravel app on a server. By the time I moved the domain, that server was answering every request with a 525. On theme, sure, but not the status I’d pick for a homepage.

The new one is a folder of static files, and Cloudflare runs all of it on the free plan:

  • Hosting. The files are served from Cloudflare’s network, from whichever city is closest to you. There’s no server, no code running on each request, and nothing to patch at 2 a.m.
  • Deploys. I push to main, Cloudflare builds the site and puts it live a few minutes later. The free plan includes 3,000 build minutes a month. I use about four.
  • Caching. Every file the build fingerprints is cached for a year. HTML is checked on every visit, so a deploy shows up right away. No cache to purge, no “have you tried a hard refresh?”.
  • Security. HTTPS everywhere, TLS 1.2 at minimum, and no database, admin panel or login to break into. The attack surface is a folder of HTML.
  • The domain. I moved the registration from Namecheap to Cloudflare, which sells domains at cost. The service has been great so far, and so has their customer support. The domain is now the only line on the bill, once a year.
  • Email. hello@kennyhorna.com and hola@kennyhorna.com have no mailboxes behind them. Email Routing forwards both to my personal inbox. My Google Workspace accounts used to go through Namecheap, and in my experience changing the number of seats was a small adventure every single time. Now there are no seats to change. That’s a Workspace bill I’m not paying, every month, forever. Replies arrive at the same speed as before, which is to say “eventually”.

I’m moving the rest of my domains away from Namecheap the same way, one at a time. Yes, like migrations.

This is the entire hosting setup:

wrangler.jsonc
{
"name": "kennyhorna",
"compatibility_date": "2026-09-25",
"assets": {
"directory": "./dist",
"html_handling": "auto-trailing-slash",
"not_found_handling": "404-page"
},
"routes": [
{ "pattern": "kennyhorna.com", "custom_domain": true },
{ "pattern": "www.kennyhorna.com", "custom_domain": true }
]
}

Is a global edge network overkill for a site with fewer than 50 visits a month? Completely. Cloudflare could serve this site’s entire monthly audience before you finish this sentence. Hi, by the way. You’re in it.

The stack, this week

The agents are Claude Code and Codex, with fal and ElevenLabs for images and audio. Solo runs them, along with the dev servers and the to-do lists they share. A knowledge graph of the repo saves them from rereading everything on every task.

I don’t list models. By the time you read this, a newer one is out, and my agent will still insist its own is the latest. I pick the tools when a project starts, based on what’s actually best for it that month.

What I take from it

AI shrinks the gap between an idea and a first version to almost nothing. That doesn’t make the decisions go away. It makes them the whole job: what to build, what to cut, and when it’s good enough to ship. The hour was the agents. The taste, and the phone in my hand, were mine. And the monthly bill, for once, is nobody’s.