pattern

Islands Architecture

also called Partial Hydration, Selective Interactivity, Component Islands

Rendering a page as static HTML with independently-hydrated interactive regions, so JavaScript is shipped and executed only for the parts that need it rather than for the whole page.

hydrationjavascriptinteractivityperformancemobile

A conventional server-rendered single-page application hydrates the entire component tree on the client: the framework downloads, parses and executes the bundle, then re-runs every component to attach event handlers and rebuild state — including the header, the footer, the article text and everything else that will never respond to a click.

Islands architecture inverts the default. The page is static HTML, and interactivity is opt-in per region. Each interactive component is an island, hydrated independently, shipping only its own code.

Why it matters

During hydration the page looks finished and does nothing — clicks are dropped, inputs do not respond — and the visual completeness sets an expectation the page cannot meet. That interval is proportional to the JavaScript shipped and is paid on the user's device, so it is dramatically worse on mid-range mobile hardware than on the machine the developer tested on.

Islands attack the cause rather than the symptom. Most of a typical page does not need to be interactive at all, and every other mitigation — selective hydration, streaming, resumability — changes when the cost is paid or reduces it at the margin. Shipping less code is the only response that changes the order of magnitude.

Implementation patterns

  • Static HTML by default, interactivity declared explicitly per component, so the expensive option requires a decision.
  • Independent hydration per island, so a heavy widget does not delay a light one and a failure in one does not block the others.
  • Lazy hydration by trigger: on viewport entry, on first interaction, or on idle — so a component below the fold costs nothing until it matters.
  • Islands kept small and leaf-like. A large island containing most of the page has reintroduced whole-page hydration under a different name.
  • State shared between islands through a deliberate mechanism — URL, storage, a small shared store, or custom events — since islands are independent by design and cross-island state is the coupling that erodes the model.
  • Server components or equivalent for anything whose code should never reach the client at all.
  • Measured with interaction-to-next-paint and total blocking time on real devices, segmented by device class, because first contentful paint looks excellent in exactly the situation this addresses.

Industry example

The approach spread through frameworks built explicitly around it — Astro being the clearest instance — and its influence is visible in the wider ecosystem's direction: server components, selective hydration and resumability are all responses to the same finding, that whole-page hydration was a default nobody had justified.

The evidence driving adoption is consistently field data rather than lab scores: teams measuring interaction metrics on real mid-range devices found delays that their laboratory paint metrics had entirely concealed, which is the recurring lesson about where web performance is actually measured.

Failure scenarios

  • One large island wrapping most of the page, which is whole-page hydration renamed.
  • Cross-island state passed through a shared client store, coupling islands and forcing them all to hydrate.
  • Islands hydrating eagerly on load, discarding the lazy benefit.
  • A heavy shared dependency pulled into several islands and duplicated, unless the build deduplicates it.
  • Content that genuinely needs coordinated interactivity forced into the model, producing awkward communication between fragments.
  • Measuring paint rather than interaction, so the improvement is invisible and the effort is questioned.
  • Applying it to an application-like interface that is interactive throughout, where the model buys little.

Trade-offs

Islands suit content-dominant pages with pockets of interactivity — publishing, commerce, marketing, documentation. They suit application interfaces far less, where most of the surface is interactive and the model's overhead buys little; a dashboard is not a page with islands, it is an island.

The model also constrains architecture: shared state between islands is deliberately awkward, which is correct for the intended use and a genuine obstacle when requirements evolve toward richer interaction. Teams frequently discover a page has become application-like and the island boundaries now fight them.

The trade is cross-component interactivity and framework flexibility in exchange for shipping an order of magnitude less JavaScript. For content-heavy products serving mobile users on mid-range devices, that is decisively the right trade — and for a heavily interactive application behind authentication, the conventional model remains the better fit.

Interview question

"Our article pages score well on paint metrics and users say the page freezes for a few seconds after it appears. Explain what is happening, tell me what you would change structurally rather than by optimisation, and tell me which metric would show that it worked."