← Back to Blog

Astro: The Framework That Didn't Judge Our Legacy Code.


Table of Contents



Why Migrate?

Experian’s website had only two major migrations in its entire twenty-year history. It moved from plain HTML managed through the now-retired TeamSite CMS, to an AWS-hosted setup using EJS templates - and now, its ongoing migration to Astro. For a static site, that level of evolution is enough. However, without a design system in place, each new developer brings their own patterns and preferences, and as the team grows, that flexibility quickly turns into inconsistency. At that stage, defining clear standards becomes essential. But most importantly, when critical vulnerabilities begin to rise because npm dependencies can no longer be updated without breaking changes, it’s a signal to reassess the risks, especially for a site that serves as the primary entry point for millions of users checking their credit scores.

Framework Evaluation

The key requirement for initiating a framework migration is having supportive leadership - both a Manager and a Head of Product for .co.uk who understand the value of the change and are willing to authorise the effort. Fortunately, we had exactly that. Once the challenges and limitations of the current system have been clearly presented and approval is granted, the next step is to establish a structured plan and involve additional developers promptly. Priorities shift quickly, and you don’t want the project stalling before it even starts.

We began by developing several proof-of-concepts: Next.js, Gatsby, React, and Astro, each with its own strengths and limitations. For our specific needs, Astro was the most suitable option. After presenting our evaluation to key stakeholders and cross-team leaders, and receiving approval to proceed, we shifted our focus to execution.

Implementation Strategy

Our first step was validating whether Astro could integrate cleanly with our existing legacy codebase and project structure. It did, enabling a seamless hybrid setup. We started by migrating a minimal low-traffic page with simple content as our initial test case. From there, we built the main Astro components needed for the next set of pages, including the CTA, Navigation, Footer, Banner, and Carousel.

We organised an internal interactive workshop to align the entire team on best practices, and we included quizzes to keep the session engaging, offered small prizes, and even created custom coasters to make the experience memorable.

Astro migration workshop
© Martyn
Astro migration coaster
© Craig

The Design and QA teams were incredibly understanding and collaborative. Since everything was rebuilt from scratch, pixel‑perfect parity with the legacy site wasn’t always possible. We agreed to accept minor visual differences so we could focus on delivering value rather than chasing 100% replication.

Our collaboration with the CloudServices team was excellent as well. They supported us in integrating the Astro build into the deployment pipeline, and our simultaneous migration to GitHub Actions aligned perfectly. They took the time to understand Astro’s workflow and how best to support the transition.

Key Features

A few lovely features make Astro exceptional: zero-kilobyte JavaScript by default, built-in routing, island architecture, image optimisation, live content collections, and its flexible server-client hybrid model, which lets one page render on the server while another runs entirely on the client. It’s an impressive combination. Astro borrows concepts from other frameworks, but only the strongest ones. Kudos to Fred and the team for shaping it into something this refined.

Astro also lets you embed components from any frontend framework—React, Vue, Angular, Svelte, and others—without friction. One of its biggest advantages is that these components are rendered on the server, so the browser never receives the framework runtime unless you explicitly hydrate them using directives like client:load, client:visible, etc. Without hydration, the component ships zero JavaScript, and a fully static page sends none at all. That doesn’t mean every framework should be embedded just because it’s possible. A strength of Astro’s framework‑agnostic approach could be when another team — maybe one working in React, builds a widget or feature for a different product that would be tedious or impractical to recreate as a pure Astro component. Instead of rebuilding it, you can simply integrate that component directly. It’s a similar concept to Micro Frontend Federation, but with far less overhead, and especially useful when an existing plugin or widget offers more flexibility than an Astro‑native alternative.

Results & Timeline

The migration is still in progress, but we’re confident we can complete the remaining 300 pages by the end of the year. The process has been remarkably smooth so far, Astro is straightforward to learn, configure, and reason about. The developer experience has been outstanding, especially compared to our previous Webpack setup, where starting the dev server took 30 seconds and was basically an invitation to go make some tea. With Astro, it’s instant.

Performance numbers already look promising. We’re making a few final tweaks before sharing them, because if we’re going to brag, we want the Lighthouse score glowing green and say: “Yes, it was worth it”. But even without the exact numbers, the improvements in load times and interactivity are noticeable, especially on mobile where we’ve been able to strip away unnecessary kB. The new architecture has also made it easier to maintain and update the site, and the team is excited about the future possibilities with Astro’s features and ecosystem.

An example of an Astro page is: Applying for a credit card.

Lessons Learned

We ran into a few unexpected issues, including the default \_astro assets being blocked by CORS in production even though everything worked perfectly in pre-prod. We had to roll back, sync with DevOps, and redeploy the next day. Thankfully, our build only takes about 10 minutes, so the rollback was painless. We’d been excited to go live — like a kid unwrapping a new toy — and when it didn’t work, it felt like that toy was suddenly taken away. It was a good reminder of the importance of testing in production-like environments and having a solid rollback plan.

Of course, as much as we love working with Astro, the progress we’ve made isn’t entirely because of the framework. Starting fresh gave us a rare chance to rethink everything with care — remove layers of overrides, replace noisy markup with components that actually mean something, tailor the mobile experience so it only loads what truly matters, and much more. It felt less like a technical reset and more like giving the project space to breathe again.

Final thoughts

Astro might not be the perfect fit for every team, but more and more websites are moving to it — and for good reason. The only real way to know if it’s right for you is to put it to the test, explore its capabilities, and weigh the pros and cons.

We also had the chance to meet the Astro team in person and enjoyed a great conversation with Sarah, Matt, and Fred. If you’d like to support Astro’s development, they have an Open Collective fund — even small contributions make a difference: Open Collective - Astro.

Although Astro were recently acquired by Cloudflare, Astro continues to operate independently, and the team remains dedicated to its open‑source roots and community‑driven approach.

Photos taken by me during ViteConf in Amsterdam, 2025.