Qwik: Betting on Resumability Instead of Hydration
Actualizado: 2026-05-03
Hydrating a React or Vue application means re-running on the browser the same code that already ran on the server, just to recover the event handlers and state tree that were lost when the HTML was serialised. It is a silent tax paid on every load: the bundle downloads, parses and executes before the button responds. Qwik, the framework Misko Hevery (creator of Angular) drives from Builder.io, attacks the problem at the root with a different idea — resumability: instead of rehydrating, the client resumes execution where the server left off, and downloads code only when needed.
Key takeaways
- The initial application bundle is literally zero kilobytes: the HTML arrives complete and Qwik’s runtime (~4 KB) listens globally.
- The
$marker is not syntactic sugar — it is the lazy-loading boundary the Vite compiler respects to generate independent chunks per event. - In Lighthouse, Qwik landing pages consistently achieve TTI below 0.5s and LCP around 0.6s.
- The advantage grows with size: on a shop with 50 components, Next.js hydrates the full visible tree; Qwik only downloads the handler for the button that was pressed.
- Not for everyone: teams with React investment, realtime collaborative apps, or near-static sites have better alternatives.
Resumability versus hydration
In the classic model the server renders HTML, the browser paints it and then downloads the JavaScript bundle — between 100 and 300 KB on medium apps — to reconstruct state and attach listeners. Until that finishes, the page looks alive but does not respond: this is what Lighthouse measures as the gap between First Contentful Paint and Time to Interactive.
Qwik does something else. The server serialises into the HTML itself everything needed — state, references to handlers, closure captures — inside attributes and a JSON block at the end of the document. The client downloads HTML and nothing more. A tiny runtime of a few kilobytes listens to events globally via delegation; when the user clicks a button, Qwik knows which chunk to request and fetches it right then. The page is interactive from the first byte, even though the code behind each action arrives on demand.
The piece that makes this possible is the $ marker. When we write onClick$ or wrap a component in component$, the Qwik compiler (Vite-based) cuts the dependency graph there and generates an independent chunk. That symbol is not syntactic sugar: it is the lazy-loading boundary the optimiser respects. That is why components look very close to React, yet the resulting bundle looks nothing like it.
import { component$, useSignal } from '@builder.io/qwik';
import { routeLoader$ } from '@builder.io/qwik-city';
export const useUser = routeLoader$(async ({ params }) => {
return await db.user.findById(params.id);
});
export default component$(() => {
const user = useUser();
const count = useSignal(0);
return (
<section>
<h1>{user.value.name}</h1>
<button onClick$={() => count.value++}>
Visits: {count.value}
</button>
</section>
);
});
What the numbers say
On landing pages and blogs with some interactivity, benchmarks published through 2024 are consistent:
- Lighthouse: score of 100.
- TTI: below 0.5 seconds.
- LCP: around 0.6 seconds.
- Initial bundle: zero kilobytes of application JavaScript.
An equivalent Next.js tends to sit between 80 and 150 KB of initial JS and a TTI of 1 to 2 seconds on 4G. The gap is not marginal, and it widens on mobile with slow networks — exactly where Google penalises the hardest on Core Web Vitals.
The important nuance: those numbers stay sustainable as the application grows, because interactivity cost is proportional to what the user actually touches, not to total code size. Comparing with SvelteKit 1.0 and its real adoption gives perspective: SvelteKit also has small bundles, but it doesn’t solve the hydration problem the same way.
Qwik City and the ecosystem
Qwik City is to the framework what SvelteKit is to Svelte: file-based routing, routeLoader$ for server-side data, routeAction$ for forms, SSR by default and stable adapters for Vercel, Cloudflare Pages, Netlify, Node and static deployment. With Qwik 1.5, released in March 2024, adapters stopped throwing surprises in production and the Vite 5 integration is solid.
The ecosystem is still small compared to React:
- Components: Qwik UI and Modus.
- Forms:
modular-forms. - Global state: built-in signals usually suffice.
- Testing: Vitest and Playwright.
- React interoperability:
qwik-reactallows islands, at the cost of losing resumability on those nodes.
Where it pays off and where it does not
Qwik shines when the critical metric is TTI on mobile and the page has real interactivity but is not a massive-state SPA: e-commerce, content portals with comments, marketing sites with configurators, public dashboards. In those scenarios the zero bundle converts directly into revenue — every 100ms of LCP improvement moves the needle on mid-sized shops.
Qwik doesn’t pay off in equally clear cases. A team with years of React investment pays a steep migration cost. For very client-heavy apps — collaborative editors, realtime tools — the code ends up loading anyway and Qwik doesn’t add as much versus a well-partitioned Next.js. For sites that are almost static with occasional interactive islands, Astro remains a simpler choice with direct React ecosystem access.
Real adoption
Adoption is in an early phase: Builder.io uses Qwik for its own marketing, Daily.dev integrates it partially, there are reported cases in mid-sized shops as Shopify Hydrogen alternatives, and some European agencies sell it as a competitive edge on Core Web Vitals. It is not a mainstream stack, but the resumability concept already influences other frameworks: React Server Components chase a similar goal by a different path.
Conclusion
Qwik solves a real problem well and does it with an idea that deserves to exist. For a greenfield project where performance is a KPI and the team can afford a new paradigm, it is a defensible choice and technically superior to nearly any alternative in the on-demand interactivity scenario. For everyone else — the majority — SvelteKit, Astro or Next.js with App Router remain safer bets. Qwik does not need to win the framework war to have left a mark: it has already proved hydration is not inevitable, and that shifts the yardstick for the rest.