npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

numrs-node

v0.1.1

Published

Node.js bindings for NumRs

Downloads

109

Readme

NumRs JavaScript Bindings

High-performance Node.js bindings for NumRs with zero-copy Float32 operations powered by Intel MKL.

✨ Features

  • 🚀 Zero-Copy Operations: Direct Float32Array access with no conversions (5-7x faster than standard API)
  • ⚡ Intel MKL Backend: Optimized BLAS operations with multi-threading support
  • 📊 25+ Operations: Binary, unary, reduction, linear algebra, and shape operations
  • 💾 Memory Efficient: 50% memory reduction using Float32 instead of Float64
  • 🔧 Type Safe: Full TypeScript definitions included

Performance

Benchmark results on 12th Gen Intel Core i9-12900HK:

| Operation Category | Average Throughput | Best Performance | |-------------------|-------------------|------------------| | Matrix Multiplication | 40.44 Gops/s | 114.13 Gops/s (512×512) | | Reduction Operations | 513.54 Mops/s | 803.79 Mops/s (min) | | Binary Operations | 164.59 Mops/s | 278 Mops/s (sub) | | Unary Operations | 161.75 Mops/s | 577 Mops/s (neg) |

See BENCHMARK_JS_12th_Gen_IntelR_CoreTM_i9-12900HK.md for complete benchmark results.

Installation

npm install
npm run build

Quick Start

const numrs = require('./index.node');

// Create Float32Arrays
const size = 10000;
const a = new Float32Array(size);
const b = new Float32Array(size);

// Initialize with random data
for (let i = 0; i < size; i++) {
  a[i] = Math.random();
  b[i] = Math.random();
}

// Zero-copy operations with clean API!
const result = numrs.add(a, [size], b, [size]);
console.log('Result:', result.slice(0, 5)); // Float32Array

API Reference

All operations work directly with Float32Arrays - no type conversions!

Binary Operations

Operations on two arrays of the same shape:

// Syntax: operation(data1, shape1, data2, shape2) -> Float32Array
numrs.add(a, [rows, cols], b, [rows, cols]);
numrs.sub(a, [rows, cols], b, [rows, cols]);
numrs.mul(a, [rows, cols], b, [rows, cols]);
numrs.div(a, [rows, cols], b, [rows, cols]);
numrs.pow(a, [rows, cols], b, [rows, cols]);

Unary Operations

Operations on a single array:

// Syntax: operation(data, shape) -> Float32Array
numrs.sin(data, [size]);
numrs.cos(data, [size]);
numrs.tan(data, [size]);
numrs.exp(data, [size]);
numrs.log(data, [size]);
numrs.sqrt(data, [size]);
numrs.abs(data, [size]);
numrs.relu(data, [size]);
numrs.sigmoid(data, [size]);
numrs.tanh(data, [size]);

Special case - Negation:

// Returns Array<number> instead of Float32Array
const result = numrs.neg(data, [size]); // Array<number>
const typedResult = new Float32Array(result);

Reduction Operations

Operations that reduce an array to a single scalar:

// Syntax: operation(data, shape) -> number
const total = numrs.sum(data, [rows, cols]);
const average = numrs.mean(data, [rows, cols]);
const maximum = numrs.max(data, [rows, cols]);
const minimum = numrs.min(data, [rows, cols]);
const variance = numrs.variance(data, [rows, cols]);

Linear Algebra

// Matrix multiplication: (M×K) @ (K×N) -> (M×N)
const result = numrs.matmul(
  matA, [M, K],  // First matrix
  matB, [K, N]   // Second matrix
); // Returns Float32Array of size M*N

// Dot product: returns scalar
const dotResult = numrs.dot(
  vecA, [size],
  vecB, [size]
); // Returns number

Shape Operations

// Transpose: (M×N) -> (N×M)
const transposed = numrs.transpose(data, [rows, cols]);

// Reshape: change dimensions without copying data
const reshaped = numrs.reshape(data, [oldShape], [newShape]);

Complete Example

See example.js for a comprehensive demo of all operations.

const numrs = require('./index.node');

// Binary operations
const a = new Float32Array([1, 2, 3, 4]);
const b = new Float32Array([5, 6, 7, 8]);
const sum = numrs.add(a, [4], b, [4]);
console.log('Sum:', sum); // Float32Array [6, 8, 10, 12]

// Unary operations
const angles = new Float32Array([0, Math.PI/4, Math.PI/2]);
const sines = numrs.sin(angles, [3]);
console.log('Sine:', sines);

// Reductions
const data = new Float32Array([1, 2, 3, 4, 5]);
console.log('Sum:', numrs.sum(data, [5])); // 15
console.log('Mean:', numrs.mean(data, [5])); // 3

// Matrix multiplication
const matA = new Float32Array([1, 2, 3, 4]); // 2×2
const matB = new Float32Array([5, 6, 7, 8]); // 2×2
const product = numrs.matmul(matA, [2, 2], matB, [2, 2]);
console.log('Matrix product:', product); // Float32Array [19, 22, 43, 50]

TypeScript Support

Full TypeScript definitions are available:

import type { Float32Array } from './index';

declare function add(
  data1: Float32Array,
  shape1: number[],
  data2: Float32Array,
  shape2: number[]
): Float32Array;

// ... all other operations

Benchmarking

Run the comprehensive benchmark suite:

node benchmark_gen.js

This generates a detailed markdown report with:

  • System configuration
  • Performance metrics for all 77 operation/size combinations
  • Throughput statistics (Mops/s and Gops/s)
  • Operation categories and summaries

Performance Tips

  1. Use Float32Arrays directly - Avoid conversions from/to regular JavaScript arrays
  2. Batch operations - Process larger arrays to amortize overhead
  3. Reuse arrays - Create Float32Arrays once and reuse them
  4. Matrix sizes - MKL performs best with matrices ≥256×256

Legacy API

The original JsArray-based API has been deprecated in favor of the zero-copy Float32Array API:

// Old (deprecated) - 5-7x slower
const a = numrs.array([2, 2], [1, 2, 3, 4], 'float32');
const b = numrs.array([2, 2], [5, 6, 7, 8], 'float32');
const result = numrs.add(a, b);

// New (recommended) - Zero-copy, ultra fast!
const aData = new Float32Array([1, 2, 3, 4]);
const bData = new Float32Array([5, 6, 7, 8]);
const result = numrs.add(aData, [2, 2], bData, [2, 2]);

Building from Source

# Debug build
cargo build

# Release build with optimizations
npm run build

# CPU-only (no WebGPU)
npm run build:cpu

License

See LICENSE for details.

See Also