Back to blog
astro svelte react micro-frontends islands-architecture performance frontend-architecture

Micro-frontend Architecture with Astro Islands: Mixing React and Svelte

Why Astro's Island Architecture makes mixing React and Svelte a first-class pattern — and how to decide which framework gets which component based on bundle size and reactivity needs.

· 6 min
Component architecture diagram

Shipping a page from a monolithic React SPA means sending the entire component tree to the browser — including parts that never change. Astro’s Island Architecture inverts this default: everything is static HTML unless you explicitly opt a component into hydration.

This changes how you think about framework selection.

What Astro Islands Actually Are

An “island” is an interactive component embedded in an otherwise static page. The surrounding HTML ships with zero JavaScript. The island ships only what it needs, hydrated independently.

---
import StaticCard from '@components/Astro/Card.astro';
import FilterComponent from '@components/Svelte/FilterComponent.svelte';
import SkillsDashboard from '@components/React/SkillsDashboard';
---

<!-- Zero JS — pure HTML -->
<StaticCard title="Portfolio" />

<!-- Svelte hydrated only when scrolled into view -->
<FilterComponent client:visible />

<!-- React hydrated immediately — critical interactivity -->
<SkillsDashboard client:load />

The client:* directive is the hydration boundary. Without it, even React and Svelte components render as static HTML.

The Framework Selection Decision

Using two frameworks in one project isn’t a flex. It’s a deliberate tradeoff. Here’s the actual reasoning:

React for complex, interconnected state. The admin panel and skills dashboard manage multiple data sources, derived state, and optimistic updates. React’s ecosystem — useReducer, React Query, the mature tooling — handles this better than Svelte’s simpler model at scale.

Svelte for lightweight, local reactivity. The navigation, filter component, and card interactions are self-contained. Svelte compiles to vanilla JS with no runtime — the bundle impact is minimal. A filter component that needs to react to user input doesn’t need a virtual DOM.

The bundle difference is measurable:

ComponentFrameworkGzipped JS
FilterComponentSvelte~4 KB
Equivalent in ReactReact~42 KB + React runtime

For a component that ships on every page, that delta compounds.

Hydration Strategies

Astro exposes five client directives, each with a distinct performance profile:

  • client:load — hydrate immediately on page load. Use for above-the-fold interactive components.
  • client:idle — hydrate when the browser is idle. Use for non-critical widgets.
  • client:visible — hydrate when the component enters the viewport. Use for below-the-fold content.
  • client:media — hydrate only when a CSS media query matches. Use for responsive-only interactions.
  • client:only — skip SSR entirely, render on client only. Use when the component requires browser APIs unavailable during SSR.

The practical rule: default to client:visible, promote to client:load only when the user’s first interaction depends on it.

What This Looks Like in Production

The portfolio ships with React for the admin panel and skills visualization, Svelte for all public-facing interactive components (nav, filters, cards), and Astro for everything structural. The result is a page that ships near-zero JavaScript to visitors who don’t interact with the interactive islands.

The tradeoff isn’t “which framework is better.” It’s “what does this specific component need, and what’s the cost of shipping that to every user?”