Skip to main content

How and why to move from WordPress to Astro

A journey from a monolithic content management system to a modern tech stack. And how AI can help create a smooth path to get there.

By Julius Honnor

How and why to move from WordPress to Astro

WordPress, is, in many ways, an amazing solution. It powers nearly half the web. But although its huge ecosystem of plugins is brilliant, the sheer complexity can also be problematic. And it can still feel like a system designed primarily for blog posts and pages, rather than a more sophisticated, modern content model. We’d outgrown it.

This resource explains the reasons for making this change, the best solutions for each element of this shiny new tech stack and why they were chosen, and how to pull it all together.

Our old setup

WordPress Website
Old setup diagram showing WordPress and Website as overlapping circles

Our old setup used WordPress. When people visited our website they were effectively visiting WordPress: the software and the content were all hosted in the same place and the CMS dealt with functionality and presentation and content all together. It was a big, complex beast: it did many things at the same time, none of them brilliantly.

Our new setup

Claude Code Storyblok Astro GitHub Netlify Website Style guide
New setup diagram showing Claude Code, Storyblok, Astro, GitHub, Netlify, Website, and Style guide as connected flow

Our new setup uses a modern tech stack where each element has a specialist role. It’s far more maintainable and the final site is about ten times faster.

Why do this

The case for making this move was a mix of content, technical and strategic reasons. Also, we’ve been espousing a headless/decoupled/composable approach to people for ages, so it was slightly embarrassing that our own website was still a WordPress site.

Performance

The Contentious site now loads ten times faster than it did. That’s a massive improvement to the user experience. We used Divi in WordPress, which was great for building multi-component, rich, engaging content. But even with caching, it wasn’t fast. Divi 5 promises lots of improvements but after what feels like eons of development it’s still buggy and not really ready.

Our new setup creates static files that are lightning quick to load and are infinitely cacheable using a content delivery network that should make it equally fast around the world. And Astro is brilliant at making the setup lean, only loading exactly what’s needed, with no superfluous javascript or unnecessarily complex code.

Separation of concerns

Separation of concerns has long been a really important aspect of good software development. But monolithic content management systems bundle many aspects of website publishing and maintenance, often to nobody’s advantage.

In headless or decoupled systems, content and presentation are different layers in the tech stack, meaning they can scale independently, be worked on independently, even be changed independently.

Genuine content management

It’s been a longstanding bugbear of content managers that content management systems are seldom any good at content management. In fact, the very CMS name is a misnomer: WordPress is really a website publishing system. It’s rubbish at managing content workflow.

Whereas, once you’ve decoupled your content management from your content publishing you can create a really good system that works for the needs of your authors and editors.

Structure

Whereas Wordpress is built around the concept of pages and posts, Astro encourages you down a much more modern componentised, composable route that works brilliantly. We did manage to have a bespoke content model in WordPress, and Advanced Custom Fields is a great plugin. But it always felt as if we were swimming against the current at best. And being downright hacky and trying to fit square pegs in round holes at worst.

Cost

For a single site, WPEngine hosting costs £240 a year. That’s not bank-breaking, but it’s still £240 more than free. Our old site also used some paid-for plugins.

Astro is open source. Netlify’s free tier gives us a generous 100GB bandwidth a month. Github is also free unless you need enterprise features (we don’t). And Storyblok is free for up to 25,000 pieces of content. I don’t think we’ll be hitting any of those limits any time soon.

Security

No tears were shed on waving goodbye to WordPress vulnerabilities and constant plugin updates. With a massively reduced attack surface, our new approach is infinitely more secure. With our new setup, Netlify’s CDN only has static files, which are much harder to hack.

Reduced technical debt

No plugins means no conflicts, theme incompatibilities, or PHP version migration headaches. I’ve separated out the tech we use in our new stack. But in doing so I’ve made things much simpler for us to maintain. There are fewer dependencies to manage and fewer risks of things going wrong as things evolve over time.

Developer experience

The developer experience of this setup is infinitely better. Instead of battling WordPress, it uses the best of modern tooling, with a Git-based workflow. Instant rollbacks to any previous version are simple. Staging is built in without the need to maintain separate servers. Git-based deployment means multiple developers (or AI agents) could work simultaneously with proper version control, branching, and merge strategies.

Future proofing

We’re now in a great position to make future improvements to the site. We can easily add interactivity, new components and tools. No plugins required. And we could switch out part of our tech stack and switch in another fairly painlessly.

AI in the mix

With this setup it’s easy to include AI in the dev mix. I made good use of Claude for this project (see below), massively speeding up the process. Having AI developers to help me out with things is an aspect that’ll be really useful in the future.

