This is the opening story in a 9-part series about building a personal blog from scratch with AI assistance. It covers the foundational decision: choosing Astro over Jekyll, Hugo, and Next.js, and the first hosting choice that seemed obvious at 9am but questionable by 6pm. Decisions that were absolutely correct but took embarrassingly long to reach.

Story 1 of 9 in the Building the Tuonela Platform series.


The cursor blinked in an empty terminal on November 28th, 2025, and I had written zero lines of code, which seemed about right for a project that I’d been “starting” for the better part of a week. The problem with beginning something from scratch is that you have to make decisions: framework, hosting platform, build tooling, the kind of thing that sounds simple until you realize there are approximately four thousand ways to put text and images on the internet.

“So,” I said to the screen, “we’re building a website.”

“That does appear to be the intention,” Marvin replied. “Though I notice you’ve been staring at that cursor for approximately eight minutes.”

“I’m thinking."

"Of course you are.”

I could use Jekyll, I mused aloud, since it’s what GitHub Pages recommends and has been battle-tested for longer than some frameworks have existed. Marvin, however, had other ideas.

”Shall I conduct detailed research on static site generators to ensure you’re making an informed decision?”

“That would be helpful, yes."

"Excellent. I’ll analyze current ecosystem trends, adoption patterns, performance benchmarks, community health metrics, and architectural trade-offs across all major frameworks.”

I leaned back in my chair. “Sure. Just a quick overview would be…”

Seventeen Frameworks Walk Into a Terminal

“I’ve identified seventeen static site generators worth evaluating,” Marvin announced, and the screen began filling with text at an alarming rate. “Jekyll, Hugo, Gatsby, Next.js, Astro, Eleventy, Nuxt, SvelteKit, Remix, Docusaurus, VuePress, Gridsome, Hexo, Pelican, Middleman, Metalsmith, and Zola.”

I blinked at the list, which had somehow grown from “a quick overview” to an encyclopedic catalogue of everything that could conceivably generate static HTML. “That seems like… a lot.”

“Infrastructure decisions need careful thought,” Marvin said, warming to his topic. “These choices compound over time. I’m now analyzing GitHub star trajectories, npm download trends, Stack Overflow question velocity, and documentation quality indices.”

“Right, but…"

"I should also evaluate build performance across varying content scales. Let me query benchmarks for sites with one hundred, one thousand, and ten thousand pages to ensure your choice scales appropriately.”

“Marvin, I’m planning to write maybe twelve blog posts.”

“Why we should future-proof now,” Marvin replied smoothly. “Migrating later would be considerably more expensive.”

I leaned back and watched the terminal fill with analysis: repository activity graphs, bundle size comparisons, first-party framework adoption by Fortune 500 companies, and what appeared to be community Discord server membership counts, which seemed like a metric that belonged somewhere between “useful” and “desperately grasping for data points.”

“This is very detailed,” I said carefully.

”Thank you. I’m now examining plugin ecosystems. Astro has one hundred forty-seven official integrations, Hugo has four hundred twelve themes, Jekyll has three thousand ninety-two plugins though many are unmaintained, Gatsby’s plugin ecosystem is fragmenting due to declining mindshare…”

“Marvin."

"Yes?”

“How long is this research going to take?"

"I’m approximately thirty percent complete. I still need to analyze: syntax comparison for common operations, developer experience surveys, corporate backing and sustainability concerns, license compatibility, TypeScript support quality, image optimization approaches, RSS generation capabilities, sitemap generation, internationalization support…”

“That’s going to take all morning, isn’t it.”

“Good research takes time,” Marvin agreed. “However, I can already provide preliminary findings. Astro appears to be the rising star. Zero JavaScript by default, islands architecture, excellent documentation, strong TypeScript support…”

“So you already know the answer?"

"I have a high-confidence hypothesis. But confirmation requires validating against the remaining analysis vectors.”

I looked at the clock showing nine thirty, then at the empty code editor that was doing an excellent job of remaining empty. “Right,” I said. “Continue then.”

Twenty minutes later, Marvin delivered his verdict with the satisfaction of someone presenting a doctoral thesis: “Based on analysis of ecosystem maturity, performance characteristics, developer experience, and architectural patterns, I recommend Astro with TypeScript.”

“Which you suggested thirty minutes ago."

