astro islands

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

The one idea — zero JS by default

An Astro page is a sea of static HTML. Islands are the bits that get hydrated — the rest ships zero JS. An SPA, by contrast, hydrates everything.

Astro components (.astro) render to static HTML with no client-side runtime. A framework component (React, Svelte, Vue…) only ships JavaScript when you opt it in with a client:* directive. Toggle islands below and watch the JS-shipped counter drop.

no client:* → static HTML, 0 JS client:load → hydrate now client:visible → hydrate when scrolled to client:only → skip server render

JS shipped to the browser — live

0 KB
Astro — your current config
vs
100 KB
if this were an SPA (hydrate everything)
0 / 4
islands hydrated
not loaded
React runtime (~45 KB)

The zero JS preset is the gold-check state: every framework component renders to static HTML and the page ships 0 KB of JavaScript.

The page — toggle which components are islands

A sample blog-post page, top to bottom. The .astro components are static HTML — they never ship JS. The framework components (.tsx) let you pick a client:* directive; pick none and Astro renders them to plain HTML too.

static HTML (in the sea — 0 JS) hydrated island (ships JS)

Before / after — SPA “hydrate everything” vs Astro “hydrate only islands”

SPA model hydrate everything

100 KB
React runtime + client router + every component's bundle
  • One monolithic JS app hydrates the whole page top-down
  • A slow component blocks the rest — there is a root that must init first
  • The router itself is JS the user must download even to read text

Astro model hydrate only islands

0 KB
React runtime only if ≥1 island; no SPA router ever
  • The page is real HTML — readable before any JS loads
  • Each island hydrates independently; one slow island never blocks another
  • No framework runtime at all until you explicitly opt in

The client:* directives — reference

From the Astro directives reference: with no client:* directive, a framework component's HTML is rendered onto the page without JavaScript. Each directive below opts it into hydration on a different schedule.

DirectivePriorityWhen it hydratesShips JS?Use for
(none)never — server-rendered HTML onlyNOthe default; anything that doesn't need to be interactive
client:loadHighimmediately on page loadyesimmediately-visible UI that must be interactive ASAP (buy button)
client:idleMediumrequestIdleCallback / load eventyeslower-priority UI that doesn't need to be instant (show/hide toggle)
client:visibleLowIntersectionObserver — enters viewportyesbelow-the-fold or heavy widgets (image carousel, comments)
client:mediaLowa CSS media query matchesyessidebar toggle that only exists on small screens
client:onlyclient-only — skips server render entirelyyescomponents that can't render on the server (depends on window); you MUST pass the framework, e.g. client:only="react"
This bundle is an explainer/simulator — it does not run a real Astro build. It visualizes Astro's Islands Architecture with a curated page model and JS-budget math (React ~45 KB runtime, SPA router ~30 KB, per-component bundles). Verified against the Astro docs and Jason Miller's original islands post. Cross-refs: 🔗 metaframework landscape (why Astro wins for content) · 🔗 astro_react_integration (the client:* directives in depth).