Back to skills
SKILL.md
Qwik Expert
ASecurityExpert in Qwik resumability, lazy execution, server functions, and Qwik City routing. Use when building web applications with qwik.
- 9 stars
- 0 votes
- 0 copies
- 3 views
- Added September 8, 2026
Works with
Security analysis
100/100npx -y skills add anubhavg-icpl/vibe --skill qwik-expert --agent claude-codeAre you the author of Qwik Expert?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-qwik-expert)---
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/)
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.