Files
wasm-overhead-research/docs/JAVY_WASMER_ANALYSIS.md
Tristan Cartledge 226aa9283a Initial commit: JavaScript to WebAssembly compilation comparison
- 5 different JS-to-WASM implementations analyzed
- QuickJS (283KB) and Javy Static (519KB) are Wasmer-compatible
- Comprehensive size analysis and runtime compatibility testing
- Complete documentation and build automation
- Wasmer v6.1.0-rc.2 dynamic linking analysis included
2025-08-18 13:51:20 +10:00

3.6 KiB

Javy + Wasmer Compatibility Analysis

Summary

Static Build: Javy's static build (transform.wasm) works perfectly with Wasmer CLI
Dynamic Build: Javy's dynamic build approach is not compatible with Wasmer CLI

Test Results

Static Build (Working)

# File: transform.wasm (1.3MB raw, 519KB gzipped)
echo '{"users":[{"name":"Alice","age":30}]}' | wasmer run transform.wasm
# ✅ Output: {"message":"Data has been processed by Javy WASM",...}

Dynamic Build (Not Working)

# Files: plugin.wasm (1.2MB) + transform_dynamic.wasm (3.5KB)
echo '{"users":[{"name":"Alice","age":30}]}' | wasmer run transform_dynamic.wasm
# ❌ Error: unknown import "javy_quickjs_provider_v3"."canonical_abi_realloc"

Technical Analysis

Why Static Build Works

  • Self-contained: All JavaScript engine code is embedded in the WASM binary
  • No imports: Doesn't require external modules or dynamic linking
  • WASI compatible: Uses standard WASI interfaces for I/O
  • Single file: Wasmer can run it directly with wasmer run transform.wasm

Why Dynamic Build Fails

  • Dynamic linking: Requires importing functions from javy_quickjs_provider_v3
  • Multi-file: Needs both plugin.wasm (engine) + transform_dynamic.wasm (code)
  • Wasmer limitation: CLI doesn't support dynamic linking between WASM modules
  • Import resolution: No mechanism to resolve imports from separate WASM files

Wasmer CLI Limitations

The wasmer run command signature is:

wasmer run <INPUT> [ARGS]...
  • Only accepts a single WASM file as input
  • No built-in support for dynamic linking
  • No --plugin or --import-from flags
  • The --use flag is for containers, not WASM imports

Alternative Approaches

1. Wasmer SDK Integration

The Wasmer SDK (Rust, Python, etc.) might support:

  • Manual import resolution
  • Loading multiple WASM modules
  • Custom linking between modules

2. WASM Component Model

Future WASM standards may enable:

  • Component composition
  • Interface-based linking
  • Multi-module applications

3. Bundle Approach

Create a bundled WASM that includes both:

  • The Javy engine
  • The JavaScript code
  • Similar to static build but more flexible

Size Comparison

Approach Raw Size Gzipped Wasmer Compatible
Static Build 1.3MB 519KB Yes
Dynamic Build 1.2MB + 3.5KB ~488KB + 2KB No
QuickJS (Rust) 692KB 283KB Yes

Recommendations

For Wasmer CLI Usage

  1. Use Static Build: javy build -o transform.wasm transform.js

    • Single file deployment
    • 519KB gzipped
    • Perfect Wasmer compatibility
  2. Consider QuickJS: Alternative with smaller size (283KB gzipped)

    • Rust + QuickJS implementation
    • Also Wasmer compatible
    • More flexible for custom JavaScript engines

For Production Deployment

  • Static builds are ideal for Wasmer Edge, containers, and CLI usage
  • Dynamic builds might work with Wasmer SDK but require custom integration
  • Size vs Flexibility: Static builds are larger but simpler to deploy

Conclusion

Javy + Wasmer works best with static builds. The dynamic plugin approach, while more efficient for multiple JavaScript functions, is not compatible with Wasmer CLI due to its lack of dynamic linking support.

For Wasmer integration, choose:

  • Javy Static: 519KB, full JavaScript compatibility
  • QuickJS Rust: 283KB, custom JavaScript engine
  • Both provide excellent Wasmer compatibility for production use