Islands Architecture Explained
Why Astro ships static HTML by default and hydrates only the interactive pieces you mark.
អាន 2 នាទី
Traditional single-page apps hydrate the entire page: the browser downloads a JavaScript bundle, and a framework like React takes over the whole document, re-rendering it client-side even though most of that markup never changes. Astro takes a different approach, called the islands architecture: the page is static HTML by default, and only specific components — the "islands" — ship JavaScript and become interactive in the browser.
The ocean and the islands
Picture a typical blog post page: a header, the article body, a footer, and — somewhere in the middle — a comment widget that needs to fetch and post data client-side. In a conventional SPA, the whole page is JavaScript-rendered to get that one widget working. In Astro, the header, article, and footer render as plain HTML with no JavaScript attached at all — the "ocean" — while only the comment widget is hydrated as an "island":
---
import CommentWidget from "../components/CommentWidget.jsx";
---
<article>
<h1>My Blog Post</h1>
<p>Static content — no JavaScript needed to display this.</p>
</article>
<CommentWidget client:load />Everything outside <CommentWidget> — the heading, the paragraph, the surrounding page — ships as inert HTML. Only CommentWidget includes a JavaScript bundle, and it's scoped to exactly the DOM it occupies.
Why this matters for performance
Shipping less JavaScript isn't just an aesthetic preference — it directly affects how fast a page becomes usable. Every kilobyte of JavaScript has to be downloaded, parsed, compiled, and executed before the browser can respond to input, and a framework's hydration step typically re-does work the server already did once (re-running render logic client-side to attach event listeners). A page with ten islands and a mostly-static layout downloads roughly ten components' worth of JavaScript, not the whole page's worth — often an order of magnitude less than a fully hydrated SPA rendering the same visual result.
Islands are independent
Each island hydrates on its own, unaware of the others. A search box island and a shopping cart island on the same page don't share a framework runtime or a global render tree — they're two separate, small applications that happen to sit on the same static page. This isolation is also why Astro can freely mix frameworks: nothing requires the search box and the cart to be written in the same UI library, because neither one needs to coordinate with a shared client-side tree the way components in a single SPA would.
What decides if something becomes an island
By default, importing a UI-framework component into an .astro file renders it to static HTML just like everything else — no JavaScript ships unless you explicitly add a client directive telling Astro to hydrate it. Those directives — client:load, client:idle, client:visible, and a few others — are the subject of the next lesson, and they're the one line of code standing between "static markup" and "interactive island" for any given component.