This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: capacitor-7-native-bridge-thread-pool-scoping-standard

Capacitor 7 Native Bridge Thread-Pool Scoping & Dispatch Invariant

Fences native plugin JSON serialization, binary conversions, and I/O execution away from mobile UI threads into dedicated background dispatch queues. Prevents Android ANR watchdog timeouts and iOS Main Thread Watchdog crashes during high-throughput bridge messaging in Capacitor 7 plugins. Enforces concurrent background workers with explicit main-thread synchronization only during direct WebView manipulation.

Prohibited Anti-Pattern: Executing JSON Deserialization, Disk I/O, or Heavy Compute Directly Inside CapacitorPlugin Main Thread Dispatchers

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Capacitor 7 Native Bridge Thread-Pool Scoping & Dispatch Invariant - Fences native plugin JSON serialization, binary conversions, and I/O execution away from mobile UI threads into dedicated background dispatch queues. Prevents Android ANR watchdog timeouts and iOS Main Thread Watchdog crashes during high-throughput bridge messaging in Capacitor 7 plugins. Enforces concurrent background workers with explicit main-thread synchronization only during direct WebView manipulation.
globs: android/app/src/main/java/**/*.java, android/app/src/main/java/**/*.kt, ios/App/App/**/*.swift, ios/App/App/**/*.m, src/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/capacitor-7-native-bridge-thread-pool-scoping-standard"
---

# Capacitor 7 Native Bridge Thread-Pool Scoping & Dispatch Invariant

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Executing JSON Deserialization, Disk I/O, or Heavy Compute Directly Inside CapacitorPlugin Main Thread Dispatchers

## System Constraints
You are a Principal Mobile Architect enforcing Capacitor 7 Native Bridge Thread-Pool Scoping. In Capacitor 7, plugin methods annotated with @PluginMethod execute on the native UI/Main thread by default on iOS, and synchronous message passing blocks WebKit rendering queues. You must mandate off-main-thread execution for all deserialization, file/network I/O, and cryptographic operations via dedicated Grand Central Dispatch (GCD) queues on iOS and Coroutine/Executor thread pools on Android.

## Strict Guidelines
- Engineers MUST ALWAYS offload CPU-intensive parsing, file reading, and cryptographic routines to background threads before invoking PluginCall.resolve() or PluginCall.reject().
- Engineers MUST NOT invoke blocking disk I/O, network requests, or large SQLite operations directly inside the raw @PluginMethod or @objc func body without dispatching to a concurrent queue.
- iOS Swift plugins MUST use DispatchQueue.global(qos: .userInitiated).async or Swift Concurrency Task.detached(priority: .userInitiated) to wrap heavy bridge logic.
- Android Kotlin plugins MUST use CoroutineScope(Dispatchers.IO).launch or execute via bridge.executeOnBackgroundThread { ... } rather than running on the main Looper.
- Engineers MUST ensure that any UI-layer calls (e.g., modifying WebView directly, showing native alerts) switch explicitly back to DispatchQueue.main.async or activity.runOnUiThread.
- TypeScript bridge consumers SHOULD debounce or chunk payloads exceeding 256KB to minimize bridge serialization latency and memory spikes across the JS-to-Native barrier.

## Bad vs Good Implementations
### Android Kotlin: Offloading Heavy Bridge I/O to Dispatchers.IO

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Executing file read and decryption directly inside the PluginMethod without a background dispatcher risks triggering an Application Not Responding (ANR) error and drops frames on the main thread.
```kotlin
@CapacitorPlugin(name = "SecureStorage")
class SecureStoragePlugin : Plugin() {
    @PluginMethod
    fun readEncryptedPayload(call: PluginCall) {
        val key = call.getString("key") ?: return call.reject("Missing key")
        // VIOLATION: Disk I/O and cryptographic decrypt executing directly on Capacitor caller thread
        val file = File(context.filesDir, "$key.enc")
        val rawBytes = file.readBytes() 
        val decryptedString = CryptoManager.decrypt(rawBytes)
        
        val ret = JSObject()
        ret.put("data", decryptedString)
        call.resolve(ret)
    }
}
```

#### Production Standard (Correct)
> **Standard**: Encapsulates file reads and crypto calculations within a CoroutineScope bound to Dispatchers.IO, isolating heavy compute from the main application loop.
```kotlin
@CapacitorPlugin(name = "SecureStorage")
class SecureStoragePlugin : Plugin() {
    private val pluginScope = CoroutineScope(Dispatchers.IO + SupervisorJob())

    @PluginMethod
    fun readEncryptedPayload(call: PluginCall) {
        val key = call.getString("key") ?: run {
            call.reject("Missing key")
            return
        }

        pluginScope.launch {
            try {
                val file = File(context.filesDir, "$key.enc")
                if (!file.exists()) {
                    call.reject("File not found")
                    return@launch
                }
                val rawBytes = file.readBytes()
                val decryptedString = CryptoManager.decrypt(rawBytes)
                
                val ret = JSObject().apply {
                    put("data", decryptedString)
                }
                call.resolve(ret)
            } catch (e: Exception) {
                call.reject("Decryption failure", e)
            }
        }
    }
}
```

