Deploying Qwik Apps
Resumable framework with lazy hydration, deploy Qwik City apps to Vercel, Cloudflare, Netlify, or Node.
PlatformsIntermediate
Why
Qwik's resumability means zero hydration JS — the browser picks up exactly where the server left off. This makes Qwik the fastest framework for large interactive sites, with lazy-loaded interactivity on interaction.
Platform-as-a-Service adoption grew 24% in 2024 as teams shift from VM management to git-push deploys. the cloud infrastructure market reached $330B in 2024, growing 22% year-over-year (Synergy Research), and PaaS layers capture the majority of new workloads.
When
Use Qwik for large interactive sites where hydration cost dominates (e-commerce, portals). Avoid if team lacks familiarity — ecosystem is newer than React/Vue.
How
1. Build — npm run build produces dist/ (adapter-specific)
2. Vercel — @builder.io/qwik/vercel adapter, zero config on git push
3. Cloudflare — @builder.io/qwik/cloudflare-pages
4. Netlify — @builder.io/qwik/netlify
5. Node — @builder.io/qwik/node, run node server/entry.express.mjs
6. Static — @builder.io/qwik/static for SSG
7. Components — use component$() for lazy-resumable components
Example
// src/routes/index.tsx — Qwik component
import { component$, useSignal } from "@builder.io/qwik";
export default component$(() => {
const count = useSignal(0);
return (
<button onClick$={() => count.value++}>
Count: {count.value}
</button>
);
});
// adapters/vercel/vite.config.ts
import { defineConfig } from "vite";
import { qwikVite } from "@builder.io/qwik/optimizer";
import { qwikCity } from "@builder.io/qwik-city/vite";
export default defineConfig({
plugins: [qwikCity(), qwikVite()],
});
// Deploy: npm run build && vercel --prod
Common Problems
- ⚠Using onClick instead of onClick$ — loses resumability, eager-loads handler JS
- ⚠Build fails on Cloudflare — Qwik City adapter version mismatch, pin compatible versions
- ⚠SSR not working — adapter not set or ssr disabled in vite config
Best Practices
- ✓Always use $-suffix APIs (component$, onClick$, useSignal) — they enable lazy resumability
- ✓Use useResource$ and useTask$ for async data — avoids waterfalls and enables streaming SSR
- ✓Set up health checks and graceful shutdown — handle SIGTERM to drain in-flight requests before exit