Auditable performance evidence

One lifecycle boundary across three languages.

JavaScript, Rust, and C# each run the same one-million-case lifecycle shape natively and in browser WebAssembly where applicable. All six rows share one initialized-runtime timing contract and publish raw samples from one machine and source commit. The separate JavaScript framework tables retain their own cold-pipeline protocol.

Equivalent JavaScript, Rust, and C# timing

Six runtimes, one measured boundary

One warmup + five measured pipelines

Every row initializes its host and language runtime first, discards one warmup, then times five fresh executions of the same 1,000,000-case, 1,000-suite lifecycle pipeline. The resolved runner-entry invocation, case naming, arithmetic, the wrapping checksum, lifecycle calls, report materialization, per-suite checks, final validation, and runtime-managed work triggered during the call are inside every timer. Startup, module loading, initial module compilation or instantiation, coverage, memory probes, report encoding and file output, and teardown are outside every timer.

Loading equivalent language benchmark data…

Equivalent language benchmark results; lower time is better
Language / runtimeFive raw samplesMedianThroughput
Loading six equivalent runtime lanes…
The boundary is now directly comparable.

Runtime implementation, clock, garbage collection, and host architecture still differ naturally; the work included by the timer no longer does.

JavaScript record · Rust record · C# record

Separate JavaScript framework protocol

Cold-pipeline run and machine

Loading signed-off benchmark data…

This machine card and the scaling/framework sections below come from the separate JavaScript datasets, not the six-row initialized-runtime record above.

Algorithm boundary

Core lifecycle scaling

Loading signed-off scaling data…

Each point puts 250 through 16,000 uniquely named passing cases in one runner. Imports and report() are outside the timer; construction plus expects(), pass(), and done() are inside it. The exact 2.1.1 index.js is reconstructed from Git and uses the same installed dependencies as the candidate.

Line chart of median lifecycle microseconds per case from 250 through 16,000 cases in one runner. Version 2.1.1 rises with suite size while version 2.1.2 stays nearly flat; lower is better.
Median lifecycle cost per case with observed ranges from five fresh-process samples. The vertical scale is logarithmic. Download the raw scaling JSON.
Core lifecycle scaling; lower time is better
Cases in one runner2.1.1 median2.1.2 median2.1.1 per case2.1.2 per caseFaster
Loading core-scaling samples…

Waiting for scaling provenance…

Run the equivalent browser lane here

JavaScript browser benchmark

Page and modules initialize before timing

This page loads the JavaScript runner first, discards one warmup, then times five fresh calls to the shared lifecycle pipeline with performance.now(). It uses the same contract as all six published rows.

Ready to run in this browser.

Live result from this browser; no result is written back to published provenance
Raw samplesMedianThroughput
———

Complete host pipelines

One-million-case overview

Independent zero-based axes

Bar charts of one-million-case cold-wall medians. Node compares vanilla-test, Mocha, and node:test; Chrome separately compares vanilla-test and Mocha. Each host uses an independent axis and lower is better.
Cold startup, runner lifecycle, native V8 coverage, validation, four report files, and teardown. Compare runners only within the same host panel. Download the raw pipeline JSON.

Native Node only

Node pipeline

Fresh worker + test child per sample

One-million-case Node results; lower time is better within this lane only
RunnerCold wallFull pipelineRunner phaseCold throughputPeak sampled
Loading Node samples…

Real browser only

Google Chrome pipeline

Fresh isolated Chrome profile per sample

vanilla-test works with bundlers and without a bundler. This benchmark exercises the native no-bundler ESM path through an explicit document-relative import map; package imports and startup remain outside the measured lifecycle.

One-million-case Chrome results; lower time is better within this lane only
RunnerCold wallFull pipelineRunner phaseCold throughputPeak sampled
Loading browser samples…

Node peak is sampled process RSS; Chrome peak is sampled renderer JavaScript heap. Treat them as host-specific context, not a cross-runtime memory ranking.

Keep this cold-pipeline table host-local.

Its Node and Chrome rows include different startup and host costs, so compare frameworks only within the same host panel. The six-language table above uses the separate aligned boundary.

What “end to end” means here

  1. Cold host.Start a fresh Node worker and test child, or a fresh isolated Google Chrome process.
  2. Real runner cases.Define and complete 1,000,000 uniquely named cases in 1,000 bounded suites. No raw loop is ranked as a competitor.
  3. Detailed result work.Materialize each framework's detailed passing report into a silent sink, so terminal spam is removed without deleting report cost.
  4. Native coverage.Collect untransformed V8 ranges from the identical shared workload in the selected host.
  5. Four files and teardown.Write test JSON, coverage JSON, LCOV, and standalone HTML; validate hashes and exact counts; then close the host.

Because coverage is enabled intentionally, these are complete pipeline measurements—not claims about isolated assertion nanoseconds. The same project-owned native V8 collector and deterministic HTML/LCOV/JSON reporter wrap every entrant, holding those phases constant while the runner changes. Runner, pipeline, and cold-wall boundaries remain separate in every raw sample.

Why these competitors qualify

Node · richer native runner

node:test

Built into the exact recorded Node runtime, with suites, hooks, mocks, snapshots, reruns, reporters, and coverage.

Official capability reference
Node + browser · richer runner

Mocha

Pinned in the benchmark lockfile, with suites, hooks, async support, filtering, retries, ESM, browser execution, and reporters.

Official browser reference

Lightweight loops and less capable micro-runners are excluded from the visible ranking. This prevents a flattering but mismatched comparison.

Inspect the exact benchmark code

The implementation stays available without filling the results page with source. Open any file in a focused native dialog, copy it, or follow its commit-pinned repository link.

Exact benchmark source

Source

Open pinned source
Choose a source file to load it here.