Qwik Core Development Guide (Skill)
Scope
- Only for the Qwik core package:
packages/qwik(especiallysrc/core/**,reactive-primitives/**).
Mandatory workflow (must do)
0. Run tests immediately after any implementation change
- After changing any implementation file, immediately run the relevant unit tests (don’t wait for CI, don’t wait to be asked):
pnpm vitest run <test-file-path>
- Typical example (signals):
pnpm vitest run packages/qwik/src/core/reactive-primitives/impl/signal.unit.tsx
- If tests fail, fix and re-run until they pass. Only then proceed with anything else (docs/refactors/cleanup).
Implementation essentials (high-signal rules)
- Constructor parameter plumbing: when adding params to signal/async-signal constructors, keep parent calls and parameter order stable; extract options in factories (e.g.
signal-api.ts) before passing into constructors. - AsyncSignal promise branches:
.then()and.catch()must be symmetric (same side-effects / scheduling). Errors should not “stop” polling. - invalidate cleanup order: clear timeouts/resources first, then clear cached data and call
super.invalidate()to avoid leaks and test interference. - SSR vs browser: guard browser APIs (
setTimeout, etc.) withisBrowser; still persist configuration on the instance for hydration. - Subscriber checks: async signals may have separate subscribers for
.value,.loading, and.error; any “has subscribers” logic must consider all three sets. - Serialization/hydration alignment: when adding new serializable fields, array positions in
serialize.tsandinflate.tsmust match exactly.
Testing conventions (high-signal rules)
- Prefer
$()for QRLs; avoid manually constructing QRLs (e.g.inlinedQrl()). - In
$()tests that need mutable state, use object refs (e.g.{ count: 0 }). Don’t capture and mutate outer-scope primitives (can trigger “Assignment to constant variable”). - First computation may “throw a promise” to trigger suspense behavior; in tests, use helpers like
retryOnPromise()/withContainer()around first reads/creation.
Required validations before finishing
When the task is complete / ready to ship (especially core changes), run as appropriate:
pnpm build --qwik --qwikrouter --dev
pnpm run test.e2e.chromium
pnpm api.update
Detailed reference
- For deeper patterns, examples, pitfall tables, and full checklists, read
[AGENTS.md](AGENTS.md)in the same folder.