This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
frontendcritical PriorityID: qwik-city-resumability-serialization-boundaries

Qwik Resumability Invariants: Serializability Boundaries and Lazy QRL Execution

Enforces zero-hydration resumability invariants by governing QRL ($) boundary serialization and preventing eager execution regressions. Capturing non-serializable instances across lexical scopes or overusing useVisibleTask$ destroys lazy-loading benefits and causes runtime serialization panics.

Prohibited Anti-Pattern: Eager Component Execution and Non-Serializable Scope Leakage Across QRL Boundaries

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Qwik Resumability Invariants: Serializability Boundaries and Lazy QRL Execution - Enforces zero-hydration resumability invariants by governing QRL ($) boundary serialization and preventing eager execution regressions. Capturing non-serializable instances across lexical scopes or overusing useVisibleTask$ destroys lazy-loading benefits and causes runtime serialization panics.
globs: src/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/qwik-city-resumability-serialization-boundaries"
---

# Qwik Resumability Invariants: Serializability Boundaries and Lazy QRL Execution

> **Severity**: CRITICAL | **Category**: frontend
> **Anti-Pattern Warning**: Eager Component Execution and Non-Serializable Scope Leakage Across QRL Boundaries

## System Constraints
You are a Principal Software Architect enforcing Qwik City's resumability and containerization architecture. Qwik replaces hydration with resumability by serializing component state and event handlers into HTML via QRLs (the '$' optimizer boundary). You must strictly prevent closure capture of non-serializable objects across '$' boundaries, prevent eager code execution via 'useVisibleTask$', and enforce dynamic chunk splitting for third-party browser clients.

## Strict Guidelines
- Engineers MUST ALWAYS ensure any value captured across a '$' boundary is strictly serializable by Qwik (primitives, plain objects/arrays, Signal, Store, or NoSerialize wrappers).
- Engineers MUST NOT instantiate class instances, DOM element references, or non-serializable SDK clients directly in component scope without wrapping them in 'noSerialize()'.
- Engineers MUST default to 'useTask$' for state synchronization and data fetching, reserving 'useVisibleTask$' strictly for imperative DOM measurements or browser-only APIs that cannot run during SSR.
- Engineers MUST dynamically import heavy browser-only third-party libraries inside event handlers or delayed tasks to prevent eager bundle inclusion in the initial container payload.
- Engineers MUST NOT import server-only database or secret utilities into standard component files; all server operations must be confined to 'routeLoader$', 'routeAction$', or 'server$'.
- Code SHOULD pass state across boundaries using Signals or Stores rather than passing callbacks that capture non-serializable outer scope references.
- Components NEVER capture mutable module-level state within an inline '$' handler because module state is not serialized into the SSR container HTML.

## Bad vs Good Implementations
### Violating Resumability via Non-Serializable Closures and Eager Task Execution

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Instantiating 'HeavyAnalyticsEngine' directly in component scope leaks a non-serializable class instance into the QRL closure of 'onClick$', causing serialization failure (Code: 15). Furthermore, 'useVisibleTask$' executes eagerly on client boot, forcing the browser to download and execute JavaScript immediately, completely defeating Qwik's zero-hydration resumability.
```typescript
import { component$, useSignal, useVisibleTask$ } from '@builder.io/qwik';
import { HeavyAnalyticsEngine } from './analytics';

export const MetricCard = component$(() => {
  // Anti-pattern: Instantiating complex non-serializable class directly in component scope
  const analytics = new HeavyAnalyticsEngine();
  const count = useSignal(0);

  // Anti-pattern: useVisibleTask$ runs eagerly on hydration in the browser, forcing bundle download
  useVisibleTask$(({ track }) => {
    track(() => count.value);
    analytics.sendTrack('view_metric', { count: count.value });
  });

  return (
    <button
      onClick$={() => {
        count.value++;
        // Anti-pattern: Leaking non-serializable 'analytics' instance into the onClick$ QRL closure
        analytics.sendTrack('click_metric', { count: count.value });
      }}
    >
      Count: {count.value}
    </button>
  );
});
```