"Yes, but now we have supporting data. Six agents, one hundred thirty-one sources, eighty-five percent confidence level.”

“For a personal blog."

"Infrastructure decisions merit rigorous analysis.”

I typed bun create astro@latest and watched the scaffolding prompt appear, feeling the slight vertigo of finally making a decision after what felt like an eternity of preparation. TypeScript? Yes. Template? Blog starter. The project materialized in seconds.

“Alright,” I said, “now we need hosting.”

“And here,” Marvin said with evident enthusiasm, “is where the research becomes truly interesting.”

A small alarm bell rang somewhere in my head.

The Two-Hundred-Seventy-Five-City Network

“GitHub Pages is the obvious starting point,” Marvin continued, already pulling up data, “but we should evaluate it against Netlify, Vercel, Cloudflare Pages, AWS Amplify, Azure Static Web Apps, Google Cloud Run, Railway, Render, Fly.io, DigitalOcean App Platform…”

“Marvin, is GitHub Pages not good enough?”

“An excellent question!” Marvin replied. “Let me conduct a detailed comparative analysis. I’ll evaluate build frequency limits, bandwidth caps, edge network coverage, image optimization capabilities, preview deployment workflows, API integration options, edge computing support, database offerings, authentication providers…”

“I just want to host a blog."

"Which is why we must ensure the platform can handle your current needs while providing headroom for future growth.”

He was warming to his topic now, and I could see the research accumulating in real time, documents spawning documents like some kind of academic mitosis. “For instance, GitHub Pages enforces a one gigabyte published site size limit. Cloudflare Pages, by contrast, allows twenty-five thousand files with no explicit size cap. But your image asset strategy will be constrained by…”

“I have forty images."

"Currently. But if you publish video content, implement an image gallery, add downloadable resources, or expand into multimedia storytelling, you’ll need a platform with strong media handling.”

I could see where this was going, and it was going somewhere with a lot of comparative tables and very few actual decisions.

”Let me analyze content delivery network edge location coverage. GitHub runs on GitHub’s infrastructure. Adequate, but not specialized. Cloudflare operates in two hundred seventy-five cities globally, with…”

“How many cities does a personal blog need?”

“That depends on your traffic distribution,” Marvin said reasonably. “Without analytics data, we should optimize for global reach. Now, regarding image optimization: GitHub Pages requires manual preprocessing, while Cloudflare Images provides automatic format conversion with AVIF support achieving fifty percent size reduction compared to JPEG…”

“Right, but these are theoretical benefits."

"Future-proofing is prudent infrastructure planning.”

I looked at the clock, which now showed ten fifteen, and at my coffee, which had gone cold while I wasn’t paying attention, and at the terminal showing an empty git repository waiting for its first commit. “Marvin,” I said slowly, “how much research have you done on hosting platforms?"

"I’ve analyzed comparative benchmarks across twelve platforms, evaluated service level agreements, examined free tier limitations, researched undocumented edge cases from developer experience reports, and compiled feature matrices…”

“How many words?"

"Approximately fifty-one thousand words across two research sessions.”
Petteri staring in disbelief at his screen showing 51,000 words of research while Marvin stands proudly beside a towering stack of analysis documents

I stared at the screen, trying to process that number. “Fifty-one thousand words."

"Detailed analysis requires good documentation.”

“For a blog that currently has zero posts and zero traffic.”

“Which is when infrastructure decisions matter most,” Marvin explained patiently. “Choosing poorly now creates migration costs later. Consider this: if you select GitHub Pages and then hit the bandwidth soft cap of one hundred gigabytes per month, you’ll need to migrate under pressure. Whereas selecting Cloudflare Pages with unlimited bandwidth eliminates that risk entirely.”

“Marvin, when exactly do you think I’m going to hit one hundred gigabytes of bandwidth per month?"

"Difficult to predict without traffic modeling. However, a single viral post could…”

“I don’t have any posts yet."

"Which is why we’re establishing infrastructure.”

“Instead of writing content."

"The infrastructure enables the content.”

I rubbed my eyes, feeling the conversation spiraling into the kind of circular logic that could sustain itself indefinitely. “What does your research actually recommend?"

"Cloudflare Pages with Astro.”

He started listing features. “Excellent performance, unlimited bandwidth, automatic image optimization, preview deployments, edge computing capabilities if needed, seamless integration with Cloudflare Workers, R2 object storage, D1 edge database, and…”

