Astro's islands architecture is the framework's central idea: a page ships as static HTML by default, and interactive components are isolated "islands" that hydrate independently, each with its own JavaScript bundle. This is the opposite default from a typical SPA framework, where the whole page is client-rendered unless you opt out — in Astro you opt in to client-side JavaScript per component, and most of a typical content site ships zero JS for the parts that don't need it.
How hydration directives work
A component becomes an island by adding a client:* directive when you use it in a template. client:load hydrates immediately on page load, client:idle waits for the browser's idle callback, client:visible hydrates when the component scrolls into the viewport via an IntersectionObserver, and client:media hydrates only when a CSS media query matches — useful for a mobile-only nav toggle that a desktop visitor never needs to pay for. Without any directive, the component renders to static HTML at build time and ships no JavaScript at all.
---
import SearchBox from '../components/SearchBox.jsx';
import Newsletter from '../components/Newsletter.jsx';
---
Why per-component hydration beats whole-page hydration
The performance case is straightforward: a blog post with a comment widget and a newsletter signup doesn't need the full weight of a client-side router or global hydration to render mostly-static prose. Each island loads independently, so a heavy interactive widget lower on the page doesn't block a lighter one higher up, and a visitor who never scrolls to the newsletter form never downloads its JavaScript. This is the mechanism behind Astro's default low JavaScript footprint compared to frameworks that hydrate the entire page tree.
Because each island hydrates independently, two islands on the same page do not automatically share state the way sibling components in a single SPA tree would. Cross-island communication needs an explicit mechanism — nanostores is the common choice in the Astro ecosystem — rather than React context or a shared store that assumes one hydration tree.
Framework-agnostic by design
Islands can be written in React, Vue, Svelte, Solid, Preact, or plain Astro components, and different islands on the same page can use different frameworks — each ships only its own runtime. This matters for incremental migration: a team moving off an older stack can introduce Astro pages that keep existing React components as islands while the surrounding page shell is plain Astro, without a full rewrite.
Choosing the right directive for a component
The directive choice is a judgment call about how soon a component needs to be interactive. Navigation and above-the-fold interactive elements usually warrant client:load. Anything below the fold — comment sections, related-content widgets, footers with interactive elements — is a good fit for client:visible, since it defers the JavaScript cost until the user is actually about to see it. client:only="react" skips server rendering entirely, useful for components that depend on browser-only APIs and would error during the server render pass.
A component using client:only renders nothing until JavaScript executes — there is no server-rendered placeholder. For anything above the fold or important for SEO, prefer a directive that still produces server-rendered HTML, and reserve client:only for genuinely browser-dependent widgets like a canvas-based chart.
| Directive | When it hydrates |
|---|---|
| client:load | Immediately on page load |
| client:idle | After the main thread is idle |
| client:visible | When scrolled into the viewport |
| client:media | When a CSS media query matches |
| client:only | Client-rendered only, no SSR pass |
Wrapping up
Islands architecture is worth adopting when most of a page's content is genuinely static and only a handful of components need interactivity — the default of zero JS unless you opt in is what keeps Astro sites fast without manual code-splitting. Pick the least eager hydration directive that still meets the UX requirement, and treat cross-island state sharing as something you build deliberately rather than something the framework gives you for free.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.