javascript-today

Astro, SvelteKit, and the Framework-Agnostic Frontend: A 2026 Comparison

If you’ve picked a meta-framework in the last few years, you’ve probably noticed the industry splitting into two camps: frameworks that assume your site is an application (ship JS everywhere, hydrate everything), and frameworks that assume your site is content (ship almost nothing, hydrate only what asks for it). Astro and SvelteKit sit on opposite sides of that split, and that difference matters more than most feature comparisons let on — especially if you want the freedom to drop in a React component here and there without marrying React for the whole project.

Here’s a practical breakdown, including a few less-hyped options that fit the “agnostic core, React island when needed” pattern better than people realize.


What “framework-agnostic” actually means here

Two different things get called “framework-agnostic” and it’s worth separating them:

  • True multi-framework islands — you can write one component in React, another in Svelte, another in Vue, all inside the same project, and the meta-framework doesn’t care. Astro is the reference implementation of this.
  • Bring-your-own-runtime hydration — the framework has no opinion on UI libraries at all; you wire up whatever hydration strategy you want yourself, often via a small islands plugin. Eleventy fits here.

SvelteKit is neither. SvelteKit is a Svelte framework, full stop. There’s no supported way to mount a React component inside a SvelteKit route without hacks (rendering to a portal div and manually bootstrapping React yourself).


Astro: the reference implementation

Astro ships zero JavaScript by default. Every page compiles to static HTML, and JavaScript is opt-in per component via island directives — client:load, client:visible, client:idle, client:only. Astro’s own components (.astro files) have no client-side runtime at all; they’re server-rendered templates.

The part that matters for this comparison: Astro doesn’t care what UI library your interactive islands are written in. React, Vue, Svelte, Solid, and Preact components can all live in the same project side by side, each hydrated independently. This is genuinely the differentiator — you can build your marketing site in plain Astro, drop in a React component for a checkout widget because that’s what your team already knows, and use a Svelte component elsewhere because it’s lighter for that one job.

What it does well:

  • Best-in-class Core Web Vitals for content-heavy sites (blogs, docs, marketing, storefronts) since JS is opt-in, not default
  • Genuinely stable multi-framework support — this isn’t a bolt-on, it’s core to how Astro works
  • Content collections and a solid file-based routing story for static and hybrid sites
  • Was acquired by Cloudflare in early 2026 with a public commitment to keep it open source under MIT, which settles a lot of “will this still be maintained” anxiety

Honest caveats:

  • It assumes your site is mostly static. If you’re building a SaaS dashboard where nearly every view is dynamic and stateful, you’re fighting the islands model instead of benefiting from it
  • Mixing multiple UI frameworks in one project is powerful but easy to overdo — every framework you add is another client runtime shipped somewhere, and another set of dependencies to keep current

If the project is primarily content with pockets of interactivity, Astro is the default answer in 2026.


SvelteKit: the honest exception

SvelteKit assumes your site is an application. Every route ships JavaScript because the framework expects users to interact, navigate client-side, and mutate state continuously. Svelte 5’s compiler produces some of the leanest interactive bundles of any framework — genuinely faster in practice than React or Vue equivalents at similar complexity.

What it does well:

  • Compiled reactivity means less runtime overhead per component than virtual-DOM frameworks
  • Full-stack primitives (load functions, form actions, server routes) that feel considered rather than bolted on
  • Best-in-class developer experience if your team is committed to Svelte

Honest caveats:

  • Not agnostic in any meaningful sense — you’re all-in on Svelte for the whole app
  • No supported path to embedding React components; if a team member ships something in React because that’s what they know, it doesn’t fit here without real friction

Include SvelteKit in the comparison when the question is “best app-first framework,” not when the question is “can I mix in React later.” Those are different questions with different right answers.


Qwik City: resumability instead of hydration

Qwik takes a different approach to the same problem Astro solves. Instead of hydrating components on load (or on visibility, like islands), Qwik serializes execution state directly into the HTML and resumes exactly where the server left off — no replaying component logic on the client at all until a user actually interacts.

The React story here is real, not theoretical: the qwikify$() helper wraps an existing React component, runs it through renderToString() during SSR, and only calls hydrateRoot() when your specified trigger fires. Each qwikified React component is isolated, similar in spirit to an Astro island, but the surrounding app is Qwik-native rather than framework-neutral by design.

What it does well:

  • Resumability sidesteps the hydration cost entirely for the un-interacted parts of the page — genuinely different math than islands
  • qwikify$ makes dropping in existing React components low-friction if you’re migrating gradually rather than rewriting

Honest caveats:

  • Smaller ecosystem and community than Astro or SvelteKit; you’ll hit more rough edges and fewer Stack Overflow answers
  • The mental model (resumability, serialization) has a real learning curve compared to “just hydrate this component”

Worth serious consideration if you’re migrating an existing React app piece by piece and want to shed hydration cost as you go, rather than adopting islands wholesale.


Eleventy + is-land: DIY islands, zero lock-in

Eleventy isn’t a component framework at all — it’s a static site generator with no client-side runtime opinions whatsoever. Paired with @11ty/is-land, a small web-component-based islands library, you get the islands pattern without adopting any particular meta-framework’s opinions about routing or SSR. is-land is deliberately unopinionated about what’s inside the island — React, Vue, Svelte, vanilla JS, whatever you point it at — and the same package is used by Eleventy, WebC, Slinkity, and even SvelteKit projects that want more granular hydration control.

