Islands — Intro

Interactive Components in a Sea of Static HTML

Islands — Intro

Astro renders everything as static HTML by default. An "island" is a component you opt into hydrating — and only that component ships JavaScript.

4 min read Level 2/5 #astro#islands#hydration
What you'll learn
  • Recognize what an island is
  • See the cost difference vs an SPA
  • Know when to make something an island

Astro’s superpower: static by default, JavaScript by exception. Every component renders to HTML on the server. If a component needs to be interactive in the browser, you mark it with a client:* directive, and ONLY that component ships JavaScript.

Each interactive component is an island.

What That Looks Like

---
import Header from "../components/Header.astro";   // pure HTML, no JS
import Counter from "../components/Counter.tsx";    // React component
---

<Header />
<main>
  <h1>Welcome</h1>
  <Counter client:load />                          {/* this is an island */}
</main>

The output:

  • Header and <h1> are HTML — no JS to load
  • Counter ships its React component code + just enough hydration shim to make it interactive

If you removed client:load, the Counter would still render — as plain HTML, with no behavior. The directive is what asks for hydration.

The Trade-Off vs SPA

Mental modelWhat ships
Astro static pageHTML only
Astro page with 1 islandHTML + that one component’s code + 1 framework runtime
Astro page with N islandsHTML + N components’ code + 1 shared runtime
Single-Page AppHTML shell + the whole app + framework + router

For content-driven sites with a few interactive widgets (a search box, a theme toggle, a comment count), Astro ships dramatically less JS than an SPA.

When To Make Something An Island

  • The user needs to click, type, or otherwise interact with it
  • It changes after page load (timers, fetches)
  • It uses browser APIs (localStorage, mediaQuery)

When NOT to:

  • Static content (text, layout, links) — leave it as HTML
  • Already pre-rendered data with no interaction — HTML again
  • Just because you “might want it later” — wait until you need it

How An Island Hydrates

Astro generates the island’s HTML on the server. The browser downloads a tiny “preload” snippet that, when the directive condition fires (load / idle / visible / etc.), fetches the component’s code and “hydrates” it — turning the static HTML into an interactive DOM.

The next few lessons cover the directives.

Up Next

client:load — the simplest directive.

`client:load` →