Qwik is the framework that invented resumability — your app loads instantly because it never re-executes code the server already ran.
Routes: File-Based with Layouts
src/routes/
layout.tsx → Root layout
index.tsx → /
products/
layout.tsx → Products layout
index.tsx → /products
[id]/
index.tsx → /products/:id
routeLoader$: Server Data
import { routeLoader$ } from "@builder.io/qwik-city";
import { component$ } from "@builder.io/qwik";
export const useProducts = routeLoader$(async ({ query }) => {
const category = query.get("category");
const res = await fetch(`https://api.example.com/products?category=${category}`);
return res.json();
});
export default component$(() => {
const products = useProducts();
return (
<div>
{products.value.map((p) => (
<div key={p.id}>
<h3>{p.title}</h3>
<span>${p.price}</span>
</div>
))}
</div>
);
});
routeAction$: Form Mutations
import { routeAction$, Form, zod$, z } from "@builder.io/qwik-city";
export const useCreateProduct = routeAction$(
async (data, { fail }) => {
const res = await fetch("https://api.example.com/products", {
method: "POST",
body: JSON.stringify(data),
});
if (!res.ok) return fail(500, { message: "Failed to create" });
return { success: true };
},
zod$({
title: z.string().min(1),
price: z.number().positive(),
url: z.string().url(),
})
);
export default component$(() => {
const action = useCreateProduct();
return (
<Form action={action}>
<input name="title" required />
<input name="price" type="number" required />
<input name="url" type="url" required />
<button type="submit">Create</button>
{action.value?.success && <p>Created!</p>}
</Form>
);
});
Signals: Fine-Grained Reactivity
import { component$, useSignal, useComputed$, useTask$ } from "@builder.io/qwik";
export default component$(() => {
const filter = useSignal("");
const products = useSignal<Product[]>([]);
const filtered = useComputed$(() =>
products.value.filter(p =>
p.title.toLowerCase().includes(filter.value.toLowerCase())
)
);
useTask$(({ track }) => {
track(() => filter.value);
console.log(`Filter changed: ${filter.value}`);
});
return (
<div>
<input bind:value={filter} placeholder="Search..." />
{filtered.value.map(p => <ProductCard key={p.id} product={p} />)}
</div>
);
});
Zero JS Until Interaction
Qwik serializes the app state into HTML. When a user interacts, only the relevant handler is lazy-loaded — not the entire app.
export default component$(() => {
// This handler is ONLY loaded when the button is clicked
const handleClick = $(() => {
alert("Loaded on demand!");
});
return <button onClick$={handleClick}>Click me</button>;
});
Build instant-loading data apps? My Apify tools + Qwik = zero-latency dashboards.
Custom solution? Email spinov001@gmail.com
Top comments (0)