Astro Islands in Practice: Static HTML with Focused Svelte Interactions
How this portfolio uses Astro for static structure and Svelte only where interaction, persistence, or local state requires hydration.

Astro starts from static HTML. A framework component becomes a client island only when a page explicitly chooses a client:* directive. That boundary is useful because it makes the cost and purpose of hydration visible in code.
This portfolio applies a simple rule: Astro owns structure, content, routes, metadata, and server-rendered markup; Svelte owns interactions that need browser state.
Astro for the Document
Layouts, navigation links, SEO metadata, content collections, blog articles, and the semantic home fallback are Astro components. They produce useful HTML without waiting for client JavaScript.
The projects route loads versioned collection data at build time and passes the localized result to one interactive island:
---
const entries = await getCollection('projects');
const projects = entries.map((entry) => mapProjectEntry(entry, 'en'));
---
<StickerAlbum projects={projects} lang="en" client:load />
The page does not fetch a database at runtime. Svelte receives a complete initial dataset and handles search, filters, URL state, and result announcements in the browser.
Svelte for Bounded Interaction
Svelte is used for the retro operating-system shell, persistent windows, accessible dialogs, media controls, project and credential filters, and deterministic execution replays. These surfaces need local state, event handling, or lifecycle cleanup.
Hydration still has to justify itself:
client:loadis reserved for interaction available immediately.client:mediacan prevent desktop-only chrome from hydrating on small screens.client:only="svelte"is limited to the desktop simulation that depends on browser APIs.- Static Astro content remains available when JavaScript is disabled.
React Is Not a Third Presentation System
The repository still contains isolated React-era components, icon modules, and runtime packages, but current public pages do not hydrate a React application or admin panel. The Astro React integration was removed after its consumers and generated output were audited; the remaining legacy source and packages require the same evidence before removal.
That distinction matters: installed source or packages are not evidence that a framework is part of the active runtime architecture.
Measure the Actual Route
Generic framework comparisons are not a performance budget. The Phase 5 quality gate measures generated HTML, JavaScript, CSS, images, audio, and opt-in DOOM assets in the local static artifact. Remote images have a separate availability and 512 KiB limit. A component is optimized only after its real consumer is confirmed.
The Decision in One Sentence
Use Astro until the interface requires state; hydrate the smallest Svelte boundary that provides that interaction; keep the static document useful underneath it.
