Qwik achieves instant page loads by sending zero JavaScript to the browser by default. It resumes interactivity lazily — only loading code when the user actually interacts.
The Free APIs You're Missing
1. useSignal — Fine-Grained Reactivity
import { component$, useSignal, useComputed$ } from "@builder.io/qwik";
export const Counter = component$(() => {
const count = useSignal(0);
const doubled = useComputed$(() => count.value * 2);
return (
<div>
<p>Count: {count.value}</p>
<p>Doubled: {doubled.value}</p>
<button onClick$={() => count.value++}>+1</button>
</div>
);
});
The $ suffix is Qwik's magic — it marks lazy-loading boundaries. The click handler only loads when clicked.
2. useTask$ — Server & Client Side Effects
import { useTask$, useSignal } from "@builder.io/qwik";
export const UserProfile = component$(() => {
const userId = useSignal("123");
const user = useSignal<User | null>(null);
useTask$(async ({ track }) => {
track(() => userId.value);
const resp = await fetch(`/api/users/${userId.value}`);
user.value = await resp.json();
});
// Runs on SERVER during SSR, then on CLIENT when userId changes
return <div>{user.value?.name}</div>;
});
3. routeLoader$ — Server Data Loading
// src/routes/users/[id]/index.tsx
import { routeLoader$ } from "@builder.io/qwik-city";
export const useUser = routeLoader$(async ({ params, status }) => {
const user = await db.users.findUnique({ where: { id: params.id } });
if (!user) {
status(404);
return null;
}
return user;
});
export default component$(() => {
const user = useUser();
return <h1>{user.value?.name}</h1>;
});
4. routeAction$ — Form Handling Without JS
import { routeAction$, Form, zod$, z } from "@builder.io/qwik-city";
export const useCreatePost = routeAction$(
async (data, { redirect }) => {
await db.posts.create({ data });
throw redirect(302, "/posts");
},
zod$({
title: z.string().min(3),
content: z.string().min(10),
})
);
export default component$(() => {
const action = useCreatePost();
return (
<Form action={action}>
<input name="title" />
{action.value?.fieldErrors?.title && <span>{action.value.fieldErrors.title}</span>}
<textarea name="content" />
<button type="submit">Create</button>
</Form>
);
});
Works without JavaScript. Progressive enhancement built in.
5. useVisibleTask$ — Client-Only Code
import { useVisibleTask$ } from "@builder.io/qwik";
export const Analytics = component$(() => {
useVisibleTask$(() => {
// Only runs in browser, only when component is visible
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
trackPageView();
}
});
return () => observer.disconnect();
});
return <div>Tracked section</div>;
});
Getting Started
npm create qwik@latest
cd my-qwik-app && npm start
Need data from any website delivered as clean JSON? I build production web scrapers that handle anti-bot, proxies, and rate limits. 77 scrapers running in production. Email me: Spinov001@gmail.com
Check out my awesome-web-scraping list for the best scraping tools and resources.
Top comments (0)