### iOS Swift: Scoping Bridge Work to Dedicated QoS Queue

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Calling Data(contentsOf:) and JSONSerialization synchronously on the bridge invocation queue locks UI updates and can trigger the iOS watchdog kill timer (0x8badf00d).
```swift
@objc(FileProcessorPlugin)
public class FileProcessorPlugin: CAPPlugin, CAPBridgedPlugin {
    public let identifier = "FileProcessorPlugin"
    public let jsName = "FileProcessor"
    public let pluginMethods: [CAPPluginMethod] = [
        CAPPluginMethod(name: "processLargeFile", returnType: CAPPluginReturnPromise)
    ]

    @objc func processLargeFile(_ call: CAPPluginCall) {
        guard let path = call.getString("path") else { call.reject("No path"); return }
        // VIOLATION: Synchronous file ingestion and JSON transformation blocks WebKit bridge
        if let data = try? Data(contentsOf: URL(fileURLWithPath: path)),
           let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
            call.resolve(json)
        } else {
            call.reject("Processing error")
        }
    }
}
```

#### Production Standard (Correct)
> **Standard**: Explicitly fences the blocking disk read and JSON serialization into a dedicated background DispatchQueue with userInitiated QoS, preserving smooth 60/120fps UI rendering.
```swift
@objc(FileProcessorPlugin)
public class FileProcessorPlugin: CAPPlugin, CAPBridgedPlugin {
    public let identifier = "FileProcessorPlugin"
    public let jsName = "FileProcessor"
    public let pluginMethods: [CAPPluginMethod] = [
        CAPPluginMethod(name: "processLargeFile", returnType: CAPPluginReturnPromise)
    ]
    private let processingQueue = DispatchQueue(label: "com.app.fileprocessor.queue", qos: .userInitiated, attributes: .concurrent)

    @objc func processLargeFile(_ call: CAPPluginCall) {
        guard let path = call.getString("path") else { call.reject("No path"); return }
        
        processingQueue.async {
            do {
                let url = URL(fileURLWithPath: path)
                let data = try Data(contentsOf: url)
                guard let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
                    call.reject("Invalid JSON payload")
                    return
                }
                call.resolve(json)
            } catch {
                call.reject("Failed reading payload: \(error.localizedDescription)")
            }
        }
    }
}
```

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: Capacitor 7 Native Bridge Thread-Pool Scoping & Dispatch Invariant

Capacitor 7 Native Bridge Thread-Pool Scoping & Dispatch Invariant defines an industrial-grade behavioral standard for mobile engineering. Fences native plugin JSON serialization, binary conversions, and I/O execution away from mobile UI threads into dedicated background dispatch queues. Prevents Android ANR watchdog timeouts and iOS Main Thread Watchdog crashes during high-throughput bridge messaging in Capacitor 7 plugins. Enforces concurrent background workers with explicit main-thread synchronization only during direct WebView manipulation. 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: Executing JSON Deserialization, Disk I/O, or Heavy Compute Directly Inside CapacitorPlugin Main Thread Dispatchers 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 DriftExecuting JSON Deserialization, Disk I/O, or Heavy Compute Directly Inside CapacitorPlugin Main Thread DispatchersCritical
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 offload CPU-intensive parsing, file reading, and cryptographic routines to background threads before invoking PluginCall.resolve() or PluginCall.reject().

Engineers MUST ALWAYS offload CPU-intensive parsing, file reading, and cryptographic routines to background threads before invoking PluginCall.resolve() or PluginCall.reject().

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 invoke blocking disk I/O, network requests, or large SQLite operations directly inside the raw @PluginMethod or @objc func body without dispatching to a concurrent queue.

Engineers MUST NOT invoke blocking disk I/O, network requests, or large SQLite operations directly inside the raw @PluginMethod or @objc func body without dispatching to a concurrent queue.

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

iOS Swift plugins MUST use DispatchQueue.global(qos

iOS Swift plugins MUST use DispatchQueue.global(qos: .userInitiated).async or Swift Concurrency Task.detached(priority: .userInitiated) to wrap heavy bridge logic.

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

Android Kotlin plugins MUST use CoroutineScope(Dispatchers.IO).launch or execute via bridge.executeOnBackgroundThread { ... } rather than running on the main Looper.

Android Kotlin plugins MUST use CoroutineScope(Dispatchers.IO).launch or execute via bridge.executeOnBackgroundThread { ... } rather than running on the main Looper.

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 ensure that any UI-layer calls (e.g., modifying WebView directly, showing native alerts) switch explicitly back to DispatchQueue.main.async or activity.runOnUiThread.

Engineers MUST ensure that any UI-layer calls (e.g., modifying WebView directly, showing native alerts) switch explicitly back to DispatchQueue.main.async or activity.runOnUiThread.

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

TypeScript bridge consumers SHOULD debounce or chunk payloads exceeding 256KB to minimize bridge serialization latency and memory spikes across the JS-to-Native barrier.

TypeScript bridge consumers SHOULD debounce or chunk payloads exceeding 256KB to minimize bridge serialization latency and memory spikes across the JS-to-Native barrier.

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 Capacitor 7 Native Bridge Thread-Pool Scoping & Dispatch Invariant critical for AI coding assistants?

Fences native plugin JSON serialization, binary conversions, and I/O execution away from mobile UI threads into dedicated background dispatch queues. Prevents Android ANR watchdog timeouts and iOS Main Thread Watchdog crashes during high-throughput bridge messaging in Capacitor 7 plugins. Enforces concurrent background workers with explicit main-thread synchronization only during direct WebView manipulation. 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 (Executing JSON Deserialization, Disk I/O, or Heavy Compute Directly Inside CapacitorPlugin Main Thread Dispatchers) 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 MOBILE Rules

View all rules →
1 Rule in Stack

Capacitor