Story heading

Migrating ByteofDev from SvelteKit to Astro

August 16, 2022

Astro and SvelteKit are both modern frameworks. Originally, I built my blog ByteofDev using SvelteKit, but I recently migrated to Astro due to performance and tools for writing. This article talks about why I did it and how.

Why we migrated to Astro


ByteofDev Lighthouse Scores
ByteofDev's Scores using Lighthouse

Astro supports component-level partial hydration, which Astro based on the Islands Architecture. Component hydration is much more granular than SvelteKit’s page hydration because you can isolate JavaScript to one specific part of the page rather than either shipping JavaScript for the whole page or no JavaScript period. Partial hydration helped heavily reduce the JavaScript shipped to the client, significantly improving performance.

While doing this, I also was trying to migrate from a headless CMS to using markdown and Git to allow for more flexibility and performance. For markdown with Svelte components, Svelte has mdsvex, which works pretty well, but Astro has officially supported integration with MDX (which is what inspired mdsvex), which I found easier to use. Astro also has an easy-to-use API for getting the frontmatter of markdown files (Astro.glob()), making it easy to implement features like tag pages. Finally, Astro an easy-to-use plugin for sitemap and RSS feed generation, which is helpful for SEO and reaching a wider range of readers.

Migrating to Astro

Overall, migrating to Astro was not overly complex, as both Astro’s JSX and Svelte mainly use HTML. Additionally, some Svelte components I could keep as Svelte components. However, there were still a few hitches.


In Svelte, all frontmatter is handled inside <script> tags. However, in Astro, this is not the case. In Astro, you put everything in ---, like markdown frontmatter. There were also differences in loading data and displaying it due to the differences in API (this was exemplified due to also moving away from a CMS). Finally, with SvelteKit, there is a <svelte:head> component, which does not exist in Astro. It is possible to use slots in Astro, but ultimately I settled on using a custom SEO component like Astro SEO.

Conditionals and iteration

SvelteKit has a custom syntax for iterating through elements and using conditionals, whereas Astro follows JSX and uses embedded JavaScript expressions. For example, a conditional in Svelte might look something like this:

{#if boolean}
<h1>The boolean is true</h1>

Where in Astro, you would do something like this:

	boolean ? <h1>The boolean is true</h1> : "";

When iterating through an array, it is also different. For Svelte, you would do this:

{#each array as item}

For Astro, the best way to iterate through an array is usually this:

{ => (

These differences made it harder to migrate, but it was pretty simple to change it still.

API Endpoints

SvelteKit has built-in support of API Endpoints, but Astro does not. I reduced the number of endpoints I needed, but I still needed one for signing up for the ByteofDev mailing list. This is where a recent development helped me. Fullstack pages, a new feature in Cloudflare Pages, made it significantly easier to set up an API Endpoint compared to using a Worker. It still was not as easy as using SvelteKit’s integration with Cloudflare, and the endpoint does not run in development, but overall it works pretty well. If you are using Netlify, Netlify Functions or Edge will work. If you are using Vercel, Vercel Serverless Functions should work.


Moving from SvelteKit to Astro has benefited my blog because of the features provided and the performance. Using Astro, I reduced my server hosting costs by eliminating the CMS and reducing Cloudflare Worker requests to only one route while improving performance by reducing the JavaScript sent (see Lighthouse scores above). If you liked this article, sign up for the newsletter below. I hope you have learned something from this, and thank you for reading.


Sign up for email updates

Get interesting posts about web development and more programming straight in your inbox!