Skip to main content
Voltaire provides three entrypoints with identical APIs. All implement the VoltaireAPI interface, ensuring compile-time errors if APIs diverge.

Three Entrypoints

All three entrypoints export identical namespaces and types. Switch implementations by changing the import path - no code changes required.

JS (Default)

Pure TypeScript/JavaScript. Works everywhere JavaScript runs.
Shares the ox peer dependency for amortized bundle costs.
A useful default - easy to debug and performant enough for most use cases.

WASM

WebAssembly bindings to Zig implementations. Portable high-performance.
The WASM entrypoint exports the same API as JS. Switch by changing the import path.
We recommend WASM for crypto operations - usually faster and smaller bundle size than JS equivalents. Best for applications needing maximum performance.
Design trade-off: Voltaire’s published WASM builds target a balance of strong performance and small bundle size. If you need maximum raw speed for specific workloads, build from source using the performance-optimized target (ReleaseFast). See /dev/build-system#typescript-targets and /dev/wasm#build-modes.

Native FFI (Bun)

Direct bindings to Zig via Bun FFI. Maximum performance.
The Native entrypoint exports the same API as JS. Switch by changing the import path.
Runtime support: Native FFI is Bun-only. In Node.js, use the JS or WASM entrypoint. Ensure the compiled .dylib/.so/.dll is available (run zig build build-ts-native).

Per-Module Imports

For fine-grained control, import specific implementations:

Performance Considerations

Performance is nuanced. WASM/Native aren’t always faster than TypeScript.
Bridging overhead: Crossing the JS↔WASM or JS↔FFI boundary has constant overhead (~1-10μs). For cheap operations (simple math, short string manipulation), this overhead can exceed the operation itself. When WASM/Native wins:
  • Cryptographic operations (keccak256, secp256k1, BLS) - 5-15x faster
  • Large data encoding/decoding (RLP, ABI with big payloads)
  • Batch operations that amortize bridging cost
When JS wins:
  • Simple operations (hex encoding small values, address validation)
  • String/hex formatting helpers that map to JS built-ins (for example, toHex())
  • Very small, trivial conversions where JS↔WASM overhead dominates
  • Single-item operations with low computational cost
  • When avoiding async overhead matters
Bundle size: For cryptography specifically, WASM is often smaller than equivalent pure-JS implementations. A full JS secp256k1 library can be 50-100KB, while WASM crypto modules are typically 20-40KB.
Benchmark your actual workload. Default implementations are chosen for common use cases, but your specific access patterns may differ.

WASM Limitations

All other modules including BLS12-381, KZG, and BN254 work in WASM.