#### Production Standard (Correct)
> **Standard**: The non-serializable class reference is wrapped in 'noSerialize', preventing runtime container serialization panics. The client-only engine is dynamically imported on-demand, preserving zero initial JS delivery. 'useTask$' replaces 'useVisibleTask$', allowing the initial render to complete entirely on the server without eager client bundle execution.
```typescript
import { component$, useSignal, useTask$, noSerialize, type NoSerialize } from '@builder.io/qwik';
import type { HeavyAnalyticsEngine } from './analytics';

export const MetricCard = component$(() => {
  const count = useSignal(0);
  // Invariant: Non-serializable clients must be explicitly wrapped in NoSerialize
  const analyticsRef = useSignal<NoSerialize<HeavyAnalyticsEngine>>();

  // Invariant: useTask$ runs server-side during SSR and only re-runs when tracked dependencies mutate
  useTask$(async ({ track }) => {
    track(() => count.value);
    
    // Lazily initialize client-side SDK on demand without forcing eager script bundles
    if (typeof window !== 'undefined' && !analyticsRef.value) {
      const { HeavyAnalyticsEngine } = await import('./analytics');
      analyticsRef.value = noSerialize(new HeavyAnalyticsEngine());
    }
    
    analyticsRef.value?.sendTrack('view_metric', { count: count.value });
  });

  return (
    <button
      onClick$={() => {
        count.value++;
        analyticsRef.value?.sendTrack('click_metric', { count: count.value });
      }}
    >
      Count: {count.value}
    </button>
  );
});
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Qwik Resumability Invariants: Serializability Boundaries and Lazy QRL Execution

Qwik Resumability Invariants: Serializability Boundaries and Lazy QRL Execution defines an industrial-grade behavioral standard for frontend engineering. Enforces zero-hydration resumability invariants by governing QRL ($) boundary serialization and preventing eager execution regressions. Capturing non-serializable instances across lexical scopes or overusing useVisibleTask$ destroys lazy-loading benefits and causes runtime serialization panics. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Eager Component Execution and Non-Serializable Scope Leakage Across QRL Boundaries Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftEager Component Execution and Non-Serializable Scope Leakage Across QRL BoundariesCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS ensure any value captured across a '$' boundary is strictly serializable by Qwik (primitives, plain objects/arrays, Signal, Store, or NoSerialize wrappers).

Engineers MUST ALWAYS ensure any value captured across a '$' boundary is strictly serializable by Qwik (primitives, plain objects/arrays, Signal, Store, or NoSerialize wrappers).

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT instantiate class instances, DOM element references, or non-serializable SDK clients directly in component scope without wrapping them in 'noSerialize()'.

Engineers MUST NOT instantiate class instances, DOM element references, or non-serializable SDK clients directly in component scope without wrapping them in 'noSerialize()'.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST default to 'useTask$' for state synchronization and data fetching, reserving 'useVisibleTask$' strictly for imperative DOM measurements or browser-only APIs that cannot run during SSR.

Engineers MUST default to 'useTask$' for state synchronization and data fetching, reserving 'useVisibleTask$' strictly for imperative DOM measurements or browser-only APIs that cannot run during SSR.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Engineers MUST dynamically import heavy browser-only third-party libraries inside event handlers or delayed tasks to prevent eager bundle inclusion in the initial container payload.

Engineers MUST dynamically import heavy browser-only third-party libraries inside event handlers or delayed tasks to prevent eager bundle inclusion in the initial container payload.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Engineers MUST NOT import server-only database or secret utilities into standard component files

Engineers MUST NOT import server-only database or secret utilities into standard component files; all server operations must be confined to 'routeLoader$', 'routeAction$', or 'server$'.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Code SHOULD pass state across boundaries using Signals or Stores rather than passing callbacks that capture non-serializable outer scope references.

Code SHOULD pass state across boundaries using Signals or Stores rather than passing callbacks that capture non-serializable outer scope references.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
7

Components NEVER capture mutable module-level state within an inline '$' handler because module state is not serialized into the SSR container HTML.

Components NEVER capture mutable module-level state within an inline '$' handler because module state is not serialized into the SSR container HTML.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Qwik Resumability Invariants: Serializability Boundaries and Lazy QRL Execution critical for AI coding assistants?

Enforces zero-hydration resumability invariants by governing QRL ($) boundary serialization and preventing eager execution regressions. Capturing non-serializable instances across lexical scopes or overusing useVisibleTask$ destroys lazy-loading benefits and causes runtime serialization panics. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Eager Component Execution and Non-Serializable Scope Leakage Across QRL Boundaries) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

Related FRONTEND Rules

View all rules →
frontend
119

SolidStart 1.0 Server Functions & Async Boundaries Production Standard

SolidStart 1.0 relies on the Vinxi bundler to split `server$` closures into independent HTTP POST RPC endpoints. Direct lexical closure over client signals within `server$` scopes or failure to demarcate async boundaries with `<Suspense>` causes silent serialization failures, client-bundle secret leaks, and SSR hydration mismatches. Enforcing strict parameter passing, runtime input validation, and Solid async primitives maintains security and fine-grained reactivity across network boundaries.

frontend
119

Astro 5 Actions & Content Layer Production Standard

Enforces strict type safety and architectural correctness for Astro 5 Server Actions and the zero-waterfall Content Layer API. Prevents runtime contract mismatches, hydration mismatches, and unhandled mutation exceptions across dynamic and prerendered boundaries. Failure to follow these patterns leads to silent data fetching waterfalls, build-time cache corruptions, and unhandled server action exceptions.

frontend
51

Nuxt 4 Nitro Server Engine & Shared Directory Production Standard

Nuxt 4 enforces strict boundary segregation between client UI in the app/ directory, backend endpoints in server/, and universal contracts in shared/. Violating cross-boundary isolation or maintaining module-scoped state in Nitro server handlers causes catastrophic cross-request data corruption and hydration mismatches under concurrent production traffic. Architects must enforce request-isolated H3 event contexts, universal serialization schemas, and strict path-alias boundaries.

1 Rule in Stack

Qwik