VOOZH about

URL: https://thenewstack.io/how-to-use-astro-with-a-sprinkling-of-react/

⇱ How to Use Astro with a Sprinkling of React - The New Stack


TNS
SUBSCRIBE
Join our community of software engineering leaders and aspirational developers. Always stay in-the-know by getting the most important news and exclusive content delivered fresh to your inbox to learn more about at-scale software development.
REQUIRED
It seems that you've previously unsubscribed from our newsletter in the past. Click the button below to open the re-subscribe form in a new tab. When you're done, simply close that tab and continue with this form to complete your subscription.
The New Stack does not sell your information or share it with unaffiliated third parties. By continuing, you agree to our Terms of Use and Privacy Policy.
Welcome and thank you for joining The New Stack community!
Please answer a few simple questions to help us deliver the news and resources you are interested in.
REQUIRED
REQUIRED
REQUIRED
REQUIRED
REQUIRED
Great to meet you!
Tell us a bit about your job so we can cover the topics you find most relevant.
REQUIRED
REQUIRED
REQUIRED
REQUIRED
REQUIRED
Welcome!

We’re so glad you’re here. You can expect all the best TNS content to arrive Monday through Friday to keep you on top of the news and at the top of your game.

What’s next?

Check your inbox for a confirmation email where you can adjust your preferences and even join additional groups.

Follow TNS on your favorite social media networks.

Become a TNS follower on LinkedIn.

Check out the latest featured and trending stories while you wait for your first TNS newsletter.

PREV
1 of 2
NEXT
VOXPOP
As a JavaScript developer, what non-React tools do you use most often?
Angular
0%
Astro
0%
Svelte
0%
Vue.js
0%
Other
0%
I only use React
0%
I don't use JavaScript
0%
Thanks for your opinion! Subscribe below to get the final results, published exclusively in our TNS Update newsletter:
NEW! Try Stackie AI
From clobbered drafts to real-time sync
Apr 14th 2026 10:00am, by David Moore
TypeScript 6.0 RC arrives as a bridge to a faster future
Mar 14th 2026 9:00am, by Darryl K. Taft
Mastra empowers web devs to build AI agents in TypeScript
Jan 28th 2026 11:00am, by Loraine Lawson
2023-10-24 07:00:42
How to Use Astro with a Sprinkling of React
tutorial,
Frontend Development / JavaScript

How to Use Astro with a Sprinkling of React

Here's how to use Astro to incrementally adopt a "reduced JavaScript" approach to building websites. No more refactoring every component!
Oct 24th, 2023 7:00am by Paul Scanlon
👁 Featued image for: How to Use Astro with a Sprinkling of React
Image via Unsplash.
The thought of migrating away from a React-based framework might seem a little scary at first, but if you’re intrigued about how that might work, read on. I recently made the decision to migrate my site, paulie.dev, away from a React-based framework to Astro, a web framework known for its “islands architecture.” Naturally, in my old site, everything was React, so my first thought was: this is gonna be a lot of work. But it wasn’t! During my development, I was able to lift-and-shift a lot of the “React-specific” components and drop them straight into my new Astro site. In this post, I’ll explain an approach that might work for you, and if you’re interested in incrementally adopting a no/low JavaScript approach to building websites, I think you’ll like Astro! Here’s a sample site and GitHub repository that I’ll be referencing throughout this post that demonstrates how Astro can be used alongside a sprinkling of React. But first…

What Is Astro?

Astro builds fast content sites, powerful web applications, dynamic server APIs, and everything in-between.
…and they’re not lying. Astro, like a few other frameworks, uses a fresh approach to building websites called “islands architecture”. What this means for the likes of you and me is: Astro is predominantly a framework-agnostic static site generator, but can quite easily be configured to work with a number of UI libraries or frameworks. It can also work with various cloud providers, to support client-side requests using Serverless or Edge functions, server-side rendering, or both.

Using Astro and React

Astro by default will ship zero client-side JavaScript, but it’s quite likely during a migration from a React-based framework that you’ll need a bit of React here and there. React is great, but is it required on every page of your website, or is it only needed in a few “islands” around your site? I’ll now explain how you might tackle a website migration, but rather than having to refactor absolutely everything to work in a world without React, you can keep React but only use it in pages/components where it’s needed. And more than that, using Astro’s client directives to control when the JavaScript required by those components should be loaded by the browser.

Getting Started with Astro

To get started with Astro, follow the Start your first project guide from the Astro docs, which will explain a little more about the CLI wizard. I generally start by selecting the “Empty” option from the CLI prompt. It’s just my preference, but I find it easier to see the woods for the trees when I’m starting with as few files as possible. It also highlights just how little there is to an Astro site. A single config file and a single dependency — very nice indeed! 👁 Screenshot of Astro CLI in a terminal window
However, one thing you might need to change right away is the “output” mode in astro.config.mjs. By default, Astro is static, but in my sample site, I have a mix of static and server-side rendered pages. To support both, I changed the output mode to “hybrid” and added the appropriate server-side runtime adapter. My sample site is deployed to Netlify, so I’ll be using the Astro and Netlify adapter.
import { defineConfig } from 'astro/config';

import netlify from '@astrojs/netlify/functions';

