This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
frontendcritical PriorityID: svelte-5-runes-boundary-signal-leakage-prevention

Svelte 5 Universal Runes Boundary & Signal Leakage Prevention

Enforces strict boundary encapsulation between Svelte 5 fine-grained reactive signals ($state, $derived, $effect) and external un-tracked DOM cycles or universal runtime singletons. Eliminates memory leaks and uncollected component subtrees caused by escaped reactive closures and unmanaged effect roots.

Prohibited Anti-Pattern: Escaping Reactive Signal Graphs into Long-Lived DOM Handlers and Uncontained Universal Modules

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Svelte 5 Universal Runes Boundary & Signal Leakage Prevention - Enforces strict boundary encapsulation between Svelte 5 fine-grained reactive signals ($state, $derived, $effect) and external un-tracked DOM cycles or universal runtime singletons. Eliminates memory leaks and uncollected component subtrees caused by escaped reactive closures and unmanaged effect roots.
globs: src/**/*.{svelte,svelte.ts,svelte.js,ts,js}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/svelte-5-runes-boundary-signal-leakage-prevention"
---

# Svelte 5 Universal Runes Boundary & Signal Leakage Prevention

> **Severity**: CRITICAL | **Category**: frontend
> **Anti-Pattern Warning**: Escaping Reactive Signal Graphs into Long-Lived DOM Handlers and Uncontained Universal Modules

## System Constraints
You are a Principal Software Architect enforcing Svelte 5 Universal Runes Boundary & Signal Leakage Prevention. Mandate strict boundary isolation between Svelte 5 fine-grained reactivity and unmanaged external scopes (DOM listeners, WebSockets, external instances, global caches). Ensure signal reads in non-reactive bridges are isolated with untrack(), universal module effects are gated via $effect.root(), and all event-driven signal updates strictly manage tear-down lifecycles to prevent cross-component memory pinholes.

## Strict Guidelines
- Engineers MUST ALWAYS isolate external non-reactive reads from signal graphs using untrack() when reading reactive state inside side-effect bridges or third-party mutation listeners.
- Engineers MUST ALWAYS return a teardown function from $effect blocks when registering DOM event listeners, MutationObservers, or WebSocket subscribers.
- Universal reactive modules (.svelte.ts) that instantiate effects outside a component mounting tree MUST ALWAYS wrap those effects within an explicit $effect.root() and export a disposal lifecycle hook.
- Engineers MUST NOT leak $state proxies directly into unmanaged third-party libraries; pass plain snapshot clones using $state.snapshot() when interfacing with external mutable APIs.
- Components NEVER attach window, document, or global event handlers directly modifying fine-grained signals without binding teardown hooks inside onDestroy or returning disposers from $effect.

## Bad vs Good Implementations
### Universal Window Viewport Observer in .svelte.ts

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Attaching raw signal updates directly to global event listeners inside universal classes without an explicit teardown mechanism or effect boundary causes instances to remain retained in the window event listener table permanently, preventing garbage collection across client-side page transitions.
```typescript
// Bad: Unmanaged signal attachment and missing effect root in universal module
// Creates permanent memory leaks and retains component references across navigations
export class ViewportTracker {
  width = $state(typeof window !== 'undefined' ? window.innerWidth : 0);

  constructor() {
    if (typeof window !== 'undefined') {
      // Leak: Global event listener retains this instance permanently
      // No teardown or boundary isolation provided
      window.addEventListener('resize', () => {
        this.width = window.innerWidth;
      });
    }
  }
}
```

#### Production Standard (Correct)
> **Standard**: Wraps the reactive effect inside an explicit $effect.root() container and exposes a deterministic destroy() method. The inner $effect provides immediate teardown of the DOM listener upon disposal, completely severing the link to the global window object.
```typescript
// Good: Encapsulated effect root with explicit disposal and boundary isolation
export class ViewportTracker {
  width = $state(0);
  #cleanup: (() => void) | null = null;

  constructor() {
    if (typeof window === 'undefined') return;

    this.#cleanup = $effect.root(() => {
      $effect(() => {
        const onResize = () => {
          this.width = window.innerWidth;
        };

        window.addEventListener('resize', onResize, { passive: true });
        return () => {
          window.removeEventListener('resize', onResize);
        };
      });
    });
  }

  destroy(): void {
    if (this.#cleanup) {
      this.#cleanup();
      this.#cleanup = null;
    }
  }
}
```