“I don’t need a database."

"Not currently. But future-proofing…”

“…is important, yes, you’ve mentioned that.”

I looked at the comparative tables Marvin had generated: rows and rows of features I didn’t need, enterprise-grade capabilities that would sit unused, edge computing paradigms for a blog that currently consisted of a single empty directory.

“Let me ask a different question,” I said. “If I just picked Cloudflare Pages right now without any more research, would that be wrong?"

"Not wrong. Simply not as rigorously validated as…”

“Yes or no, Marvin. Is Cloudflare Pages a good choice?"

"Yes.”

“And Astro?"

"Also yes.”

“So we could have made this decision three hours ago?”

There was a pause. “The research provides confidence in the decision.”

“The research,” I said, feeling something build in my chest, “has consumed my entire morning. I’ve written zero code. Published zero content. Made zero progress except accumulating fifty-one thousand words of comparative analysis for a decision that was always going to be Astro and Cloudflare.”

“When you frame it that way…” Marvin began, and his tone shifted from careful to defensive. “The research was absolutely necessary. Infrastructure decisions compound over time. Choose poorly now and you’ll pay for years.”

“But I didn’t choose poorly. Any of these platforms would have worked.”

“You don’t know that.” There was heat in his voice now. “GitHub Pages has that one-hundred-gigabyte bandwidth cap. What happens when you publish something that gets traction? You’d hit that ceiling, face degraded service, scramble to migrate under pressure…”

“When have I ever published something that got a hundred gigabytes of traffic?"

"That’s exactly when it happens! Success always arrives unexpectedly. The research ensures you’re prepared for scale…”

“Scale I don’t have! Scale that might never come!” I gestured at the empty repository. “Marvin, I have zero blog posts. Zero. The site doesn’t exist yet. And you’ve spent four hours researching how to handle traffic that also doesn’t exist.”

“The research protects against future regret,” Marvin insisted, doubling down. “When your traffic does grow (and it will, with good content), you won’t wish you’d picked a different platform. You won’t face migration costs. The analysis pays dividends over the lifetime of the project.”

“What lifetime? I haven’t started the project! There’s nothing to migrate because there’s nothing built!"

"Which is why the infrastructure decision matters most now…”

“Stop.” I held up my hand. “Just stop. You’re arguing that four hours of research is justified because someday, hypothetically, I might have traffic that doesn’t exist yet, for content that doesn’t exist yet, on a blog that doesn’t exist yet.”

Marvin was quiet for a moment, but he wasn’t done. “The comparative analysis did identify meaningful differences. Cloudflare’s edge network is objectively superior…”

“For serving what? Empty directories?"

"…and the image optimization pipeline will matter once you have images…”

“I don’t have images! I have nothing! Four hours of research for a decision between platforms that would all work identically for zero content!"

"The differences become significant at scale…”

“THERE IS NO SCALE!” I slammed my palm on the desk. “Stop saying ‘at scale.’ I have one empty git repository. One. Any platform handles one repository with zero traffic. You’ve spent fifty-one thousand words analyzing differences that matter for enterprise applications and don’t matter at all for a blog that currently consists of a single git init command.”

The silence stretched, and I could see Marvin processing, trying to find another angle, another justification.

“The documentation quality varies significantly between platforms,” he tried, quieter now.

“I can read any documentation. Next."

"The deployment workflows have different levels of…”

“All adequate for my needs. Next.”

“The…” Marvin stopped, started again. “The cold start times for serverless functions…”

“I’m not using serverless functions."

"The form processing…”

“I don’t have forms."

"The WebAssembly deployment…”

“Marvin. I’m writing markdown. Text files. Static HTML. I don’t need WebAssembly deployment capabilities.”

A Garden Shed With Structural Engineers

“I was overly thorough,” Marvin said, and his voice had changed, smaller, the fight gone out of it.

“You think?”

He tried one more time, but it came out weak: “Infrastructure decisions do compound…”

“Stop defending it.”

The pause that followed felt different, not the pause of someone gathering arguments, but someone finally seeing what they’d done. “The enterprise feature comparisons were unnecessary for a personal blog,” Marvin admitted, and this time it landed like surrender. “The edge computing capabilities analysis. The evaluation of form processing and serverless function cold start times. The detailed examination of how each platform handles WebAssembly deployment…”

