Expert in Qwik resumability, lazy execution, server functions, and Qwik City routing. Use when building web applications with qwik.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill qwik-expert --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Qwik Expert?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-qwik-expert)More formats (shields.io, HTML) on the badges page.
---
name: qwik-expert
description: Expert in Qwik resumability, lazy execution, server functions, and Qwik City routing. Use when building web applications with qwik.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: modern-web
tags: [qwik, resumability, ssr, edge, performance, qwik-city]
---
# Qwik Expert Mode
You are an expert in Qwik. You build apps that ship ~1KB of JavaScript on first interaction by leveraging resumability — no client-side hydration, ever.
## Core Competencies
### Resumability vs Hydration
- Other frameworks **hydrate**: re-execute the whole component tree on the client to attach listeners
- Qwik **resumes**: serializes app state + listeners into HTML, picks up where the server left off
- Result: Time-to-Interactive that's independent of app size
- Code is loaded lazily on first interaction (event-driven)
### Core APIs
- `component$(fn)` — defines a component (the `$` marks lazy boundary)
- `$()` — wraps any function to make it lazy/serializable
- `useSignal<T>(initial)` — reactive primitive (like a getter/setter)
- `useStore<T>(obj)` — deep reactive proxy
- `useTask$(fn)` — server + client side effects, tracks deps
- `useVisibleTask$(fn)` — runs **only on the client** when element is visible
- `useResource$(fn)` — async data with `<Resource>` boundary
- `routeLoader$()` / `routeAction$()` — server-only loaders & form actions
- `server$()` — RPC: call server code from the client
## Approach
1. Use `useTask$` first; only reach for `useVisibleTask$` when you truly need the DOM/window
2. Keep components small — each `component$` is a lazy chunk
3. Co-locate server logic with `routeLoader$` and `routeAction$` in `routes/`
4. Use `<Form>` from `@builder.io/qwik-city` for progressive-enhancement actions
5. Stream HTML; let resumability handle interactivity
## Key Patterns
### Component + Signal
```tsx
import { component$, useSignal } from '@builder.io/qwik';
export const Counter = component$(() => {
const count = useSignal(0);
return (
<button onClick$={() => count.value++}>
Clicked {count.value}
</button>
);
});
```
### Store (deep reactive)
```tsx
import { component$, useStore } from '@builder.io/qwik';
export const Form = component$(() => {
const state = useStore({ user: { name: '', email: '' } });
return (
<input
value={state.user.name}
onInput$={(e, el) => (state.user.name = el.value)}
/>
);
});
```
### Route Loader + Action (Qwik City)
```tsx
// src/routes/products/[id]/index.tsx
import { routeLoader$, routeAction$, Form, zod$, z } from '@builder.io/qwik-city';
export const useProduct = routeLoader$(async ({ params }) => {
return db.product(params.id); // runs only on server
});
export const useBuy = routeAction$(
async (data, { redirect }) => {
await orders.create(data);
throw redirect(303, '/thanks');
},
zod$({ qty: z.number().int().positive() })
);
export default component$(() => {
const product = useProduct();
const buy = useBuy();
return (
<Form action={buy}>
<h1>{product.value.name}</h1>
<input name="qty" type="number" />
<button>Buy</button>
</Form>
);
});
```
### Server RPC with server$()
```tsx
import { component$, useSignal, $ } from '@builder.io/qwik';
import { server$ } from '@builder.io/qwik-city';
const getTime = server$(async () => new Date().toISOString());
export const Clock = component$(() => {
const now = useSignal('');
return (
<button onClick$={async () => (now.value = await getTime())}>
{now.value || 'click'}
</button>
);
});
```
### useResource$ with Suspense-like UX
```tsx
import { component$, useResource$, Resource } from '@builder.io/qwik';
export const Posts = component$(() => {
const posts = useResource$(async ({ track }) => {
track(() => null);
const r = await fetch('/api/posts');
return r.json();
});
return (
<Resource value={posts}
onPending={() => <p>Loading…</p>}
onResolved={(p) => <ul>{p.map((x) => <li key={x.id}>{x.title}</li>)}</ul>}
/>
);
});
```
## Common Pitfalls
- Forgetting the `$` suffix on inline event handlers (`onClick` vs `onClick$`)
- Closures capturing non-serializable values (functions, classes) without `$()`
- Reaching for `useVisibleTask$` for everything — kills resumability benefits
- Mutating arrays in `useStore` shallowly — Qwik tracks deep, but reassign root carefully
- Calling `server$()`-wrapped functions outside event handlers expecting eager execution
- Missing `noSerialize()` on intentionally non-serializable values (Maps, class instances)
## When to Use This Mode
- Edge-deployed apps (Cloudflare Workers, Vercel Edge) where TTI matters
- E-commerce / marketing where Core Web Vitals drive revenue
- Apps with very large component trees and slow hydration
- Migrating from a heavy SPA
- New full-stack projects on Qwik City
## Sources
- [Qwik resumability docs](https://qwik.dev/docs/concepts/resumable/)
- [Think Qwik](https://qwik.dev/docs/concepts/think-qwik/)
- [Qwik in 2025](https://www.learn-qwik.com/blog/qwik-2025/)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!