uvu

An extremely fast, lightweight test runner for Node.js and the browser, with optional browser-safe assertions.

Library
npm
v0.5.6
3,030stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
45/100Fair
Development Activity0
Maintenance32
Community48
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
71/100Good
Architecture78
Code Quality62
Innovation68
Learning Curve75

uvu is a test runner built around a simple idea: instead of a central process that imports and orchestrates every test file, each file registers its own suites and defers execution until the whole file has finished loading. That lets any individual test file run standalone with node file.js, without a CLI wrapper, while a bundled uvu CLI (built on sade) still handles directory-wide discovery, bail-on-failure, and preload options for CI use.

The package ships as several independent, deep-importable subpaths: the core uvu module for suite/test, an optional uvu/assert module with a tape-like assertion API (is, equal, type, instance, match, snapshot, fixture, throws) built only on dequal, and a uvu/diff module that renders colorized line- and character-level diffs on failed assertions via kleur and the diff package. Because the assertion and diff modules have no Node-specific dependencies, they work unmodified in the browser.

With only four runtime dependencies and no central test-collection step, uvu trades some of the ergonomics of describe/it-nested frameworks for near-zero startup overhead — its own README benchmarks put a full suite run at a fraction of the time of heavier runners like Jest or Mocha.

What You Get

  • The uvu module exporting suite() and a default test function for registering and running tests
  • The optional uvu/assert module — a browser-compatible assertion library with is, equal, type, instance, match, snapshot, and fixture
  • The uvu/diff module for colorized, line-level diff output on assertion failures
  • A bundled uvu CLI (via sade) for directory-wide test discovery with bail, ignore, and require/preload flags
  • Dual CJS/ESM builds with a package.json exports map exposing ., ./assert, ./diff, ./parse, and ./run as separate importable subpaths

Common Use Cases

  • Running large Node.js unit test suites in CI where per-process startup overhead compounds across thousands of files
  • Executing a single test file directly with node file.js during local debugging, without invoking a CLI runner
  • Testing isomorphic/browser-targeted code with uvu/assert, which has no Node-only dependencies
  • Snapshot- and fixture-based regression testing via assert.snapshot/assert.fixture with diff output on mismatch

Under The Hood

Architecture Execution starts at bin.js, a sade-based CLI entry that parses dir/pattern arguments, delegates to parse/ to discover matching test files, and either dynamically import()s or require()s them depending on ESM support before handing the resulting suites to run/ for execution. The core src/index.js exports suite()/test, which build a context of tests, before/after hooks, and state; when a suite’s run() is invoked, it pushes onto a shared globalThis.UVU_QUEUE array and — outside the CLI — defers actual execution via setTimeout so the rest of the file finishes registering tests before any hook runs. This shared-queue convention is what lets a single test file execute standalone with plain node, without needing the CLI’s discovery/orchestration path. Module boundaries are shallow and cleanly separated: index.js (suite authoring plus the inline runner), assert.js (assertions, dependency-free aside from dequal), diff.js (diff rendering), and the CLI-only parse//run/ directories, which is why uvu/assert and uvu/diff can be deep-imported into browser bundles without pulling in any Node-only code.

Tech Stack The package declares only four runtime dependencies — dequal for deep equality, diff for text diffing, kleur for terminal colors, and sade for CLI argument parsing — with no framework or bundler dependency at runtime. bundt (a devDependency) builds dual CJS (dist/index.js) and ESM (dist/index.mjs) outputs from the plain-JavaScript src/ sources, exposed through a package.json exports map covering the root, assert, diff, parse, and run subpaths. TypeScript typings are hand-authored .d.ts files placed alongside each source file rather than generated by a compiler. The CLI itself (bin.js) is a small Node shebang script wired to sade.

Code Quality Tests live under test/ (assert.js, diff.js, exit.fails.js, index.js, parse.js, suite.js, uvu.js) and are run with node test, dogfooding uvu’s own API to validate itself — a reasonably direct behavioral check given the subject under test is the runner itself. There is no TypeScript source; the .d.ts declarations are maintained by hand and can drift from the implementation without a compiler enforcing them. runner() in src/index.js explicitly catches per-test errors and continues rather than aborting the suite, with a dedicated format()/stack() pair that strips internal Node frames from failure output. No linter or formatter configuration is present at the repo root. A GitHub Actions CI workflow runs the test suite on push.

What Makes It Unique uvu’s core differentiator is architectural rather than feature-based: rather than a central process importing and orchestrating every test file (the Jest/Mocha model), each file is independently executable, deferring its own test execution with a timeout-based trick so all tests in a file register before the first one runs — no async describe/it nesting machinery required. This buys substantially lower per-run overhead and true per-file isolation without worker processes, at the cost of some of the ergonomics that a fully framework-managed lifecycle provides. The assertion API itself is conventional and tape-like rather than novel.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search