### Passing Fine-Grained Signals to Imperative Third-Party DOM Libraries

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Passing the raw $state proxy directly into a non-reactive imperative library exposes Svelte's reactive graph to external un-tracked mutation, causing unpredictable reactive loops and retaining internal signal nodes inside external caches.
```typescript
// Bad: Passing raw reactive state directly into third-party mutating DOM charting library
// Leads to signal leakage and unintended proxy mutations outside Svelte runtime tracking
import Chart from 'external-chart-library';

let config = $state({ labels: ['A', 'B'], data: [10, 20] });
let chartInstance: Chart | null = null;

$effect(() => {
  if (!chartInstance) {
    chartInstance = new Chart('#canvas', config); // Leaks reactive proxy into external mutator
  } else {
    chartInstance.update(config);
  }
});
```

#### Production Standard (Correct)
> **Standard**: Using $state.snapshot() extracts pure non-reactive primitive data, untrack() prevents downstream library operations from triggering reactive dependencies, and the returned teardown callback guarantees deterministic resource cleanup.
```typescript
// Good: Decoupling signals via $state.snapshot and untrack boundary
import Chart from 'external-chart-library';
import { untrack } from 'svelte';

let config = $state({ labels: ['A', 'B'], data: [10, 20] });
let chartInstance: Chart | null = null;

$effect(() => {
  // Create an immutable, plain JavaScript clone free of reactive signal proxies
  const serializedConfig = $state.snapshot(config);

  untrack(() => {
    if (!chartInstance) {
      chartInstance = new Chart('#canvas', serializedConfig);
    } else {
      chartInstance.update(serializedConfig);
    }
  });

  return () => {
    if (chartInstance) {
      chartInstance.destroy();
      chartInstance = null;
    }
  };
});
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Svelte 5 Universal Runes Boundary & Signal Leakage Prevention

Svelte 5 Universal Runes Boundary & Signal Leakage Prevention defines an industrial-grade behavioral standard for frontend engineering. Enforces strict boundary encapsulation between Svelte 5 fine-grained reactive signals ($state, $derived, $effect) and external un-tracked DOM cycles or universal runtime singletons. Eliminates memory leaks and uncollected component subtrees caused by escaped reactive closures and unmanaged effect roots. 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: Escaping Reactive Signal Graphs into Long-Lived DOM Handlers and Uncontained Universal Modules 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 DriftEscaping Reactive Signal Graphs into Long-Lived DOM Handlers and Uncontained Universal ModulesCritical
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 isolate external non-reactive reads from signal graphs using untrack() when reading reactive state inside side-effect bridges or third-party mutation listeners.

Engineers MUST ALWAYS isolate external non-reactive reads from signal graphs using untrack() when reading reactive state inside side-effect bridges or third-party mutation listeners.

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 ALWAYS return a teardown function from $effect blocks when registering DOM event listeners, MutationObservers, or WebSocket subscribers.

Engineers MUST ALWAYS return a teardown function from $effect blocks when registering DOM event listeners, MutationObservers, or WebSocket subscribers.

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

Universal reactive modules (.svelte.ts) that instantiate effects outside a component mounting tree MUST ALWAYS wrap those effects within an explicit $effect.root() and export a disposal lifecycle hook.

Universal reactive modules (.svelte.ts) that instantiate effects outside a component mounting tree MUST ALWAYS wrap those effects within an explicit $effect.root() and export a disposal lifecycle hook.

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 NOT leak $state proxies directly into unmanaged third-party libraries

Engineers MUST NOT leak $state proxies directly into unmanaged third-party libraries; pass plain snapshot clones using $state.snapshot() when interfacing with external mutable APIs.

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

Components NEVER attach window, document, or global event handlers directly modifying fine-grained signals without binding teardown hooks inside onDestroy or returning disposers from $effect.

Components NEVER attach window, document, or global event handlers directly modifying fine-grained signals without binding teardown hooks inside onDestroy or returning disposers from $effect.

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 Svelte 5 Universal Runes Boundary & Signal Leakage Prevention critical for AI coding assistants?

Enforces strict boundary encapsulation between Svelte 5 fine-grained reactive signals ($state, $derived, $effect) and external un-tracked DOM cycles or universal runtime singletons. Eliminates memory leaks and uncollected component subtrees caused by escaped reactive closures and unmanaged effect roots. 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 (Escaping Reactive Signal Graphs into Long-Lived DOM Handlers and Uncontained Universal Modules) 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

Svelte