How to Add a React Component to Astro (Your First Island)
Add React to an Astro site with one command, build a counter component, and turn it into an island that works in the browser.
Tested on Astro 7.4

In this guide
React is a tool for making parts of a page that respond to clicks. Its pieces are called components. They work inside Astro pages. You only pay for their JavaScript on the parts that need it. JavaScript is the code that makes a page do things. This guide adds React. Then it builds a small counter. Then it makes the counter work.
Step 1: Add React
Run this in your project folder. Say yes to the changes:
npx astro add react
The command does three things. It installs React. It adds the integration to astro.config.mjs. An integration is an add-on for Astro. It also updates your TypeScript settings. Restart the dev server after that.
Step 2: Write a component
Create src/components/Counter.jsx:
import { useState } from 'react';
export default function Counter({ start = 0 }) {
const [count, setCount] = useState(start);
return (
<button onClick={() => setCount(count + 1)}>
Clicked {count} times
</button>
);
}
This is plain React. Nothing in it is special to Astro.
Step 3: Use it on a page
Open any page. Import the component:
---
import Layout from '../layouts/Layout.astro';
import Counter from '../components/Counter.jsx';
---
<Layout title="Counter">
<h1>My first island</h1>
<Counter start={5} client:load />
</Layout>
Look at the page. The button says “Clicked 5 times”. Click it. The number goes up.
Step 4: See what the directive does
Remove client:load. The tag should now read <Counter start={5} />. Save. Click the button again. Nothing happens.
That is not a bug. The missing part is called a client directive. It tells Astro to send JavaScript for this piece. Without it, Astro draws the component once on the server. It sends plain HTML. HTML is the basic code of a web page. It is the same React code. It just has no JavaScript attached. Put client:load back.
This is the heart of Astro islands. An island is a piece of a page that gets its own JavaScript. You choose which pieces do.
Step 5: Choose when it loads
client:load wakes the component up as soon as the page loads. Is the piece lower down the page? Then use client:visible. It waits until the piece scrolls into view:
<Counter client:visible />
We tested all five directives. Our guide to client directives tells you which one to use when.
Passing information in
Props are values you pass into a component. They work as you would expect. There is one rule for an island. The values must be simple. Strings, numbers, arrays and plain objects are fine. You cannot pass a function to an island. The value has to travel to the browser.
What it costs
We ran a test build. The counter’s own code was tiny. But the React code it needs was about 207 KB before compression. One island pays that cost. A second React island on the same page shares it. Do you only need a menu toggle? Then a plain script may be the better choice. See do you need React with Astro?
Frequently asked questions
Can I use Vue or Svelte instead of React?
Yes. Run npx astro add vue or npx astro add svelte. The rest of this guide works the same way. Astro also supports Preact and SolidJS.
Why doesn't my button do anything?
You most likely forgot the client directive. Without it, the component is plain HTML with no JavaScript. Add client:load to the tag.
Can a React component include an Astro component?
No. It works the other way round. Astro components can include React ones. To put Astro content inside a React component, pass it as children from the Astro file.
Stuck on a step?
Check the common errors guide, look up a word in the glossary, or ask the friendly people in the official Astro and EmDash Discords. How to ask so people can help.
