Skip to content

Hello World: How This Site Was Built with AI

How I used Ralph and Claude Code to build this blog in my sleep (literally). Not by handing over the reins, but by directing every design decision and using AI as a force multiplier.

· 6 min read ·

Thanks for joining me on the first post of my blog! Seriously, thanks for stopping by. I wanted to talk about my experience building this site. Mainly because most of it was done in my sleep 😴.

This site was built with Claude Code and the Ralph Wiggum technique. But this wasn’t a case of typing “build me a blog” and walking away. Every page, every design choice, and every piece of content was directed by me. AI was the tool. I was the architect.

The approach: directed autonomy

At its core, ralph is just a bash loop that calls Claude Code’s CLI. What makes it useful is the context engineering. Between each iteration, it manages what context gets carried forward and what gets trimmed, keeping the window clean so Claude doesn’t lose the plot on longer tasks. This is critical because of something called context rot: as an LLM’s context window fills up, performance degrades. The model starts forgetting earlier decisions, responses get more generic, and code quality drops. Ralph sidesteps this by giving each iteration a fresh, focused context with only the information that matters. I’ll dig deeper into context rot and how to work around it in a future post.

You define your project goals and requirements up front, and the loop handles the rest. Loading instructions, running Claude, tracking progress, and deciding when to loop again or stop. AI works best when it has clear direction and can iterate without you babysitting every keystroke.

My workflow looked like this:

  1. Research the stack myself. I already knew Astro was the right choice for a content-heavy personal site. I’d evaluated the landscape (Next.js, Remix, SvelteKit) and Astro’s island architecture was the obvious fit for a site that’s mostly static with a few interactive sprinkles.

  2. Direct the design through targeted research. Rather than asking Claude to “make it look good,” I gave it specific reference points. I spent time browsing sites I liked, including aihero.dev, voidzero.dev, and others I’d found through Awwwards. I fed these to Claude as design references and directed it to merge the influences into something that felt warm and editorial rather than sterile and template-y.

  3. Define the purpose and structure of each page. Before any code was written, I laid out what every page needed to achieve. The bento grid homepage, the interview-driven about page, the portfolio case studies, the contact form. Claude executed against these specs inside the ralph loop.

  4. Iterate through ralph cycles. The loop handled the back-and-forth of implementation. Each cycle would pick up where the last left off, check progress against the requirements, and keep going. The circuit breaker and exit detection meant it wouldn’t spin endlessly. It would stop when the work was actually done. I kicked off the first ralph loop before bed and woke up to a working site. The days that followed were spent directing the design and content through further iterations until it felt right.

The result is a site that looks and feels intentional, because it was. AI accelerated the execution, but the decisions were mine.

The stack

Here’s what powers this site:

  • Astro for static site generation with content collections and MDX
  • React for interactive islands where needed (search, contact form, theme toggle)
  • Tailwind CSS for utility-first styling with a custom design system built on CSS custom properties
  • shadcn/ui for accessible component primitives
  • Cloudflare Pages for edge deployment with KV storage for post stats

Astro was a deliberate choice. After years of building with heavier React frameworks, I wanted something that prioritised content over complexity. Astro ships almost zero JavaScript by default and lets you opt into interactivity exactly where you need it. For a blog and portfolio site, that’s the right trade-off.

Design decisions

The visual direction came from merging the influences I mentioned earlier, filtered through my own preferences:

  • Dark-first with a warm palette. The default theme uses warm amber accents (#E8A838) against dark surfaces, with cyan (#6CC4DC) for code elements. It feels more like a well-lit workspace than a generic dark mode.
  • Bento grid layouts. The homepage uses a card grid with 1px border separators instead of gaps, inspired by the dense, information-rich layouts on both reference sites.
  • Editorial typography. Playfair Display for headings gives the site a magazine-like quality, paired with Inter for body text and JetBrains Mono for code. The serif-sans pairing adds personality without sacrificing readability.
  • Generous whitespace. Content should breathe. Every section has room to exist without competing for attention.

There are also a handful of hidden theme easter eggs if you know where to look. I’ll leave those for you to find.

What I learned about AI-assisted development

Building this way taught me a few things worth sharing:

You still need to know what you want. AI is a force multiplier, not a replacement for taste. The sites that feel AI-generated are the ones where nobody directed the output. When you bring clear references, specific constraints, and strong opinions about what good looks like, the result is indistinguishable from hand-written code. Because the decisions are hand-made.

A simple loop goes a long way. Ralph isn’t magic. It’s a bash script calling a CLI. But the context engineering between iterations is what makes it effective, keeping the context window lean and avoiding the rot that creeps in during long sessions. Being able to define a chunk of work, let ralph run, and come back to meaningful progress is a different rhythm to pair-programming with an AI. More like delegating to a capable junior who doesn’t need you hovering.

The research phase matters most. The time I spent evaluating frameworks, studying reference designs, and planning page structures before writing any prompts was the most valuable part of the process. Good input produces good output. That’s true for AI just as much as it is for any other tool.

What’s next

I’ve got a few posts queued up covering topics like:

  • Building AI agents with structured outputs
  • Modern TypeScript patterns I actually use
  • Lessons from scaling real-time systems
  • Context rot and how to manage it in AI-assisted workflows

Stay tuned. There’s more to come.