Skip to content

Introduction: Astro for React Developers

You already know how to build UIs with React. You understand components, hooks, state, and JSX. Astro is not a replacement for that knowledge — it is a different delivery vehicle that reuses your React mental model where it matters and gets out of the way where it doesn’t.

The single biggest shift: React ships a JavaScript runtime to the browser and renders your UI there. Astro renders your UI on the server (or at build time) and ships HTML. JavaScript reaches the browser only for the parts that genuinely need interactivity.

For content-heavy sites — docs, marketing pages, blogs, landing pages — that difference is enormous: faster Time to First Contentful Paint, smaller bundles, and better Core Web Vitals with zero manual optimisation.

Next.js is a great full-stack React framework. Astro is the right tool when:

  • Your content outweighs your interactivity. Static pages, blogs, docs sites, and marketing sites ship almost no JavaScript with Astro by default.
  • You want to mix frameworks. Astro lets you drop in a React, Svelte, Vue, or Preact component side by side — or none at all.
  • You care about bundle size. Astro’s islands architecture means each interactive widget is independently hydrated; the rest of the page is plain HTML.
  • You want file-based routing without a client-side router. Every .astro page in src/pages/ becomes a URL — no Link component, no router config, no hydration overhead.
React / Next.jsAstro equivalent
.jsx / .tsx component file.astro component file
Function bodyFrontmatter (--- block)
return (<JSX />)HTML template below ---
props argumentAstro.props
children prop<slot />
useEffect / useStateFramework island with client:* directive
getServerSidePropsFrontmatter (fetch at build/request time)
Pages Router filesrc/pages/*.astro
  • JSX-like {expr} syntax in templates
  • Component composition (<Header />, <Footer />)
  • TypeScript everywhere (interface Props)
  • Your existing React components — drop them in as islands
  • npm/pnpm tooling, Vite under the hood
ModuleWhat you’ll learn
Intro (this module)Why Astro, islands architecture, setup, project structure, first page
Components.astro component anatomy, props, slots, expressions
LayoutsShared layouts, nested layouts, <slot /> patterns
RoutingFile-based routing, dynamic routes, 404 pages
Data Fetchingfetch in frontmatter, getStaticPaths, content collections
IslandsUsing React/Svelte/Vue components with client:* directives

Here is the smallest meaningful comparison: a React component that renders a hero section, versus the equivalent Astro page.

React
// src/app/page.tsx (Next.js App Router)
export default function HeroPage() {
return (
<html lang="en">
<head><title>My Site</title></head>
<body>
<h1>Hello from React</h1>
<p>This page ships a full React runtime.</p>
</body>
</html>
);
}
Astro
---
// src/pages/index.astro
const title = "My Site";
---
<html lang="en">
<head><title>{title}</title></head>
<body>
<h1>Hello from Astro</h1>
<p>This page ships zero JavaScript.</p>
</body>
</html>

The Astro page above ships no JavaScript to the browser — the title variable is evaluated once at build time and baked into the HTML. There is no React runtime, no hydration, no virtual DOM.

Astro
---
const framework = "Astro";
const audience = "React developer";
const year = new Date().getFullYear();
const features = ["Zero JS by default", "Islands architecture", "Use React components as islands", "File-based routing"];
---
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Welcome to {framework}</title>
    <style>
      body { font-family: sans-serif; max-width: 640px; margin: 2rem auto; padding: 0 1rem; }
      ul { line-height: 2; }
      li::marker { color: #6366f1; }
    </style>
  </head>
  <body>
    <h1>Welcome, {audience}!</h1>
    <p>This is an Astro page rendered in {year}. Check the browser DevTools — no JS bundle.</p>
    <h2>Why Astro?</h2>
    <ul>
      {features.map(f => <li>{f}</li>)}
    </ul>
  </body>
</html>
What does an Astro page ship to the browser by default?
When does the code inside an Astro frontmatter (--- block) run?
Which Astro feature lets you use a React component inside an Astro page?
What is the Astro equivalent of Next.js `getServerSideProps`?