
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
@harperfast/hnsw
Advanced tools
Persistent, incrementally-maintained, concurrently-searchable native HNSW for Node.js: a memory-mapped fixed-slot graph file with off-event-loop search, seqlock concurrency, int8 asymmetric distance, and bitset/predicate filtering.
Persistent, incrementally-maintained, concurrently-searchable HNSW vector index for Node.js — a native (Rust) traversal engine over a memory-mapped fixed-slot graph file.
Most HNSW libraries for Node either keep the graph in JS objects (slow per-visit cost, GC pressure) or wrap an in-memory C++ index with no durable incremental persistence. This one is built around a different contract:
insert/remove/search), or mirroring (writeNodeRaw/clearNode: a host application
that already maintains an HNSW graph mirrors it in and gets the native search path —
this is how Harper integrates it).Durability is deliberately relaxed: the file is msync'd on a cadence with a transaction watermark, and the intended recovery model is "replay indexing from the watermark" against the host's authoritative record store. Approximate indexes don't need per-commit fsyncs; they need cheap, bounded catch-up. See DESIGN.md for the format, the concurrency model, measured baselines, and the reasoning behind every trade.
npm install @harperfast/hnsw
Prebuilds are not published yet: building requires a Rust toolchain
(npm run build, or automatically on install when cargo is available). Linux x86_64 is the
performance target (AVX2); macOS works (scalar fallback); Windows is untested.
const { Plane } = require('@harperfast/hnsw');
const plane = Plane.create('/data/vectors.hnsw', 768, 128, 10_000_000);
const id = plane.insert(myFloat32Vector);
const hits = await plane.search(queryVector, 10, 512); // [{ id, distance }, ...]
// filtered: allow-bitset over node ids
const allowed = new Uint8Array(Math.ceil(plane.idHighWater() / 8));
// ... set bits ...
const filtered = await plane.search(queryVector, 10, 512, allowed);
// or a JS predicate, batched off the event loop
const predicated = await plane.searchWithPredicate(queryVector, 10, 512, (ids) =>
Uint8Array.from(ids, (id) => (isVisible(id) ? 1 : 0))
);
Full API in index.d.ts.
cargo run --release --bin bench -- 1000000 768 100 512 /tmp/bench.hnsw 128 8 builds a 1M ×
768-d graph on a calibrated Gaussian-mixture corpus, reports p50/p95/p99, per-visit cost,
brute-force recall@10, and a concurrent-throughput pass. Numbers from the design work
(Linux, single box): p50 0.75 ms, 0.33 µs/visit, recall@10 0.999 — ~9× the wall-clock and
~13× the per-visit cost of a well-optimized pure-JS implementation of the same graph at
equal recall.
Extracted from the Harper vector-index engine; the format (v2) and API are young and may change with a major version + reindex. Roadmap: prebuilds, binary-quantized slot format (~4× smaller traversal plane), Matryoshka dimension truncation, mremap growth, index slicing with native top-k merge.
Apache-2.0
FAQs
Persistent, incrementally-maintained, concurrently-searchable native HNSW for Node.js: a memory-mapped fixed-slot graph file with off-event-loop search, seqlock concurrency, int8 asymmetric distance, and bitset/predicate filtering.
We found that @harperfast/hnsw demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 7 open source maintainers collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.