React in Astro

[check: …]
📖 Full guide → 📖 ASTRO_REACT_INTEGRATION.md — the complete narrative, code samples, and verified sources. This page is its interactive companion.

The island rule

Import a .tsx into an .astro file → it renders to static HTML on the server. A client:* directive decides when (or whether) React's JS ever wakes up. No directive → 0 bytes of JavaScript shipped.

Install once with npx astro add react (adds @astrojs/react + react/react-dom and registers the integration), then choose a directive per island. Most pages ship almost no JS.

no directive → static HTML, 0 JS client:load → instant, ships now client:visible → defers until scrolled in client:only → skips the server entirely

Directive explorer — pick one for the sample island

Each option shows the simulated JS shipped and time-to-interactive for one sample React island (an "Add to cart" button, React + component ≈ 45 KB). Numbers are an illustrative deterministic model of when hydration happens — the tradeoffs are the real point.

Sample island

Add to cart
static HTML — no JS attached
JavaScript shipped
Time-to-interactive (after load)

Pick a directive above.

The five directives on a timeline

Relative to page load, when each hydrates. client:load is immediate; client:idle waits for the browser to go idle; client:visible waits for the viewport; client:media waits for a media query; client:only is immediate but with no server HTML first.

Comparison — directive × hydration × JS × best for

This bundle is HOW React runs in Astro: @astrojs/react + the client:* directives. Cross-refs: 🔗 astro_islands (this is how islands are made) · 🔗 react_via_cdn (the React these components use) · 🔗 astro_rendering_modes (SSG/SSR).