Skip to content
Development
Agent

performance

<!-- GENERATED from docs/api/performance.md by scripts/build-agent-skill.mjs. Do not edit. -->

BOOST
From plugin
crossbind
14832 skills32 agents
Install
$ npx -y skills add crossbind/crossbind --agent claude-code

How it fires

How this agent gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.

Context preview

The summary Claude sees to decide when to auto-load this agent.

<!-- GENERATED from docs/api/performance.md by scripts/build-agent-skill.mjs. Do not edit. -->

Agent definition

performance.md

<!-- GENERATED from docs/api/performance.md by scripts/build-agent-skill.mjs. Do not edit. -->

Performance — defaults, what's safe to override, what to leave alone

> crossbind picks production-grade defaults for every Emscripten and CMake flag. **Most apps should change nothing.** This doc lists every default crossbind sets, marks each as "safe to override" or "don't touch", and shows when to reach for a tweak.

The rule: **if your build runs and your app works, the defaults are fine**. Only touch performance flags after measuring. AI agents should resist the urge to "optimize" defaults proactively.

Defaults reference

Emscripten flags (always-on, set by `buildWasm.js`)

| Flag | Value | Purpose | Safe to override? | |------|-------|---------|--| | `-O3` | (release) | Max optimization | 🔒 Don't override unless debugging a codegen issue | | `-O0` | (debug) | No optimization | ✅ Already debug — fine | | `-msimd128` | wasm | SIMD128 instruction set | 🔒 Already optimal | | `-sMEMORY64=1` | wasm64 only | 64-bit memory | 🔒 Set by target.arch, not flag override | | `-sSTACK_SIZE=1MB` (+ `-sSTACK_OVERFLOW_CHECK=1` in debug) | links with Rust | Stack for Rust code; a C++ build keeps Emscripten's 64KB | ✅ A size in the config wins (read § `STACK_SIZE`) | | `-pthread` + `-sPTHREAD_POOL_SIZE=Math.min(navigator.hardwareConcurrency \|\| 1, 2)` | mt only | Thread pool capped at 2 workers (1 if `hardwareConcurrency` is unavailable) | ✅ `PTHREAD_POOL_SIZE` is tunable (see below) | | `-sPTHREAD_POOL_SIZE_STRICT=2` | mt only | Abort if more pthreads requested than pool (no dynamic growth) | ⚠️ Drop to `1` (warn + grow) or `0` (silent grow) only if your code spawns unbounded threads | | `-lembind` | always | Embind binding lib | 🔒 Required | | `-Wl,--whole-archive` | Bridge archive only | Keep embind registrations (static initializers) alive | ✅ `export.wholeArchive: true` on the app restores the legacy all-archives layout; a library can declare the same in its own config | | `-fwasm-exceptions` | always | C++ exceptions via Wasm EH | 🔒 Required for proper `throw` semantics | | `-sWASM=1` | always | Output wasm (not asm.js) | 🔒 Don't touch | | `-sMODULARIZE=1` | always | ES module wrapper | 🔒 crossbind bundling depends on this | | `-sDYNAMIC_EXECUTION=0` | always | Disable eval / new Function | 🔒 Required for CSP-strict environments | | `-sRESERVED_FUNCTION_POINTERS=200` | always | Function table size | ⚠️ Increase if "Cannot enlarge function table" error | | `-sALLOW_MEMORY_GROWTH=1` | always | Heap can grow at runtime | 🔒 Don't disable | | `-sFORCE_FILESYSTEM=1` | always | Always include FS | 🔒 crossbind fs adapters depend on this | | `-sWASMFS` | browser, node | New filesystem backend | 🔒 OPFS depends on this | | `-Wl,--wrap=__wasi_fd_sync`, `-Wl,--wrap=__syscall_fdatasync` | node | `fsync` and `fdatasync` on a host file succeed instead of trapping in WasmFS's Node backend | 🔒 Don't touch | | `-sEXPORT_NAME=Module2` | always | JS namespace name | 🔒 crossbind bundling depends on this |

Emscripten 6.0.13 enables WebAssembly BigInt integration for every supported engine. Crossbind therefore relies on that toolchain default instead of passing the deprecated `WASM_BIGINT` setting; `i64` values still cross the JavaScript boundary as `bigint`.

Per-runtimeEnv flags

| runtimeEnv | `-sENVIRONMENT` | `-sEXPORTED_RUNTIME_METHODS` | |------------|---|---| | browser | `web,webview,worker` | `["FS", "ENV"]` | | edge | `web` | `["FS", "ENV"]` | | node | `node` | `["FS", "ENV"]` |

CMake flags (set by `getCmakeParameters.js`)

| Flag | Value | Purpose | Safe to override? | |------|-------|---------|--| | `-DPROJECT_NAME` | `general.name` | Internal | 🔒 Don't change | | `-DPROJECT_TARGET_*` | platform/arch/runtime/buildType | Routing | 🔒 Don't change | | `-DBUILD_TYPE=STATIC` | wasm, ios | Static libs | 🔒 Required by emcc / iOS frameworks | | `-DBUILD_TYPE=SHARED` | android | Shared libs | 🔒 Required by Android dynamic loading | | `-DBUILD_SHARED_LIBS=OFF` | wasm, ios | Inverse of above | 🔒 Don't override | | `-DCMAKE_TOOLCHAIN_FILE` | per-platform | toolchain pin | 🔒 Don't override | | `-DANDROID_PLATFORM=android-33` | android | NDK API level | ⚠️ Lower if targeting older devices (read § Android API level) | | `-DCMAKE_OSX_DEPLOYMENT_TARGET=15.1` | ios | iOS minimum | Fixed (read § iOS deployment target) |

System defaults

| Variable | Default | Source | |----------|---------|--------| | Android NDK | 30.0.16248370 | Docker image pin | | Android API | 33 | CMake flag | | iOS deployment | 15.1 | CMake flag | | Bitcode | embedded (release) / marker (debug) | iOS only | | Emscripten cache | `~/.crossbind/emscripten/` | Docker volume |

What's safe to override

`INITIAL_MEMORY` (default: 16MB Wasm default)

If you allocate large objects on startup (loading a model, opening a large geo dataset), the runtime grows memory dynamically — but you'll see growth pauses. Pre-allocating reduces pauses:

// crossbind.config.js
targetSpecs: [{
    platform: 'wasm',
    specs: { binary: { emccFlags: ['-sINITIAL_MEMORY=64MB'] } },
}]

Sweet spot: pre-allocate ~2× your steady-state usage. Going higher just delays startup.

`MAXIMUM_MEMORY` (default: ~2GB on wasm32)

Browser cap is ~4GB on wasm32. If you genuinely need more (large geospatial / scientific datasets), use **wasm64** target instead:

// crossbind.config.js
target: { arch: 'wasm64' }

Don't try to push wasm32 past 4GB — Wasm spec doesn't allow it.

`PTHREAD_POOL_SIZE` (default: `Math.min(navigator.hardwareConcurrency || 1, 2)`)

The default expression is evaluated by Emscripten at module load (not baked at build time):

  • Caps the pool at **2 worker threads**, even on 16-core devices.
  • Falls back to **1** if `navigator.hardwareConcurrency` is unavailable (older browsers, Node, edge runtimes).

Why the cap? Each pthread is a Web Worker with its own startup latency, JavaScript runtime and thread sta

Read more
Ships withcrossbind

Import C++ and Rust like JavaScript modules (WebAssembly & React Native)

Get the whole plugin

Other agents on crossbind.