This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
frontendcritical PriorityID: vite-6-module-runner-environment-isolation-guardrail

Vite 6 Environment API Module Runner Deterministic Memory & Runtime Isolation Guardrail

Enforces deterministic lifecycle disposal, module graph cache invalidation, and strict global scope hygiene across concurrent SSR micro-frontends executed via Vite 6 Environment API Module Runner. Prevents host memory leaks and cross-context pollution caused by lingering module evaluators, unclosed runners, and detached closure retention in long-running Vite server runtimes.

Prohibited Anti-Pattern: Unbounded ModuleRunner Instantiation and Leaked Module Cache Closures in Vite 6 Multi-Tenant SSR

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Vite 6 Environment API Module Runner Deterministic Memory & Runtime Isolation Guardrail - Enforces deterministic lifecycle disposal, module graph cache invalidation, and strict global scope hygiene across concurrent SSR micro-frontends executed via Vite 6 Environment API Module Runner. Prevents host memory leaks and cross-context pollution caused by lingering module evaluators, unclosed runners, and detached closure retention in long-running Vite server runtimes.
globs: src/**/*.ssr.{ts,tsx}, src/**/runtime.{ts,tsx}, server/**/*.{ts,js}, vite.config.{ts,js}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/vite-6-module-runner-environment-isolation-guardrail"
---

# Vite 6 Environment API Module Runner Deterministic Memory & Runtime Isolation Guardrail

> **Severity**: CRITICAL | **Category**: frontend
> **Anti-Pattern Warning**: Unbounded ModuleRunner Instantiation and Leaked Module Cache Closures in Vite 6 Multi-Tenant SSR

## System Constraints
You are a Principal Software Architect enforcing Vite 6 Environment API Module Runner Memory Leak Isolation Guardrails. Vite 6 decouples the runtime execution layer via the Environment API and ModuleRunner. In concurrent micro-frontend (MFE) SSR architectures, instantiating runners without deterministic lifecycle bounds retains the entire module evaluation graph, AST caches, and module-scope closures within V8 heap indefinitely. You must enforce explicit disposal, deterministic unmounting hooks, strict isolation of host globals, and cache invalidation protocols.

## Strict Guidelines
- Engineers MUST ALWAYS implement deterministic lifecycle management using TypeScript 5.2+ explicit resource management (Symbol.asyncDispose / using) or explicit lifecycle teardown methods on any ModuleRunner instance.
- Engineers MUST NOT evaluate micro-frontends into shared host global scope; all micro-frontend state MUST be scoped to runner context or explicit AsyncLocalStorage stores that are pruned upon request completion.
- Engineers MUST ALWAYS invoke runner.close() or runner.moduleCache.clear() when an environment runtime transitions, hot-reloads, or terminates a micro-frontend session.
- Code MUST explicitly unbind all external EventEmitter listeners, timers, and microtask queues inside module evaluation scopes using an AbortSignal passed into the runner evaluation boundary.
- Services NEVER instantiate dynamic ModuleRunner instances per-request without deterministic bound disposal, as unreclaimed ModuleRunner caches and evaluator registries induce rapid V8 Old-Space heap exhaustion.

## Bad vs Good Implementations
### Vite 6 Module Runner SSR Micro-Frontend Execution and Teardown

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Creates a new ModuleRunner per request without lifecycle disposal. ModuleRunner.moduleCache indefinitely retains instantiated module graphs, closures, and evaluator references. Leaking module state onto globalThis induces cross-tenant data corruption and prevents garbage collection of the entire MFE AST.
```typescript
import { createViteServer } from 'vite';
import { ModuleRunner, ESModulesEvaluator } from 'vite/module-runner';

interface MFERenderer {
  render: (url: string) => Promise<string>;
}

export async function handleSSRRequest(url: string, mfeEntry: string): Promise<string> {
  const vite = await createViteServer();
  // ANTI-PATTERN: Spawning unmanaged ModuleRunner instances per request.
  // No lifecycle container, no ModuleRunner.close(), and moduleCache retains
  // entire evaluation closures and imports in heap indefinitely.
  const runner = new ModuleRunner(
    {
      root: vite.config.root,
      transport: vite.environments.ssr.hot,
    },
    new ESModulesEvaluator()
  );

  // Global state pollution leaks into Node.js runtime process
  (globalThis as unknown as { __MFE_CONTEXT__: string }).__MFE_CONTEXT__ = url;

  const { render }: MFERenderer = await runner.import(mfeEntry);
  return await render(url);
}
```