Content versioning

Rock-solid versioning for content as well as code, using Git, the world’s standard versioning system, gives us a complete audit trail of all changes. For us that may be something we don’t use that often; for others this could be a huge selling point of this approach.

Multi-platform content delivery

Monolithic CMSes such as WordPress often hold huge quantities of organisations’ content but they’re web-only. Parallel, disconnected systems are needed for other channels and platforms: apps, email, social, devices that haven’t been invented yet. That’s a recipe for inconsistency and mess.

Whereas a decoupled, componentised, content-first setup like this allows for much more systematic, tidy multi-channel setups.

This isn’t an aspect that we’re taking advantage of yet, but it’s hugely relevant to bigger organisations. And if we decide in future that your internet-connected-fridge needs some content strategy resources, we’ll be ready.

SEO

Faster load times and cleaner HTML aren’t just good for users; they directly benefit search engine rankings too.

Content portability

As simple, plain text formats, Markdown and MDX files are future-proof. Content isn’t locked into a proprietary format. Down the road, if new, better options become available, we’ll be able to switch our content over to those without headaches.

A live style guide and a website from the same project

I rebuilt our style guide (covering brand foundations, content, code and design) at the same time as the website. It sits on its own subdomain and has its own navigation but it’s actually part of the same development project, and uses the same GitHub repository. This means that it’s genuinely live: a component (or colour or heading level or CSS rule) in the main website is also a component in the style guide. If one changes the other changes too. This keeps the documentation always in sync with the live site.

We could have done something like this in WordPress, but it would have been a bit clunky. This feels much more like a natural fit.

Building a brilliant stack

Our new tech stack consists of Claude Code, Storyblok, Astro, GitHub and Netlify.

Here’s why I chose them.

Claude Code

I initially used Windsurf as a development environment with agentic AI built in. You can choose your model; I mostly used Claude Sonnet 4.5, with some Claude Opus 4.5 and some GPT-5.2 while they were on special offer. Each model worked fairly well.

Having the ability to switch between models in Windsurf was great but I wasn’t really using other Windsurf features and Claude Code seems more powerful than just using Claude models within Windsurf’s AI assistant. So I’ve since shifted to just using Claude Code via the plugin in VS Code. Because the codebase is a GitHub repository, this shift was incredibly simple.

I’ve also used Replit before. Replit’s great because it’s all in the cloud, which means it’s easy to switch from one device to another. And it deals nicely with deployments and setting up databases. But for me, working as a fairly competent but self-taught developer, Claude Code is not only more powerful than Replit, it also gives me the right level of agency. For this project I wanted an opinionated, expert developer to help me with tasks, not a vibe coder to make decisions and head off in its own directions.

Astro

Astro is the presentation layer and the engine of our new tech stack. It takes all the component parts and builds optimised, lightweight websites.

Astro felt like the perfect fit for us. It’s a JavaScript framework specifically designed for content-driven websites. It creates incredibly fast sites in an efficient way.

Storyblok

Storyblok is a headless content management system. It manages content according to a content model and passes it via an API to wherever it needs to go.

I chose to go with Storyblok because I like their content-centric approach and their user-friendly editor, but you could also use Sanity or Contentful.

I’m using Sanity for the Content Health Check, and it’s been great. But for this I wanted a more creative, visual content design environment.

This part of the new tech stack is still work in progress. Currently the content is mostly raw Markdown or MDX, which is absolutely fine for now. The plan is to move one content type at a time to Storyblok. It’s another advantage of this approach that a staggered migration is perfectly possible.

GitHub

GitHub holds all the code. It allows for versioning, and for different people to work on the codebase at the same time.

Having a git-based approach means I can work locally safe in the knowledge that if I spill coffee all over my laptop, the code is safe.

We already have a GitHub account so this was an easy choice. Other Git providers are available, and if you object to Microsoftification you may want to use GitLab instead.

Netlify

Netlify does the building and is essentially the host, though “host” in this setup really means Content Delivery Network. It also deals with some other crucial, interactive aspects such as forms. Within seconds of a change in GitHub, Netlify distributes a new version of the site.

Vercel, Netlify and Cloudflare are close competitors and there’s not much to choose between them. They all have generous free tiers. Cloudflare is possibly a tad faster (but they’re all really fast, so this is a marginal advantage) and we already use it for DNS management. It’s also now the parent of Astro. But I went for Netlify because we already host other things there and their form support seemed easier/better.

How to pull it all together

An article suggesting that AI meant this was all possible in 3 hours was the starting point that set me off on this adventure. It gave some useful suggestions, but for our site at least (and, arguably, my levels of perfectionism) 3 hours was wildly over-optimistic.

