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

@gcu/natra

v0.2.0

Published

ndarray operations backed by atra-compiled Wasm kernels. NumPy-compatible element-wise ops, reductions, broadcasting, strided views. Designed to pair with @gcu/adder (Python) for numpy-style code; standalone JS API also available.

Readme

@gcu/natra

ndarray operations for JavaScript, backed by atra-compiled Wasm kernels. NumPy-compatible element-wise ops, reductions (sum, min, max, prod, nan-variants), broadcasting, strided views. Designed to pair with adder for numpy-style Python code; standalone JS API also available.

Part of Auditable. Architecture notes at SPEC.md.

Pre-1.0 — APIs may break on minor version bumps.

Install

npm install @gcu/natra @gcu/atra

Usage

import { natra } from '@gcu/natra';

const nx = await natra({ pages: 256 });
const a = nx.array([1, 2, 3, 4]);
const b = nx.array([10, 20, 30, 40]);
nx.add(a, b);          // [11, 22, 33, 44]
nx.sum(a);             // 10
nx.reshape(nx.arange(12), [3, 4]);

f32 (single-precision) arrays

Pass dtype: 'f32' when creating arrays. f32 routes through alpack's sgemm/sdot for ~2× speedup on large matmul + dot. f32 element-wise ops are not yet routed (v0.2.0 partial dispatch); they throw a clear error.

const A = nx.array([[1, 2], [3, 4]], { dtype: 'f32' });
const B = nx.array([[5, 6], [7, 8]], { dtype: 'f32' });
nx.scope(s => s.matmul(A, B));      // routes to alas.sgemm — 2× faster than dgemm
nx.scope(s => s.dot(a32, b32));     // routes to alas.sdot

Dtype mismatch throws (no auto-upcast). Convert manually if needed.

Adder integration (numpy-style)

import '@gcu/natra/adder';   // registers with adder's import hook
// Now in an adder cell: `import numpy as np` — resolves to natra.

Performance

Underpinned by @gcu/alpack — a hand-written wasm BLAS in atra. The Level 3 routines (dgemm, sgemm) use 2×2 register-blocked microkernels with f64x2/f32x4 SIMD and FMA. Level 2/1 routines and ALPACK factorizations (LU, Cholesky) are similarly SIMD'd.

Benchmarks (AMD Ryzen AI 9 HX 370, single-threaded):

| Workload | natra f64 | TF.js wasm f32 | numpy ST f64 (native) | |---|---:|---:|---:| | 200×200 matmul | 0.85 ms | 0.34 ms | 0.26 ms | | 500×500 matmul | 14 ms | 4.9 ms | 4.3 ms | | 1000×1000 matmul | 156 ms | 38 ms | — | | 100×100 solve (LU) | 0.08 ms | — | 0.04 ms | | 200×200 solve | 0.69 ms | — | 0.19 ms | | 100×100 cholesky | 0.12 ms | — | — | | 100K vector add | 0.030 ms | — | 0.091 ms |

Notable:

  • At 100K vector add, natra is faster than NumPy (the Python-C call overhead dominates over actual SIMD work at this size).
  • For solves and Cholesky at N ≤ 200, natra is within 2-3× of native numpy LAPACK. Practical for daily-driver geological / regression workloads.
  • At 1000×1000 matmul, natra (f64) hits ~38 GFLOPS — about 50% of f64 SIMD peak. The wasm-vs-native AVX-512 gap caps single-threaded f64 wasm at roughly 3× behind native.
  • f32 sgemm matches or beats TF.js wasm f32 at N ≤ 100. Within 1.4× at larger sizes — the practical wasm BLAS ceiling.

Memory model — scope promotion and the discard pattern

natra runs each operation in a bump-allocated arena and reclaims everything when the arena exits. Returning an array from scope() promotes it to permanent memory so it survives past the scope. There is no public free API (yet) — promoted arrays live for the lifetime of the natra context.

This matters in tight loops. If you call scope many times and don't need the result of each iteration:

// Leaks: each iteration promotes a fresh result to permanent memory.
for (let i = 0; i < 1000; i++) ctx.scope(s => s.add(big, big));

// Discards: braced arrow returns undefined, scope reclaims the result.
for (let i = 0; i < 1000; i++) ctx.scope(s => { s.add(big, big); });

For 1 M-element arrays the leak is 8 MB per call; ~125 iterations exhaust the default 1 GB maxPages cap. For benchmark loops, side-effect work, or anywhere you don't capture the result, prefer the braced form.

When you DO need the result, capture it once and reuse it across the scope's lifetime, rather than re-allocating on each iteration.

License

MIT.