This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: bun-ffi-zerocopy-buffer-isolation-boundary

Bun 1.2 FFI Zero-Copy Buffer Isolation Boundary and Lifetime Invariant

Mandates strict ownership demarcation, deterministic lifecycle tracking, and memory pinning boundaries when streaming binary frames between native C/Rust extensions and Bun 1.2 TypedArrays via bun:ffi. Prevents use-after-free, double-free, and cross-tick memory corruption caused by V8/JSC GC movements or premature deallocations of unmanaged native backing stores.

Prohibited Anti-Pattern: Retaining Raw Zero-Copy FFI ArrayBuffers Across Asynchronous Boundaries Without Pinned Lifecycles

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Bun 1.2 FFI Zero-Copy Buffer Isolation Boundary and Lifetime Invariant - Mandates strict ownership demarcation, deterministic lifecycle tracking, and memory pinning boundaries when streaming binary frames between native C/Rust extensions and Bun 1.2 TypedArrays via bun:ffi. Prevents use-after-free, double-free, and cross-tick memory corruption caused by V8/JSC GC movements or premature deallocations of unmanaged native backing stores.
globs: src/**/*.{ts,tsx}, lib/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/bun-ffi-zerocopy-buffer-isolation-boundary"
---

# Bun 1.2 FFI Zero-Copy Buffer Isolation Boundary and Lifetime Invariant

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Retaining Raw Zero-Copy FFI ArrayBuffers Across Asynchronous Boundaries Without Pinned Lifecycles

## System Constraints
You are a Principal Systems Engineer enforcing strict zero-copy memory safety boundaries in Bun 1.2 native FFI integrations. Enforce deterministic pointer lifecycles, explicit ownership transfer, and memory isolation.

## Strict Guidelines
- Engineers MUST ALWAYS isolate raw pointers returned from `bun:ffi` by either copying data via `.slice()` across asynchronous task boundaries or wrapping the pointer in a deterministic Disposable pattern (`Symbol.dispose` / `Symbol.asyncDispose`).
- Engineers MUST NOT expose `toArrayBuffer(ptr, byteOffset, byteLength)` to consumers outside the synchronous scope that guarantees the native memory's validity.
- Services MUST explicitly manage native allocator lifecycles: whenever native C/Rust memory is allocated for zero-copy JS consumption, an associated cleanup foreign function (e.g., `free_frame`) MUST be invoked deterministically.
- Code SHOULD prefer Bun's built-in fast-call TypedArray zero-copy passing conventions while ensuring native pointers remain pinned and unaliased during parallel worker execution.
- Components NEVER cast native buffers into mutable TypedArrays if the underlying native extension retains a write reference, preventing data races and memory tearing.

## Bad vs Good Implementations
### Unsafe FFI Buffer Escape Across Microtask Boundaries vs. RAII Disposable Isolation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The native pointer `ptr` is immediately freed before the asynchronous `fetch` finishes. The `rawBuffer` references dead unmanaged memory, leading to data corruption, heap exploitation vectors, or process crashes (SIGSEGV).
```typescript
import { dlopen, FFIType, toArrayBuffer } from "bun:ffi";

const lib = dlopen("libframe_processor.so", {
  next_frame: {
    args: [],
    returns: FFIType.ptr,
  },
  free_frame: {
    args: [FFIType.ptr],
    returns: FFIType.void,
  },
});

// ANTI-PATTERN: toArrayBuffer creates an unmanaged view over native heap.
// Freeing the pointer immediately or letting the view escape across async
// ticks leads to use-after-free or buffer aliasing.
export async function processNextFrameBad() {
  const ptr = lib.symbols.next_frame();
  if (!ptr) return null;

  // 1024-byte zero-copy view
  const rawBuffer = toArrayBuffer(ptr, 0, 1024);
  const frameView = new Uint8Array(rawBuffer);

  // Native memory freed synchronously while async pipeline consumes view
  lib.symbols.free_frame(ptr);

  await fetch("https://analytics.internal/frames", {
    method: "POST",
    body: frameView, // CRITICAL: Reading deallocated native memory
  });
}
```

