Getting Started
zig-bind is a high-performance, zero-allocation JavaScript and TypeScript binding engine for Zig WebAssembly. It bypasses heavy object wrapper abstractions, allowing you to interface directly with WebAssembly linear memory using standard, flyweight-cached JavaScript TypedArrays.
Installation
Section titled “Installation”Install the core registry package into your modern JavaScript runtime environment.
pnpm add zig-bindnpm install zig-bindyarn add zig-bindQuick Start Guide
Section titled “Quick Start Guide”Follow these steps to write your high-performance business logic, compile it using the CLI tool, and execute zero-copy calculations in JavaScript/TypeScript.
-
Write Your Business Logic in Zig
Create your native functionality. Ensure your exported functions use the
pub export fnmodifier so they can be discovered by the binding engine compiler.src/math.zig const std = @import("std");// Your high-performance business logicpub export fn add_vectors(a_ptr: [*]f32, b_ptr: [*]f32, c_ptr: [*]f32, len: usize) void {var i: usize = 0;while (i < len) : (i += 1) {c_ptr[i] = a_ptr[i] + b_ptr[i];}} -
Compile the WebAssembly Binary Use the
zig-bindCLI tool to compile your code. For a simple standalone runtime environment without WASI requirements, pass the--standaloneflag:Terminal window npx zig-bind build src/math.zig --out ./dist/math --standalone -
Initialize the Core Registry Load the compiled
.wasmbinary into your JavaScript runtime and feed it into theZigBindRegistrymanager:src/index.ts import fs from 'node:fs';import { ZigBindRegistry } from 'zig-bind';// Load the compiled WebAssembly binaryconst wasmBuffer = fs.readFileSync('./dist/math.wasm');const { instance } = await WebAssembly.instantiate(wasmBuffer, {});// Instantiate the high-speed registry agentexport const registry = new ZigBindRegistry(instance);``` -
Execute High-Speed, Zero-Copy Calculations Allocate vectors seamlessly using familiar syntax and run your compiled native operations with zero garbage collection churn:
import { registry } from './index.js';// 1. Instantly allocate and fill memory spaces using native syntaxconst vecA = registry.alloc('f32', [10.0, 20.0, 30.0, 40.0]);const vecB = registry.alloc('f32', 4);vecB.set([1.5, 2.5, 3.5, 4.5]); // Pure native TypedArray method!const vecC = registry.alloc('f32', 4);// 2. Bind the function by its string nameconst add = registry.bind('add_vectors');// 3. Execute! Arity inferencing automatically passes trailing length argumentsadd(vecA, vecB, vecC);console.log(Array.from(vecC));// [11.5, 22.5, 33.5, 44.5]// 4. Wipe arena tokens when finished to reuse pointers on subsequent cyclesregistry.reset();
Next Architecture Steps
Section titled “Next Architecture Steps”- Memory Management & Resets — Leverage the underlying flyweight cache strategies to guarantee a zero GC footprint.
- Binding Advanced Signatures — Handle non-primitive matrices, strings, structs, and complex multi-threaded worker pools.