Using Astro Islands to Hydrate Only What You Need
Learn how Astro Islands let you hydrate only the components you need, reducing JavaScript payload while keeping pages fast.
10 Mar 2026, 08:20 UTC

Problem: Shipping Too Much JavaScript for Simple Interactivity
When you build a content‑heavy site with Astro, the default output is static HTML. Adding a small interactive widget—like a comment toggle or a live counter—often forces you to pull in an entire framework bundle, increasing the initial JavaScript payload and hurting Core Web Vitals.
Thesis: Astro Islands let you hydrate individual components on demand, keeping the rest of the page static while still delivering the interactivity you need.
How Islands Work
Astro renders the whole page to static HTML first. When you mark a component with a client:* directive, Astro emits a placeholder in the HTML and a separate JavaScript chunk that hydrates that component only when the condition defined by the directive is met (e.g., on page load, when idle, or when it becomes visible). The rest of the page remains plain HTML, so the browser can paint it quickly.
Choosing the Right Directive
client:load– hydrates immediately after the page loads.client:idle– waits until the browser’s main thread is idle.client:visible– hydrates when the component enters the viewport.client:only– skips server‑side rendering entirely; the component is rendered only on the client.
Pick the directive that matches the component’s priority and expected user interaction.
Worked Example: Adding a Reactive Counter with client:load
Assume you have a minimal Astro project (created with npm create astro@latest -- --template minimal) and you want a counter that increments when a button is clicked.
- Create a React component
src/components/Counter.jsx:
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return (
Count: {count}
setCount(c => c + 1)}>+1
);
}
- Import and use the component in a Markdown page (e.g.,
src/pages/counter.md) with theclient:loaddirective:
----
title: Counter Demo
---
Here is a live counter that stays interactive while the rest of the page stays static.
- Run the dev server (
npm run dev) and open the page. - Open Chrome DevTools → Network tab, reload the page, and look for the initial HTML response. You should see the markup for the counter but no JavaScript chunk named something like
Counter.[hash].jsin the initial request. - After the page finishes loading, a new request for that island’s JavaScript chunk appears. The counter becomes clickable, and the count updates.
- Inspect the page source (
View Page Source) – you will see an attribute likedata-astro-islandon the counter’s placeholder, indicating where the hydration script will attach.
To verify the build output, run npm run build and examine dist/assets. You will find a separate file for the Counter island (e.g., Counter-[hash].js) alongside the main page assets, confirming that the component’s JavaScript is not bundled into the primary page script.
Trade‑off and Limitation
While Islands reduce the initial JavaScript payload, creating many small islands can lead to numerous tiny JavaScript chunks. Each chunk incurs an HTTP request overhead, and if overused, the total transfer size may approach or exceed a single bundled approach. The practical way to check this is to run npm run build and use the --analyze flag (if you have @astrojs/addons-analytics installed) or a tool like webpack-bundle-analyzer on the generated assets to see the size and count of island chunks. If you notice many sub‑5 KB chunks, consider consolidating related interactions into a single island or using a less eager directive like client:idle.
Actionable Closing
Start small: pick one interactive element on your site, wrap it in an Island with a directive that matches its priority, and measure the difference in initial JavaScript size using DevTools → Network → Disable cache → reload. If the payload drops and the page feels faster, expand the pattern to other components, always keeping an eye on the number and size of island chunks generated by your build.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.