DEV Community

Cover image for Islands Architecture in Practice – A Deep Dive
Md Enayetur Rahman
Md Enayetur Rahman

Posted on

Islands Architecture in Practice – A Deep Dive

#LearningPatterns50   |   Based on “Learning Patterns” by Lydia Hallie & Addy Osmani

Table of Contents


What Sparked Islands Architecture?

Single‑Page Applications (SPAs) gave us fluid UX but at a heavy cost: large JS bundles, hydration delays, and poor first‑page performance. Islands Architecture emerged as a middle path:

  • MPA ergonomics – ship mostly static HTML for fast TTFB and reliable SEO.
  • Targeted interactivity – hydrate only the parts that need it, shrinking JS and CPU usage.

The term was popularized by Addy Osmani’s 2019 post “The Cost Of JavaScript Frameworks” and later formalized in Learning Patterns.


Islands of Dynamic Components Explained

An island is a self‑contained, interactive component surrounded by inert, static HTML (the “ocean”).

+--------------------------------------------------------+
|             Static hero section (pure HTML)            |
|  +-----------------------------------------------+     |
|  |  <SearchBox/>   ← interactive island (hydrated) |   |
|  +-----------------------------------------------+     |
|      Static marketing copy (no client JS)            |
|  +-----------------------------------------------+     |
|  |  <SubscribeForm/>  ← another island             |   |
|  +-----------------------------------------------+     |
+--------------------------------------------------------+
Enter fullscreen mode Exit fullscreen mode

Only the SearchBox and SubscribeForm download/execute JS; everything else remains lightweight markup.


Implementing Islands — The Core Mechanics

  1. Server renders full HTML for the page.
  2. Interactive components embed a tiny marker (e.g. data-island="ComponentName") plus their serialized props.
  3. On the client, a micro‑runtime scans the DOM, lazy‑loads each component bundle, and mounts it into its placeholder.
  4. Each island runs in isolation; no global SPA router required.

This is essentially partial hydration.


Ecosystem & Framework Support

Framework Islands Support Notes
Astro ✅ Built‑in (client:only, client:visible, etc.) Zero JS by default
Qwik ✅ Resumability + island hydration (q:scoped) Ultra‑deferred execution
Slinkity ✅ Islands on top of Eleventy Great for static sites
Marko 6 ✅ Streaming islands (<client> tag) Hydrates only when needed
Fresh (Deno) ✅ Per‑component islands Runs on Deno Deploy

DIY: A Minimal Islands Implementation

Below is a tiny proof‑of‑concept with Astro.

1 · Install Astro

npm create astro@latest my‑islands‑demo
cd my‑islands‑demo && npm i
Enter fullscreen mode Exit fullscreen mode

2 · Create an Island Component (src/components/Counter.jsx)

import { useState } from "react";

export default function Counter({ initial = 0 }) {
  const [count, setCount] = useState(initial);
  return (
    <button
      className="px-3 py-2 rounded bg-blue-600 text-white"
      onClick={() => setCount(c => c + 1)}
    >
      Count: {count}
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

3 · Use the Island in a Page (src/pages/index.astro)

---
import Counter from "../components/Counter.jsx";
---

<html lang="en">
  <body>
    <h1>Islands Demo</h1>

    <!-- 👇 Hydrate this component only when it becomes visible -->
    <Counter client:visible initial={5} />

    <p>No other JS was shipped!</p>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Run npm run dev and inspect the network tab—only ~1 KB of JS for the counter.

Vanilla Roll‑Your‑Own (Optional)

If you can’t switch frameworks, you can sprinkle islands into any SSR stack:

<!-- server‑rendered -->
<div id="search" data-props='{"term": ""}'></div>
<script type="module">
  import SearchBox from "/static/search.js";
  const el   = document.getElementById("search");
  const props = JSON.parse(el.dataset.props);
  SearchBox.mount(el, props);      // your own mini runtime
</script>
Enter fullscreen mode Exit fullscreen mode

Pros & Cons

✅ Pros ❌ Cons
Lower JS payloads – only hydrate what’s necessary. Mental model shift – designers/devs must think in islands.
Great Core Web Vitals – faster FCP, TTI. State sharing between islands can be tricky (requires events or server).
Progressive enhancement out of the box. Tooling lock‑in if you lean on a specific island framework.
SEO‑friendly – full HTML delivered up front. Not a silver bullet for highly interactive dashboards (might still need SPA techniques).

Conclusion

Islands Architecture re‑balances the SPA/MPA spectrum: deliver static HTML for speed, sprinkle interactivity where it actually adds value. Frameworks such as Astro and Qwik automate the heavy lifting, but you can experiment with your own mini‑runtime today.

If your next project is content‑heavy with just a few interactive widgets, give islands a try—you might never look back at full‑page hydration.

Happy shipping, and see you in the next pattern! 🚀

Top comments (0)