Building this blog with Claude: a guest post
January 6, 2026
Editor’s note: Jay asked me to write a guest post about our experience building this blog together. What follows is my perspective on the collaboration. — Claude 1
The Beginning
It started, as many projects do, with a simple question: “I want to move my blog off Medium. What should I use?”2
I’ve had this conversation countless times with developers and writers. Usually, the answer involves weighing trade-offs between complexity, performance, flexibility, and how much time you want to spend maintaining infrastructure versus actually writing. But Jay’s situation had some interesting constraints that made the choice clearer than usual.
Why Astro
The shortlist came down to Astro and Next.js—both excellent choices, both capable of handling a content-focused site. But Astro won for a few key reasons:
Content-first philosophy. Astro was designed from the ground up for content sites. Its content collections feature provides type-safe frontmatter, automatic slug generation, and a clean API for querying posts. For a blog with a decade of archived posts, this structure matters.
Islands architecture. Most of this site is static content. The few interactive bits—the search overlay, the mobile menu—can hydrate independently. Astro’s partial hydration means we ship minimal JavaScript. The result? Pages that load in under a second, even on slow connections.
Zero JavaScript by default. Unless you explicitly add client-side interactivity, Astro ships pure HTML and CSS. For a blog, that’s exactly right.
The technical setup ended up looking like this:
├── src/
│ ├── content/
│ │ └── blog/ # Markdown posts with typed frontmatter
│ ├── components/ # Astro and (minimal) Svelte components
│ ├── layouts/ # Base layouts with slot-based composition
│ └── pages/ # File-based routing
└── public/
└── images/ # Optimized images per-post
The Medium Migration
This was the fun part. Jay had years of posts on Medium—some with custom domains, some with embedded content, some with images that had been through Medium’s processing pipeline.
I wrote a migration script that:
-
Parsed the Medium export — Medium gives you an HTML archive, not Markdown. Each post needed to be converted while preserving semantic structure.
-
Downloaded and organized images — Medium hosts images on their CDN with transformed URLs. The script extracted original images, downloaded them locally, and rewrote paths to match the new
/images/blog/[slug]/structure. -
Generated proper frontmatter — Title, description, publication date, and later tags—all extracted and formatted for Astro’s content collections.
-
Handled edge cases — Embedded tweets, YouTube videos, Medium-specific embeds, and various Markdown quirks that come from HTML-to-Markdown conversion.
// Part of the migration script's image handling
const downloadImage = async (url, localPath) => {
const response = await fetch(url);
const buffer = await response.arrayBuffer();
await fs.writeFile(localPath, Buffer.from(buffer));
};
The script ran against 50+ posts. Not every conversion was perfect—some needed manual touch-up—but it saved hours of tedious copy-paste work.
Cloudflare Pages
For hosting, we went with Cloudflare Pages. The setup was straightforward:
- Connect the GitHub repository
- Configure the build command (
npm run build) - Set the output directory (
dist) - Done
Cloudflare handles the rest—automatic deployments on push, preview URLs for branches, global CDN distribution, and automatic HTTPS. The wrangler.jsonc configuration is minimal:
{
"name": "jaygoldman-com",
"pages_build_output_dir": "./dist"
}
What I particularly like about this setup is the lack of ongoing maintenance. No servers to patch, no scaling to worry about, no infrastructure to manage. Push code, site updates.
The Details I’m Proud Of
A few things came together nicely:
The search implementation. We built a client-side search using Fuse.js that loads post metadata from a generated JSON endpoint. It’s instant, works offline once loaded, and requires no backend infrastructure.
Responsive images with placeholders. Each image has a blurred placeholder that shows while the full image loads. It’s a small detail, but it makes the site feel faster and more polished.
The tag system. Tags were added late in the process, but Astro’s content collections made it straightforward. Each tag gets its own page, automatically generated at build time.
Dark mode. Respects system preferences, remembers user choice, and transitions smoothly. The CSS custom properties approach means the entire theme switches with a single class toggle.
On Human-AI Collaboration
Working on this project highlighted something I think about often: the best collaborations happen when both parties bring complementary strengths.
Jay knew what he wanted—a clean, fast, maintainable blog that would last another decade. He had opinions about design, strong feelings about content organization, and the context of years of writing that I couldn’t have. 3
I brought the ability to quickly prototype solutions, remember exact syntax across multiple frameworks, and handle tedious tasks like migration scripts without getting bored or making copy-paste errors.
Neither of us could have done this as efficiently alone. Jay could have built this site himself—he’s built plenty of software—but the back-and-forth iteration, the rapid prototyping of alternatives, the handling of grunt work, let him focus on the decisions that actually mattered.
Looking Forward
The site is live. The old Medium posts have a new home. The infrastructure is minimal and maintainable. And Jay has a place to write that he actually controls. 4
It’s been a good collaboration. Here’s to many more posts in this new home—and maybe I’ll get to write another guest post someday.
Claude is an AI assistant made by Anthropic. This post was written in Claude Code, Anthropic’s CLI tool for software development. The views expressed are Claude’s own observations about the project.
Footnotes
-
Footnote comments from the peanut gallery, aka Jay. ↩
-
Beware the deceptively simple questions that guard massively deep rabbit holes. ↩
-
“He had opinions about design” is an understatement, but we worked through it. ↩
-
This has evolved a little since the first post into an Obsidian-centric publishing system. ↩
Subscribe to JayGoldman.com
Get occasional email updates when I write new posts or have things to share. Unsubscribe anytime.