Skip to main content
← Blog
Desarrollo

I migrated my blog from WordPress to Astro in a few hours using Claude

5 min read
I migrated my blog from WordPress to Astro in a few hours using Claude

My blog had been on WordPress since 2017. It worked. It had its posts, its Vantage theme, its sidebar with widgets nobody looked at. But over time I accumulated debt: no version control for the content, no reading time on post cards, no dark mode, code highlighted by a plugin that broke on old posts and getting slower every day from lack of updates. No multilingual support.

What finally made me act was simpler: I wanted to edit a post and had no way to do it from the text editor I use. Opening the WordPress admin to change three sentences is the kind of friction that builds up until one day you’ve had enough.

I decided to rebuild it with Astro.

What I changed about how I work

Normally when I build something I start writing code and make decisions as I go. With this project I did the opposite: document first, then build.

The result is that the docs/ folder in the repository has three brainstorms and three plans that explain exactly why the project made the decisions it made. Why single column instead of a sidebar. Why prefixDefaultLocale: false for i18n. Why Spanish posts live at / and English ones at /en/ and not the other way around.

That documentation isn’t just for future reference. It was the input for the build process: Claude read those documents to understand the context before writing any code.

The process: brainstorm → plan → build

I used Claude Code with the VGV Wingspan plugin, which structures the work in three phases:

  1. /brainstorm — explore the problem, make design decisions, document the reasoning
  2. /plan — turn the brainstorm into a concrete implementation plan with phases, acceptance criteria, and risks
  3. /build — build by executing the plan step by step

The brainstorm is the most important step. With a simple prompt — “I want to migrate my WordPress to Astro and Tailwind keeping my posts” — Claude didn’t start generating code. It started asking questions.

Did I want a sidebar or a single column? Should the default language be Spanish or English? Did the old posts have images worth migrating?

One that made me think: do you want Spanish at / and English at /en/, or the other way around? I hadn’t considered it. But the answer defines the site’s canonical URL, the i18n configuration, and how search engines index it. Having to answer it before writing a single line of code was exactly right.

By the end I had the idea clear: Astro v5, Tailwind CSS v4, single column, dark mode with prefers-color-scheme, posts as Markdown files in the repository, Spanish by default and English at /en/.

The plan was more extensive — six phases from initial setup to deployment, with documented gotchas from Astro v5 and Tailwind v4. I ran into those gotchas later in practice. The plan had them noted down in advance.

What got built

/build executed the plan phase by phase. In a few hours from the first brainstorm: complete static site, 19 posts migrated from WordPress to Markdown and translated to English, all pages in both languages, dark mode, reading time, Shiki for code, RSS, sitemap, and Open Graph per post.

There was one point where I had to step in: content migration. The 19 posts came from a WordPress export and required cleaning up the HTML, converting it to Markdown, adding frontmatter, reviewing images. Claude helped with the structure (basically did all the work), but reviewing each post was manual. /build doesn’t remove the work of knowing your own content.

The parts that surprised me

What surprised me most wasn’t the stack. It was that Wingspan identified requirements before I knew they were requirements.

When I told it I wanted Astro v5 and Tailwind CSS v4, the brainstorm didn’t assume I knew the changes in the latest versions. It researched them, documented the breaking points, and turned them into acceptance criteria in the plan:

  • In Astro v5, entry.slug disappeared. The identifier is now entry.id. A detail that breaks the entire routing system if you don’t know it upfront.
  • Tailwind CSS v4 dropped tailwind.config.js. Configuration is CSS-first, with @theme and @custom-variant. Coming from v3, the instinct is to look for a file that no longer exists.
  • Running git add with [slug] in the path, zsh interprets the brackets as a glob and fails. The plan said: add by directory, not by file.

None of these were part of my initial prompt. I asked for a blog with Astro and Tailwind. Wingspan asked about the versions, researched the implications, and turned them into part of the plan before writing a single line of code.

That’s what separates a well-made plan from a task list.

What’s next

For now, only comments (probably Giscus) and search (Pagefind as a post-build step) are missing. Neither blocked the launch, so they were left out of the initial scope.

What works right now: open the text editor, create a .md file with the right frontmatter, commit, and the post shows up on the site on the next deploy. No WordPress admin. No plugins. No configuration. And it loads like lightning.

That was what I wanted from the start.


More in Desarrollo