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

EntrypointImportRuntimeUse Case
JS@tevm/voltaireAny JS runtimeDefault, universal compatibility
WASM@tevm/voltaire/wasmBrowser, Node, Bun, DenoHigh performance, portable
Native@tevm/voltaire/nativeBunMaximum performance via FFI
// All three have the SAME API
import { Address, Keccak256 } from '@tevm/voltaire'        // JS (default)
import { Address, Keccak256 } from '@tevm/voltaire/wasm'   // WASM
import { Address, Keccak256 } from '@tevm/voltaire/native' // Native FFI
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.
import { Keccak256, Address, Hex } from '@tevm/voltaire'

const hash = Keccak256.hash(Hex.toBytes(Hex.fromString('hello')))
const addr = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')
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.
import { Keccak256, Secp256k1, Hex, Address } from '@tevm/voltaire/wasm'

// Same API as JS entrypoint
const hash = Keccak256.hash(data)
const recovered = Secp256k1.recoverAddress(hash, signature)
const addr = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')

// All namespaces work identically
Secp256k1.sign(message, privateKey)
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.
import { Keccak256, Address, Secp256k1 } from '@tevm/voltaire/native'

// Same API as JS entrypoint
const hash = Keccak256.hash(data)
const addr = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e')
const signature = Secp256k1.sign(message, privateKey)
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:
// Keccak256 variants
import { Keccak256 } from '@tevm/voltaire/Keccak256'           // JS (default)
import { Keccak256 } from '@tevm/voltaire/Keccak256/wasm'      // WASM
import { Keccak256 } from '@tevm/voltaire/Keccak256/native'    // Native FFI

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.
OperationJSWASMNativeDefault
keccak2561x~5x~10xJS
secp256k1 sign1x~8x~15xJS
secp256k1 recover1x~8x~15xJS
RLP encode1x~1.2x~1.5xJS
Hex encode1x~1.1x~1.2xJS
Benchmark your actual workload. Default implementations are chosen for common use cases, but your specific access patterns may differ.

WASM Limitations

ModuleWASM StatusReasonAlternative
BIP-39 / HD Wallet❌ Not availableRequires libwally-core (C library)Use native or JS entrypoint
All other modules including BLS12-381, KZG, and BN254 work in WASM.