← back to articles

what i learned rewriting my site in astro

2023-05-17 · 2 min read

moving a small portfolio off next.js and onto astro. the bundle, the build, and the time it took to load on a phone in a tunnel.

my portfolio started as a next.js application because that was what i knew. it worked, but it was more machine than my content needed. a full react bundle for a page that displays text and links. client-side routing to navigate between four pages. a server that runs on every request to serve static content.

the migration

the rewrite took two nights. i ported the layout, the components, the styling, and the data files from next to astro. the page count was small enough that i could do it page by page, verifying each one before moving to the next.

the result: zero javascript on the initial page load. the home page is 9kb of html and a css file. the framework overhead — react, next, client-side routing — is gone. the site builds to a directory of flat html files that any web server can serve.

here is the difference in practical terms:

metricnext.jsastro
page size (html)27kb9kb
js to first paint143kb0kb
build time47s4s
cold start on vercel800msinstant

the numbers are not surprising — astro does less at runtime because it does more at build time. the surprising part was how little i had to change in the component code. astro’s component model is close enough to react’s that the mental model transferred with minor adjustments.

what i lost

i lost the ability to use react components that depend on browser apis without wrapping them in client directives. i lost the instant page transitions that next’s app router provides. i lost the api routes that i was not using anyway.

the loss that mattered most was the development loop. next’s hot module replacement is fast and reliable. astro’s is slightly slower — about two seconds to reflect a change in the browser versus sub-second in next. this is noticeable on a small project where you are iterating quickly on layout and spacing.

what i gained

the site loads faster on actual devices in actual network conditions. on a 4g connection, the next.js site took 4.2 seconds to become interactive. the astro site is interactive at 1.1 seconds. the difference is the react hydration payload — 143kb of javascript that the browser downloads, parses, and executes before the user can click a link.

i also gained confidence that the site will render correctly in any browser, including text-mode browsers, rss readers, and the various crawlers and scrapers that read the web. no javascript, no hydration errors, no flash of wrong content.

conclusion

astro is the right tool for content-focused sites where the interactivity is limited to links and forms. next.js is the right tool for applications where the user spends minutes, not seconds. the rewrite taught me to match the tool to the job, not to the hype.