What it does well:

  • True zero-lock-in — you’re not betting on a meta-framework’s roadmap, just a template engine and a hydration primitive
  • Loading conditions (on:visible, on:idle, on:interaction, on:media) map closely to Astro’s client directives, so the concepts transfer

Honest caveats:

  • You’re assembling the pieces yourself. There’s no built-in dev-server component reloading or typed props story the way Astro provides — expect more manual wiring
  • Best suited to teams that already know Eleventy’s templating model; it’s not a drop-in replacement for a full meta-framework if you need SSR data fetching, API routes, or server actions

Good fit if the project is genuinely simple (a marketing site, a docs site) and you want the lightest possible dependency footprint rather than a full framework.


htmx: skip the component model entirely

Everything above is a variation on the same theme — pick which framework hydrates your interactive pieces. htmx opts out of that question completely. There’s no client-side component model, no hydration lifecycle, no virtual DOM. HTML attributes (hx-get, hx-post, hx-trigger, hx-target) trigger AJAX calls, and the server responds with HTML fragments that htmx swaps directly into the page. The library itself is roughly 14KB and requires no build step. The server — not the client — stays the single source of truth for application state, which is why this pattern gets called “hypermedia-driven” rather than component-driven.

Because htmx has zero opinion about how pages are built, it pairs naturally with every static-first tool on this list, provided you put a real backend behind it:

  • Hugo + htmx + Go is the most fleshed-out version of this. Hugo builds the static shell; a small Go server (using html/template or templ) handles the endpoints htmx calls for forms, comments, votes, or any dynamic fragment. The hugo-htmx-go-template starter project even ships a bin/build script that compiles the entire Hugo site and the Go API into a single fat binary, deployable as one file.
  • Eleventy + htmx is the same idea with a Node backend instead of Go — Eleventy for the static build, htmx pointed at whatever API you stand up.
  • Astro + htmx is less common but workable — Astro’s built-in API routes can serve as the htmx backend, though at that point you’re running two interactivity philosophies (islands and hypermedia) in one project, which is worth a deliberate decision rather than an accident.

What it does well:

  • No client framework to choose, version, or hydrate at all — for CRUD-heavy interactions (forms, filters, tables, search, pagination), this eliminates an entire category of frontend complexity
  • Pairs with literally any server that can render HTML, which makes it a natural fit for the static generators covered above rather than a competing framework

Honest caveats:

  • It needs a real backend behind the static shell to do anything dynamic — unlike is-land, this isn’t a client-only trick, so it adds an actual server component (and its deployment story) to what was otherwise a static site
  • Falls apart for anything needing fine-grained client state at high frequency — rich text editors, drag-and-drop boards, real-time collaborative UIs. Those still want a real component framework, often as a single island dropped into an otherwise htmx-driven page

The pragmatic pattern gaining traction in 2026 is a hybrid: htmx for routine server-driven interactions, a React (or Svelte, or Vue) component mounted as a self-contained island only where the interaction genuinely needs local client state. That’s not a contradiction of the islands approach — it’s islands with a much smaller default surface area.


Honorable mention: Marko

Marko, eBay’s in-house framework, deserves a mention for a different reason: it automates the island decision for you. The compiler analyzes your templates and decides what needs hydration — static content like headers and footers never ships JS, while forms and interactive widgets automatically become islands, without directive syntax. It’s arguably the most efficient MPA framework available for server-rendered pages.

It’s not React-friendly in the same casual way as Astro or Qwik, though — Marko has its own component syntax and there’s no first-class “just drop a React component in” story. Worth knowing about if raw server-rendering performance is the top priority and your team is willing to learn Marko’s own model rather than reuse existing React components.


Quick reference

Framework Default JS Multi-framework components Best fit
Astro Zero, opt-in per island Yes — React, Vue, Svelte, Solid, Preact Content sites with pockets of interactivity
SvelteKit Ships on every route No — Svelte only Interactive apps, full Svelte commitment
Qwik City Resumed, not hydrated Via qwikify$ for React specifically Gradual React migrations, resumability wins
Eleventy + is-land Zero, opt-in per island Yes — bring your own Simple sites, minimal dependency footprint
htmx (+ any static generator) Zero component JS, server sends HTML fragments N/A — no client component model at all CRUD-heavy interactions, forms, dashboards
Marko Auto-detected per island No — Marko syntax only Max server-render performance, MPA

Which one to actually reach for

If the project is content-first and you want real freedom to mix React, Vue, or Svelte components without committing to one ecosystem, Astro is the clear default in 2026 — it’s the most mature implementation of that idea and now has Cloudflare’s backing. If you’re migrating an existing React codebase incrementally and want to shed hydration cost along the way, Qwik City’s qwikify$ path is worth a serious prototype before committing. If the site is simple enough that a full meta-framework feels like overkill, Eleventy plus is-land gets you the islands pattern with the least buy-in. And if most of the interactivity you need is forms, tables, and CRUD rather than rich client state, htmx paired with a static generator and a thin backend often removes the need to pick a component framework at all.

SvelteKit is a strong choice — arguably the best compiled-framework app experience available — but it should be chosen on its own terms as an app-first, Svelte-only framework, not evaluated as an agnostic option. If cross-framework component reuse matters to the project, that’s the one item on this list to rule out early rather than discover later.