Sharing State Between Islands

Each Island Is Independent — Reach for a Shared Store

Sharing State Between Islands

Two islands can't share React state directly. Use a framework- agnostic store like nanostores when they need to.

4 min read Level 2/5 #astro#state#islands
What you'll learn
  • Recognize the cross-island problem
  • Use nanostores to share state
  • Know when DOM events are simpler

Each island hydrates as its own root — they don’t share React/Vue context. When two islands need the same value (a cart count in the header AND a cart drawer), reach for a shared store.

The Tiny Standard: nanostores

nanostores is a 300-byte state library that works with every framework Astro supports. The idiomatic choice for cross-island state.

npm install nanostores

A Shared Store

// src/stores/cart.ts
import { atom } from "nanostores";

export const cartItems = atom<string[]>([]);

Using It In React

// src/components/CartCount.tsx
import { useStore } from "@nanostores/react";
import { cartItems } from "../stores/cart.ts";

export default function CartCount() {
  const items = useStore(cartItems);
  return <span>Cart ({items.length})</span>;
}

Updating From Anywhere

// src/components/AddToCart.tsx
import { cartItems } from "../stores/cart.ts";

export default function AddToCart({ id }: { id: string }) {
  return (
    <button onClick={() => cartItems.set([...cartItems.get(), id])}>
      Add
    </button>
  );
}

Both islands subscribe to the same store. Click “Add” → the count updates instantly.

Vue / Svelte / Solid

@nanostores/vue, @nanostores/svelte, @nanostores/solid all work the same way — same store, different subscription hook per framework.

A Lighter Alternative — DOM Events

When the interaction is small (header counter, modal toggle), a plain custom DOM event might be enough:

// AddToCart island
function add() {
  document.dispatchEvent(new CustomEvent("cart:add", { detail: { id } }));
}

// CartCount island (or a plain <script>)
let count = 0;
document.addEventListener("cart:add", () => setCount(++count));

Fewer dependencies, similar effect for simple cases.

Chapter Done

That wraps islands and interactivity. Next chapter steps off the static path — server rendering, endpoints, forms.

Static vs Server →