#### Production Standard (Correct)
> **Standard**: Encapsulates the raw pointer in an explicit `NativeFrame` boundary utilizing `Symbol.dispose`. Zero-copy views are restricted to synchronous execution, and data escaping across an asynchronous I/O tick is cloned into JS engine memory, eliminating use-after-free and data corruption.
```typescript
import { dlopen, FFIType, toArrayBuffer, type Pointer } from "bun:ffi";

const lib = dlopen("libframe_processor.so", {
  next_frame: {
    args: [],
    returns: FFIType.ptr,
  },
  free_frame: {
    args: [FFIType.ptr],
    returns: FFIType.void,
  },
});

export class NativeFrame implements Disposable {
  readonly ptr: Pointer;
  readonly byteLength: number;
  #disposed = false;

  constructor(ptr: Pointer, byteLength: number) {
    this.ptr = ptr;
    this.byteLength = byteLength;
  }

  // Safe scoped view: synchronous access only
  getUnsafeView(): Uint8Array {
    if (this.#disposed) throw new Error("Attempted read from deallocated native frame");
    return new Uint8Array(toArrayBuffer(this.ptr, 0, this.byteLength));
  }

  // Safe async isolation: explicitly clones into JS-managed GC memory
  toClonedUint8Array(): Uint8Array {
    return new Uint8Array(this.getUnsafeView().slice().buffer);
  }

  [Symbol.dispose](): void {
    if (!this.#disposed) {
      this.#disposed = true;
      lib.symbols.free_frame(this.ptr);
    }
  }
}

export async function processNextFrameGood(): Promise<void> {
  using frame = new NativeFrame(lib.symbols.next_frame(), 1024);
  if (!frame.ptr) return;

  // Detach / clone across async boundary to preserve isolation
  const isolatedPayload = frame.toClonedUint8Array();

  await fetch("https://analytics.internal/frames", {
    method: "POST",
    body: isolatedPayload,
  });
  // Native pointer freed deterministically at end of scope via Symbol.dispose
}
```

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: Bun 1.2 FFI Zero-Copy Buffer Isolation Boundary and Lifetime Invariant

Bun 1.2 FFI Zero-Copy Buffer Isolation Boundary and Lifetime Invariant defines an industrial-grade behavioral standard for backend engineering. Mandates strict ownership demarcation, deterministic lifecycle tracking, and memory pinning boundaries when streaming binary frames between native C/Rust extensions and Bun 1.2 TypedArrays via bun:ffi. Prevents use-after-free, double-free, and cross-tick memory corruption caused by V8/JSC GC movements or premature deallocations of unmanaged native backing stores. 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: Retaining Raw Zero-Copy FFI ArrayBuffers Across Asynchronous Boundaries Without Pinned Lifecycles 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 DriftRetaining Raw Zero-Copy FFI ArrayBuffers Across Asynchronous Boundaries Without Pinned LifecyclesCritical
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 raw pointers returned from `bun

Engineers MUST ALWAYS isolate raw pointers returned from `bun:ffi` by either copying data via `.slice()` across asynchronous task boundaries or wrapping the pointer in a deterministic Disposable pattern (`Symbol.dispose` / `Symbol.asyncDispose`).

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 expose `toArrayBuffer(ptr, byteOffset, byteLength)` to consumers outside the synchronous scope that guarantees the native memory's validity.

Engineers MUST NOT expose `toArrayBuffer(ptr, byteOffset, byteLength)` to consumers outside the synchronous scope that guarantees the native memory's validity.

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

Services MUST explicitly manage native allocator lifecycles

Services MUST explicitly manage native allocator lifecycles: whenever native C/Rust memory is allocated for zero-copy JS consumption, an associated cleanup foreign function (e.g., `free_frame`) MUST be invoked deterministically.

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 SHOULD prefer Bun's built-in fast-call TypedArray zero-copy passing conventions while ensuring native pointers remain pinned and unaliased during parallel worker execution.

Code SHOULD prefer Bun's built-in fast-call TypedArray zero-copy passing conventions while ensuring native pointers remain pinned and unaliased during parallel worker execution.

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 cast native buffers into mutable TypedArrays if the underlying native extension retains a write reference, preventing data races and memory tearing.

Components NEVER cast native buffers into mutable TypedArrays if the underlying native extension retains a write reference, preventing data races and memory tearing.

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 Bun 1.2 FFI Zero-Copy Buffer Isolation Boundary and Lifetime Invariant critical for AI coding assistants?

Mandates strict ownership demarcation, deterministic lifecycle tracking, and memory pinning boundaries when streaming binary frames between native C/Rust extensions and Bun 1.2 TypedArrays via bun:ffi. Prevents use-after-free, double-free, and cross-tick memory corruption caused by V8/JSC GC movements or premature deallocations of unmanaged native backing stores. 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 (Retaining Raw Zero-Copy FFI ArrayBuffers Across Asynchronous Boundaries Without Pinned Lifecycles) 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.

1 Rule in Stack

Bun