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

vanilla-test

v2.1.3

Published

Zero-build, Web-standard JavaScript testing for Node and browsers

Readme

vanilla-test

Website · JavaScript README · Rust README · Testing · Benchmarks · Changelog

CI npm version npm downloads crates.io version crates.io downloads Node.js >=22.12 Chrome Rust >=1.85 Rust WebAssembly license

Minimal testing in the language you already ship. JavaScript uses one native ES module in Node.js and browsers. Rust uses one dependency-free, unsafe-free implementation natively and compiles the same Rust unit tests into browser WebAssembly.

Choose your language

| Language | Native path | Browser path | Package | Language documentation | | --- | --- | --- | --- | --- | | JavaScript | Node.js 22.12+ native ESM | Standards-only browser modules | npm | Node + browser | | Rust | Rust 1.85+ and Cargo | The same Rust unit-test harness compiled to wasm32-unknown-unknown | crates.io | Native + browser WASM |

JavaScript is the right lane when the application is JavaScript and needs identical source in Node and a real browser. Rust is the right lane when the application and tests should stay Rust across native and browser targets. The APIs preserve the same sequential lifecycle and first-decision rule, but each implementation stays idiomatic to its language rather than wrapping the other runtime.

Install

JavaScript

npm install vanilla-test

Rust

cargo add vanilla-test

Check the terminal for a successful exit. JavaScript and Rust package versions share the same major and minor line; patches may advance independently.

One lifecycle, native implementations

JavaScript

import VanillaTest from 'vanilla-test';

const test = new VanillaTest();
test.expects('addition preserves the total');

try {
    test.compare(1 + 2, 3);
    test.pass();
} catch (error) {
    console.error(error);
    test.fail();
}

test.done();
const result = test.report();

The same module can run unchanged in Node and the browser. Host adapters decide how to display the immutable result or map it to an exit status.

Rust

use vanilla_test::VanillaTest;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut test = VanillaTest::new();
    test.expects("addition preserves the total")?;
    if 1 + 2 == 3 { test.pass()?; } else { test.fail()?; }
    test.done()?;

    let result = test.report()?;
    assert!(result.ok, "{}", result.report);
    Ok(())
}

Native Rust uses ordinary results and the type system. The browser lane compiles the existing Rust unit tests—there is no copied browser suite:

rustup target add wasm32-unknown-unknown
cargo install vanilla-test --version 2.1.0
cargo vanilla-test --browser

The Cargo subcommand builds the current package's existing library tests and emits dist/vanilla-test/ with the WASM harness and static loader. That page checks its visible browser UI, canonical wasm32-unknown-unknown target label, artifact response, WASM MIME type, streaming instantiation, and main() export before calling the generated Rust harness once. Every check appears on-page and in DevTools. Pass --page tests/browser.html to use a compatible site page whose marked visible-text checks run alongside the Rust harness. A zero harness status passes; a panic or nonzero status fails. Native cargo test prints the individual Rust names and assertion diagnostics because the bare browser target has no stdout. Run and inspect the current Rust browser example.

Why Vanilla Test

Vanilla is a control-surface choice: keep fewer test-specific layers between source and evidence.

  • One language end to end. Choose JavaScript for Node + browser or Rust for native + browser WASM.
  • One test inventory per language. Runtime adapters execute the same source instead of maintaining browser copies.
  • Native execution. Node and Chrome run the JavaScript module directly; Cargo and the browser run Rust and WebAssembly directly.
  • No build framework. JavaScript needs no bundle or transpiler. The dependency-free Cargo subcommand uses Cargo's standard target support with no wasm framework or generated glue.
  • Small contracts. One active test, exact unique descriptions, first decision wins, undecided completion fails, and reporting seals the suite.
  • Auditable evidence. CI publishes runtime-specific tests, native V8 coverage for JavaScript, built-in LLVM source coverage for Rust, package smoke checks, a real-Chrome Rust WASM run, and reproducible benchmarks.

The JavaScript package deliberately keeps its runtime validation and ANSI rendering dependencies focused. The Rust crate has zero dependencies and forbids unsafe code.

Benchmarks

Benchmarks are separate by language and protocol. They describe observed work on one recorded machine; they are not a claim that unlike runtimes or workloads are interchangeable.

| Language/runtime | Verified workload | Median | Throughput | | --- | --- | ---: | ---: | | JavaScript · Node 24.18 | 1,000,000 passing cases across 1,000 suites, lifecycle + report | 2,589.836 ms | 386,125 cases/s | | JavaScript · Chrome 151 | The same 1,000,000-case browser workload | 2,074.900 ms | 481,951 cases/s | | Rust 1.85 · native optimized | 100,000 uniquely named passing cases, lifecycle timed and report validated | 13.278 ms | 7,531,368 cases/s |

The JavaScript figures are five-sample medians from the published native-pipeline dataset, including exact runtime, memory, source, and machine provenance. The Rust figure is a five-sample median after one warmup on the same Intel Core Ultra 9 275HX machine; its raw samples and provenance record the timed boundary and post-timer report validation.

Reproduce them independently:

npm run benchmark
cargo bench --bench lifecycle -- 100000 5

See benchmark methodology and raw JavaScript samples, the raw Rust record, and the benchmark site. Results should be compared within a lane and protocol, not used as a cross-language contest.

Test and support evidence

| Lane | Current verified support | CI evidence | | --- | --- | --- | | JavaScript · Node | 45 shared-core cases; 41 tooling cases; packed npm install/import/CLI smoke | Node 22.12 and Node 24 jobs | | JavaScript · browser | The same 45 shared-core cases in real Chrome; independent 100% native V8 gates | Chrome coverage job and live browser page | | Rust · native | 6 library tests + 3 browser-build CLI tests + 1 doctest; LLVM region/line/function coverage; formatting; warning denial; package verification | Rust 1.85 job and Rust coverage report | | Rust · browser | Visible browser/site-delivery checks plus one aggregate check that executes the same 6 Rust unit tests as a zero-import WASM harness in real Chrome | Rust browser artifact, on-page result list, DevTools output, and live browser example |

Quality gates Node core tests Chrome core tests Tooling tests Node core coverage Chrome core coverage

JavaScript coverage stays split by Node and Chrome. Rust coverage reports LLVM source regions, executable lines, and functions from the native unit-test run; browser WebAssembly remains a separate compatibility gate.

The tables are a readable snapshot. The linked CI run, generated status, coverage reports, and browser pages remain the source of truth for a specific commit.

Multi-language releases

One repository release represents the complete supported language set.

  • Major versions always align across packages.
  • Minor versions generally align and cannot move behind another language's release line.
  • Patch versions may be language-specific.
  • A GitHub release uses a bare numeric tag and title and attaches the exact current npm .tgz and Rust .crate.
  • A release is not published until every supported language artifact is available.
  • Adding a language means adding its README, documentation lane, CI/package gate, and release artifact to this same contract.

Example: GitHub release 2.1.3 may contain JavaScript/npm 2.1.3 and Rust/crates.io 2.1.0 because their shared 2.1 line is aligned.

Development

npm test
npm run coverage
cargo fmt --check
cargo test
cargo run --bin cargo-vanilla-test -- --browser
cargo package

Language-specific contracts live in JAVASCRIPT.md and RUST.md. Shared release history lives in CHANGELOG.md.

License

MIT. See licence.