export default defineConfig({
 output: 'hybrid',
 adapter: netlify(),
});
You can read more about hybrid rendering in the Astro docs: Converting a static site to hybrid rendering.

How to Create a Page Using Astro

Astro has its own file extension, .astro. Astro files look like the love child of MDX and JSX, where you have “frontmatter-like” syntax at the top of the file and HTML-like syntax lower down.
---
import thing from './thing'

const { title } = Astro.props

const request = await fetch('https://dummyjson.com/products?limit=10');
const data = await request.json();
---

<div>
 <h1>{title}</h1>
 <Thing />
 <ul>
 {
 data.map((item) => {
 return <li>{item.name}</li>
 })
 }
 </ul>
</div>
The “frontmatter-like” part of the file can be used to declare imports, access props and perform server-side requests; it looks a little unusual to begin with, but it’ll soon start to feel familiar once you get going.

Page Rendering Methods in Astro

The method used to render a page is usually determined by what the page is for, where the data comes from, how often the data changes and what components are used on the page. Below is a breakdown of each page from my sample site, together with a rationale about which page rendering method I’ve used and if React is required.

The Home Page

The home page of my sample site doesn’t need React, because it doesn’t have content that changes frequently. As such, I’ve opted to make this page static — meaning, the final output is only the HTML and CSS required by the browser to render the page… and it loads super fast!
---
import Main from '../layouts/main.astro';
---

<Main title='Home'>
 <h1>Home</h1>
 ...
</Main>
You can see the src file for this page in the repository here: src/pages/index.astro

The Product Page

The product page of my sample site also doesn’t need React, since the only job for this page is to fetch product data and display it on the page (no interactivity or state management is required). As such, I’ve opted out of using prerender, which means this page will be server-side rendered. The page makes a server-side request to an API to fetch products before, once again, the final output is only the HTML and CSS required by the browser to render the page. The page load speed is still fast, but if the API is slow to respond then it may not be quite as fast as a static page.
---
export const prerender = false;

import Main from '../layouts/main.astro';

const request = await fetch('https://dummyjson.com/products?limit=10');
const data = await request.json();
---

<Main title='Products'>
 <h1>Products</h1>
 <ul>
 {
 data.products.map((product) => {
 const { title, description, thumbnail } = product;

 return (
 	 <li>
 <img src={thumbnail} alt={title} />
 <strong>{title}</strong>
 <p>{description}</p>
 	 </li>
 	 );
 	})
 }
 </ul>
</Main>

You can see the src file for this page in the repository here: src/pages/products.astro

The Contact Page

The contact page of my sample site uses a component that does require React, but rather than refactor the component to work in a world without React, I can leave it as it is and simply lift-and-shift it from my old React-based framework site, and drop it straight into my new Astro site — Lovely stuff!
---
import Main from '../layouts/main.astro';

import ContactForm from '../components/contact-form';
---

<Main title='Contact'>
 <h1>Contact</h1>
 <ContactForm client:only=”react”/>
</Main>
You can see the src file for this page in the repository here: src/pages/contact.astro The src for the contact form itself, which uses react-hook-form, can be found here: src/components/contact-form.jsx.

Lift-and-Shift React

This lift-and-shift approach is made possible because of Astro’s integrations. By installing and adding the React integration to the config, Astro (Vite) will know how to handle any files that use React, and more to the point, will only include React in the page that needs it. The result is that only the Contact Page sends the additional JavaScript required for React to work in the browser. All other pages remain as they were, with zero client-side JavaScript! You can see the difference by visiting the sample site and looking at the Network tab in your developer tools. The Home page (without React) is ~6kb, the Contact page (with React) is ~61kb! 👁 Screenshot of developers tools showing page size with and without React
And here’s a snippet of my updated astro.config.mjs file with the React integration added.
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify/functions';

+ import react from "@astrojs/react";

export default defineConfig({
 output: 'hybrid',
 adapter: netlify(),
+ integrations: [react()]
})
You can read more about integrations in the Astro docs here: @astro/react.

Final Thoughts

This is just a hypothetical migration of course, and just one scenario where React was being used for something quite trivial but, as I mentioned, I used a similar approach when migrating my site paulie.dev to Astro and it worked out beautifully. I think this approach of incrementally opting in or out of React offers a nice middle ground, where it’ll allow you to tackle a migration without getting into the weeds and refactoring every component. Perhaps later down the line, you might want to remove React completely, but that’s a job for another day! I hope I’ve been able to demonstrate how you can use Astro to incrementally adopt a “reduced JavaScript” approach to building websites; and for what it’s worth, it was kinda cool developing my new site without my “React brain”. It reminded me of a simpler time in web development and I rather enjoyed the walk down memory lane.
TRENDING STORIES
Paul is a Senior Software Engineer, Independent Developer Advocate and Technical Writer. More from Paul can be found on his site, paulie.dev.
Read more from Paul Scanlon
SHARE THIS STORY
TRENDING STORIES
SHARE THIS STORY
TRENDING STORIES
TNS DAILY NEWSLETTER Receive a free roundup of the most recent TNS articles in your inbox each day.
The New Stack does not sell your information or share it with unaffiliated third parties. By continuing, you agree to our Terms of Use and Privacy Policy.