munum - v0.3.0
    Preparing search index...

    munum - v0.3.0

    πŸ…ΌπŸ†„πŸ…½πŸ†„πŸ…Ό

    ΞΌNum - Micro 3D Math Library


    license: MIT Docs.rs Crates.io npm codecov build

    munum is a minimalistic numerical library for high-performance 3D math with Rust, WebAssembly, and JavaScript bindings. The math is written once in no_std Rust; the same source powers a native crate, a compact WebAssembly module, and two JavaScript surfaces β€” a zero-copy WebAssembly binding and a dependency-free pure-JS implementation with the same API.

    [JavaScript] Install via npm:

    npm install --save munum
    

    [Rust] Install as Cargo dependency:

    cargo add munum
    

    Features:

    • std - enables std support. Enabled by default.
    • libm - enables trigonometry related functions in no_std environment using libm.
    • jsmath - enables trigonometry related functions in no_std WebAssembly environment using the JS Math binding.
    • serde - enables serde serialize/deserialize implementations.
    • wasm - produces the WebAssembly module and WebAssembly component (WIP).

    Sample usage to build a perspective camera view-projection matrix below:

    (Try it yourself here)

    import { lookAt, perspective, Mat4, Vec3 } from 'munum'; // Or load from CDN, e.g. 'https://unpkg.com/munum@latest'

    using eye = new Vec3(1, 1, 1);
    using target = new Vec3(0, 0, 0);
    using up = new Vec3(0, 1, 0);
    const view = lookAt(eye, target, up);

    const aspectRatio = width / height;
    const yfov = Math.PI / 4;
    const znear = 1;
    const zfar = 100;

    using viewProj = perspective(aspectRatio, yfov, znear, zfar).mul(view);

    The WebAssembly binding stores munum values directly in the WebAssembly module's linear memory and operates on them in place (zero-copy), so vectors and matrices need to be deallocated after use. Memory is managed per-MemoryManager: each value captures a manager (the module default unless one is passed) and is auto-reclaimed by that manager's embedded FinalizationRegistry, so explicit cleanup via using (which calls .free() when the value goes out of scope) or a manual .free() is recommended but not required.

    To wrap existing memory without owning it, use the view factory β€” disposing a borrowed view never frees the underlying storage:

    import { Vec3, float64View } from 'munum/js';

    // Zero-copy view over a raw glTF Float64Array (pure-JS build):
    const positions = new Float64Array(gltfBuffer); // e.g. accessor data, packed vec3s
    const p1 = Vec3.view(float64View(positions), 3 * 3 * 8); // 2nd vertex (byteOffset)
    p1.scale(2); // mutates `positions` in place
    // p1.free() is a no-op β€” `positions` is owned by the caller.

    The module is loaded through a portable top-level-await loader (munum/wasm) that inlines the WebAssembly module β€” it works unchanged in Node, browsers, and any bundler, with no WebAssembly-ESM integration or asset-loader configuration required.

    Import from munum/js for the pure-JavaScript implementation, which mirrors the WebAssembly binding's API but has no WebAssembly dependency:

    import { lookAt, perspective, Mat4, Vec3 } from 'munum/js';
    

    Sample usage to build a perspective camera view-projection matrix:

    use core::f32::{consts::PI, INFINITY};
    use munum::{transform, vec3};

    let eye = vec3(0_f32, 2., 0.);
    let target = vec3(0., 0.6, 0.);
    let up = vec3(0., 0., -1.);
    let view = transform::look_at(eye, target, up);

    let proj = transform::perspective(2., PI/2., 1., INFINITY);

    let view_proj = proj * view;

    Requires Node.js >= 26 and a Rust toolchain (edition 2024, rustc >= 1.85) with the wasm32-unknown-unknown target.

    rustup target add wasm32-unknown-unknown
    npm install
    npx playwright install chromium # one-time: the browser test project needs Chromium

    npm run build # cargo -> wasm-opt -> loader gen -> jco component -> vite (dist/)
    npm run lint # eslint (flat config)
    npm run typecheck # tsc --noEmit
    npm test # vitest: node + browser (Chromium) projects
    npm run test:rust # cargo test --all-features
    npm run doc # typedoc -> docs/

    See AGENTS.md for the full architecture, build pipeline, and contributor guidelines.

    This repository and the code inside it is licensed under the MIT License. Read LICENSE for more information.