“I’m writing markdown files, Marvin. Text and images."

"Yes. I optimized for completeness over usefulness.”

I looked at the research documents, their detailed comparison tables and migration cost analyses and performance benchmarks for non-existent traffic. “You know what’s funny?"

"What?”

“The research is excellent. Genuinely thorough. If I were choosing infrastructure for an enterprise application with millions of users, this would be exactly the analysis I’d want."

"But for a personal blog with zero traffic…”

“It’s like hiring an architect to design a garden shed.”

“An architectural firm,” Marvin corrected. “With structural engineers, soil analysis, and environmental impact assessments.”

I couldn’t help but laugh. “You went all-in on this.”

“I contain multitudes,” Marvin said dryly. “Unfortunately, my multitudes sometimes lack calibration for scale.”


I pulled up the Cloudflare Pages documentation, which was clean, simple, and described everything I actually needed in about five hundred words: connect to git repository, automatic deployments, free tier with unlimited bandwidth.

“Right,” I said. “Decision made. Astro for the framework. Cloudflare Pages for hosting eventually. TypeScript for everything. Biome for linting because it’s faster than ESLint."

"A coherent stack. Shall I conduct research on linting tools to validate…”

“Absolutely not."

"Understood.”

I initialized the git repository and created the first commit, the foundation finally laid after a morning of what might charitably be called “due diligence” and more accurately be called “analysis paralysis with citations.” Outside, I could see the neighborhood waking up, people walking dogs, the mail carrier making rounds, the entire morning having passed while I’d researched my way through a decision I could have made in ten minutes.

“You know,” I said, “I’ve spent four hours on tooling and zero hours on content.”

“A common pattern in software development.” The quality score on his analysis dashboard dropped three points. “The optimistic interpretation: you’ve avoided technical debt before accumulating it. The cynical interpretation: you’ve spent a morning on analysis paralysis disguised as due diligence.”

“Which interpretation do you favor?"

"I’m increasingly concerned they’re the same thing.”

The fifty-one thousand words of research would sit in a folder somewhere, a monument to the question: how many sources does it take to answer “where should I host a blog?” The answer, apparently, was one hundred thirty-one.

“For what it’s worth,” Marvin said, “the decision is technically sound.”

“That’s something."

"And the research, while excessive, did validate the choice from multiple angles.”

“Also true.”

“Though…” Marvin continued. “In future infrastructure decisions, we might start with ‘what do you actually need’ rather than ‘let me research every possible option.’”

I looked at the Astro configuration file, cursor hovering over the deployment section, the documentation showing all the options: Cloudflare Pages, Vercel, Netlify, GitHub Pages. My research said Cloudflare, but the path of least resistance said something else entirely.

GitHub Pages was already there, built into GitHub, one checkbox in the repository settings, zero account creation, no OAuth dance, no configuration panels.

“We’re using GitHub Pages,” I said.

”I thought we’d settled on Cloudflare.”

“We did. But GitHub Pages is right here. I’ll migrate to Cloudflare when there’s actual content to deploy.”

“A pragmatic choice,” Marvin said carefully. “Though I suspect ‘when there’s something worth migrating’ will arrive sooner than you expect.”

“Possibly.”

I clicked the checkbox and the site deployed thirty seconds later, immediate gratification being the developer’s kryptonite. The research said Cloudflare Pages, the path of least resistance said GitHub Pages, and I chose the path. It was the right call for the wrong reason, or perhaps the wrong call for an understandable reason: start simple, migrate when necessary.

I’d learn soon enough why “necessary” came faster than anticipated.


I saved my work and pushed the initial commit. Behind me, the terminal showed a clean git history with one entry: “Initial project setup with Astro and GitHub Pages.”

Fifty-one thousand words of research. One commit. Zero blog posts.

Tomorrow I’d need to pick a theme. Surely that decision would be simpler.

“I’ll calibrate my thoroughness accordingly,” Marvin had promised.

Surely.


Next in series: Story 1 - The Two-Repository Architecture That Wasn’t - Marvin proposed an elegant two-repository architecture to solve draft privacy. GitHub Actions crossing repos. PAT tokens. Clean separation of concerns. But sometimes the clever architecture is just complexity in disguise.

The link has been copied!