#### Production Standard (Correct)
> **Standard**: Wraps Vite 6 ModuleRunner in an AsyncDisposable container. Guarantees deterministic eviction of runner.moduleCache and invokes runner.close() upon block exit. Context is isolated via AsyncLocalStorage rather than host globalThis, and active tasks are cleanly terminated using AbortSignal.
```typescript
import { DevEnvironment } from 'vite';
import { ModuleRunner, ESModulesEvaluator } from 'vite/module-runner';
import { AsyncLocalStorage } from 'node:async_hooks';

interface MFERenderer {
  render: (url: string, signal: AbortSignal) => Promise<string>;
}

export class ScopedMfeRunner implements AsyncDisposable {
  private readonly runner: ModuleRunner;
  private readonly abortController: AbortController = new AbortController();
  private static readonly contextStorage = new AsyncLocalStorage<{ traceId: string }>();

  constructor(environment: DevEnvironment) {
    this.runner = new ModuleRunner(
      {
        root: environment.config.root,
        transport: environment.hot,
      },
      new ESModulesEvaluator()
    );
  }

  public async executeMfe(entrypoint: string, url: string, traceId: string): Promise<string> {
    return ScopedMfeRunner.contextStorage.run({ traceId }, async () => {
      const exports = await this.runner.import<MFERenderer>(entrypoint);
      if (!exports || typeof exports.render !== 'function') {
        throw new Error(`Entrypoint ${entrypoint} does not implement render contract.`);
      }
      return await exports.render(url, this.abortController.signal);
    });
  }

  public async [Symbol.asyncDispose](): Promise<void> {
    this.abortController.abort();
    this.runner.moduleCache.clear();
    await this.runner.close();
  }
}

export async function renderWithIsolation(
  env: DevEnvironment,
  entry: string,
  url: string,
  traceId: string
): Promise<string> {
  // Deterministic disposal via TS 5.2+ resource management pattern
  await using mfeScope = new ScopedMfeRunner(env);
  return await mfeScope.executeMfe(entry, url, traceId);
}
```

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: Vite 6 Environment API Module Runner Deterministic Memory & Runtime Isolation Guardrail

Vite 6 Environment API Module Runner Deterministic Memory & Runtime Isolation Guardrail defines an industrial-grade behavioral standard for frontend engineering. Enforces deterministic lifecycle disposal, module graph cache invalidation, and strict global scope hygiene across concurrent SSR micro-frontends executed via Vite 6 Environment API Module Runner. Prevents host memory leaks and cross-context pollution caused by lingering module evaluators, unclosed runners, and detached closure retention in long-running Vite server runtimes. 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: Unbounded ModuleRunner Instantiation and Leaked Module Cache Closures in Vite 6 Multi-Tenant SSR 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 DriftUnbounded ModuleRunner Instantiation and Leaked Module Cache Closures in Vite 6 Multi-Tenant SSRCritical
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 implement deterministic lifecycle management using TypeScript 5.2+ explicit resource management (Symbol.asyncDispose / using) or explicit lifecycle teardown methods on any ModuleRunner instance.

Engineers MUST ALWAYS implement deterministic lifecycle management using TypeScript 5.2+ explicit resource management (Symbol.asyncDispose / using) or explicit lifecycle teardown methods on any ModuleRunner instance.

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 evaluate micro-frontends into shared host global scope

Engineers MUST NOT evaluate micro-frontends into shared host global scope; all micro-frontend state MUST be scoped to runner context or explicit AsyncLocalStorage stores that are pruned upon request completion.

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 ALWAYS invoke runner.close() or runner.moduleCache.clear() when an environment runtime transitions, hot-reloads, or terminates a micro-frontend session.

Engineers MUST ALWAYS invoke runner.close() or runner.moduleCache.clear() when an environment runtime transitions, hot-reloads, or terminates a micro-frontend session.

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

Code MUST explicitly unbind all external EventEmitter listeners, timers, and microtask queues inside module evaluation scopes using an AbortSignal passed into the runner evaluation boundary.

Code MUST explicitly unbind all external EventEmitter listeners, timers, and microtask queues inside module evaluation scopes using an AbortSignal passed into the runner evaluation boundary.

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

Services NEVER instantiate dynamic ModuleRunner instances per-request without deterministic bound disposal, as unreclaimed ModuleRunner caches and evaluator registries induce rapid V8 Old-Space heap exhaustion.

Services NEVER instantiate dynamic ModuleRunner instances per-request without deterministic bound disposal, as unreclaimed ModuleRunner caches and evaluator registries induce rapid V8 Old-Space heap exhaustion.

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 Vite 6 Environment API Module Runner Deterministic Memory & Runtime Isolation Guardrail critical for AI coding assistants?

Enforces deterministic lifecycle disposal, module graph cache invalidation, and strict global scope hygiene across concurrent SSR micro-frontends executed via Vite 6 Environment API Module Runner. Prevents host memory leaks and cross-context pollution caused by lingering module evaluators, unclosed runners, and detached closure retention in long-running Vite server runtimes. 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 (Unbounded ModuleRunner Instantiation and Leaked Module Cache Closures in Vite 6 Multi-Tenant SSR) 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

Vite