All in all, even with the help of AI, it took me more like 40 hours’ work to get everything set up and functioning in a way I was happy with.

Audit, planning and structure

The first step was to gather all the raw material. WordPress lets you export all content as XML, which was helpful.

I also went a step further and used SiteSucker to create a static version of the site. This meant that AI had a couple of good, local reference points to assess and to build from.

We already had a full set of bespoke content types in WordPress, so I got the AI agent in Windsurf to set those up.

I then worked through a content type at a time, working with the AI agent to detect and build content components: all of the design and structural elements that are repeated across Contentious content, such as hero sections, borders and screenshot holders.

Tokenisation is also an important part of this new efficient, consistent setup and as I worked through the content I tokenised as much as possible. AI was sometimes less than helpful here: it tended to want to take shortcuts and hardcode values rather than take the more sustainable, efficient path.

Overall, however, AI (with human shepherding and guidance) massively sped up this architectural stage.

Markdown or MDX?

I started off using mostly Markdown for content, and ended up using mostly MDX. Markdown is simpler; MDX is more powerful. For the Contentious site, MDX offered more flexibility, which generally trumped the simplicity of Markdown. And I’m happy editing MDX files. As I migrate more content into Storyblok this choice will become less relevant.

Content building

Using the XML export from WordPress and the static site HTML files as a reference, I got the AI to create content collections and rebuild all the website content as Markdown and MDX files. Working methodically through the content revealed some additional parts that were built as repurposable components.

I got AI to help set up dynamic routing, building URLs for everything.

I also used AI to help build the Storyblok integration, starting with Thought articles and ironing out some creases as I went.

CSS

Our styles in WordPress worked but the CSS was huge and inefficient.

Astro is great at building lean efficient sites and CSS is an important part of that. Scoped CSS means that only the code that’s needed is loaded. Tokens and variables make the system much more DRY.

I considered using Tailwind CSS, which is a really solid CSS framework. If you’re starting from scratch with a similar setup, Tailwind could be a big help. But I decided that for the Contentious site, it wasn’t really needed. The combination of design tokens, scoped styles and semantic, readable markup makes it an efficient system already.

There was some wrangling involved in getting all of the CSS to work, and deciding what was genuinely site-wide and what was component-specific. And the AI agent sometimes needed reminding/arm twisting to use variables in the best possible way. But it was worthwhile wrangling: we now have a CSS system which is light years ahead of the mess of rules and exception-rules that had built up over years.

Colour system

In some areas, such as our colour system, we now have not only a tidier system but a much more powerful one. I made good use of Scale by Hayk and codified our colour palette in a way that’ll be invaluable not just for our website but our products and other outputs too.

Privacy, cookies, analytics

It seemed like a good moment to fully switch away from Google Analytics to Umami, which is a great open source, privacy-focused analytics platform. We’re hosting it on Pikapods, which costs us about $2 a month. This is cheaper than using Umami’s own hosted version and means stats are accessed from a Contentious subdomain. We could have self-hosted it, but $2 a month is well worth it not to have to worry about updates and servers, which Pikapods deal with brilliantly.

That also meant reworking our privacy policy and cookies (or, no-cookies) policies.

The style guide

Halfway through the project, I decided that rather than creating another set of documentation I should rebuild the Contentious style guide as part of the same project, and integrate everything (foundations, words, design and code).

This slowed things down, adding another layer of complexity. But it also made sense to do it now, while all the design, code and structure thinking was fresh in my mind. Abstracting as I went also concentrated the mind on what we needed and what good practice looked like. And having a style guide which publishes to its own subdomain but uses exactly the same code under the hood is a pretty neat solution.

Deployments

My local project is pushed to GitHub, where all the code is stored in the cloud and changes are tracked. Two Netlify projects (one for the main website, one for the style guide) automatically rebuild whenever anything changes in the GitHub repository.

I can check changes locally before pushing them to GitHub. After I’ve pushed to GitHub, the deployment process is seamless. It takes around 30 seconds – a minute for changes to appear on the live site.

Making changes or adding content in Storyblok is a similar story. I’ve set my dev environment to see draft content, which means that if I save content as draft in Storyblok I can check it locally before it’s published to the live site.

The final outputs

What we’ve ended up with is what you see here: a fast, secure, modern website that’s easy to maintain and update, with a comprehensive style guide that’s integrated into the same codebase.

Having AI in the mix hugely sped up the process. And that will continue to be helpful as we build new things and iterate on old ones.

It took time, effort and no small amount of thinking to get here, even with AI to help.

But it was a great learning experience, and an opportunity to improve various things along the way.