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

@small-web/test-monkey

v1.1.1

Published

A node:test custom reporter that’s also a monkey.

Downloads

358

Readme

Test Monkey

🍌️🐒️

Recording of the Test Monkey tests running in terminal. Shows the see-no-evil, hear-no-evil, speak-no-evil monkey animation with test names and other statistics animating in the status line followed by the test run summary showing 191 passing tests out of 191 total tests run in a little over 3 seconds.

A node:test custom reporter that’s also a monkey.

Displays test runner status using a static single-line spinner (hint: it’s a monkey) and only fills your screen with text on failures and with your coverage report.

No dependencies.

Test Monkey is the successor to Tap Monkey, which is a TAP formatter. If you need to consume TAP, use Tap Monkey. If you want the best possible experience with node:test, use Test Monkey.

Did your tests pass? Excellent! Here, have a banana :) 🍌

System requirements

Node.js version 24.19.0+

Install

npm i --save-dev @small-web/test-monkey

Use

Point --test-reporter at Test Monkey:

node --test --test-reporter=@small-web/test-monkey 'tests/*.js'

Or, as a test task in your package.json file:

"scripts": {
  "test": "node --test --test-reporter=@small-web/test-monkey 'tests/*.js'"
}

💡 Test Monkey is designed for interactive use and does not support --test-reporter-destination.

Options

Test Monkey is a reporter module, not a command, but it still has options you can set using environment variables.

| Variable | Description | | --------------------------- | --------------------------------------------------------------------------------------| | TEST_MONKEY_QUIET | Don’t animate the progress line. Failures, coverage, and the summary are still shown. | | TEST_MONKEY_DEBUG | Show everything the tests print, including console output from your app. | | TEST_MONKEY_BAIL_ON_FAIL | Stop reporting at the first failure. | | TEST_MONKEY_STALL_SECONDS | How long a test idle before Test Monkey warns of a possible hang. Default: 3. | | TEST_MONKEY_NO_CAPTURE | Everything your tests print go directly to the terminal. |

Accessibility

For a quieter monkey, turn TEST_MONKEY_QUIET on:

"scripts": {
  "test": "TEST_MONKEY_QUIET=1 node --test --test-reporter=@small-web/test-monkey 'tests/*.js'"
}

In quiet mode, nothing is written to the progress line (no animation, no running test names, etc.) Failures, the coverage report and the final summary are still shown in full.

This is a general accessibility and usability feature. It might help folks using assistive devices like screen readers who might otherwise get overwhelmed by notifications of running and passing tests, as well as anyone else who wants a generally calmer monkey.

💡 The monkey also stays still when it isn’t being watched. If stderr is not a terminal (TTY) – e.g., when it’s a pipe, a redirect, and/or in most continuous integration (CI) systems – the progress line is switched off. (This is to stop animation frames ending up in your log files, etc.)

The progress line

 🙉 3 files · 47 tests · 12s · Now running: a monkey test

The progress line has an animated monkey (because, of course) as well as useful statistics about the current run: the number of files in flight, the number of tests completed so far, how long the run has been going, and the name of the currently running test.

Test failures

Recording of a Test Monkey test failure in terminal. The full failure is shown, including a stack trace. The rest of the tests continue and a summary is printed at the end, showing that one test failed.

Failures are always written to the terminal in full. Here’s a list of the failure types Test Monkey handles and the information it renders for each:

  • Error thrown inside a test – flagged as an error in the test itself rather than an assertion failure, followed by its stack trace.

  • Assertion failure – the operator, and the expected and actual values, followed by the stack trace with the frame that points at your code highlighted.

  • Error thrown in a hook – flagged as an error in the setup or teardown around the test, stating which of the four possible hooks it was in. An assertion that fails inside a hook keeps its expected/actual block.

  • Plan failure – how many assertions (t.plan()) were expected and how many ran.

  • Timed-out or cancelled/aborted test – shown as ✖ CANCELLED.

  • Test that never starts – this occurs when a subtest registers after its parent has already finished and usually points to a missing await. The displayed stack is for the call that arrived late.

  • A parent with failing subtest – one line comment pointing out the child’s failure (harsh).

  • File that couldn’t be run – the child’s exit code and signal, plus the file’s output prior to failing (this is where you’ll find the SyntaxError that caused the failure).

All failures print a tail of any output received prior to the failure to provide context that could help in debugging the issue.

Stall detection

Recording of Test Monkey warning about a possible stall and being interrupted with ctrl+c.

Test Monkey makes a basic attempt to warn you about a possible hanging test run.

This is a best guess based on a wall clock heuristic (default: 3 seconds of event silence from node:test).

If you have very slow unit – or, more likely, integration – tests, you can increase this duration by setting the TEST_MONKEY_STALL_SECONDS environment variable.

Code coverage

Recording of the Test Monkey tests coverage running in terminal.

Use Test Monkey for coverage in exactly the same way as you do for your tests:

"scripts": {
  "coverage": "node --test --experimental-test-coverage --test-reporter=@small-web/test-monkey 'tests/*.js'"
}

Paths are relative to the working directory, and files that miss a --test-coverage-lines (or branches, or functions) threshold are shown in red.

If a threshold is missed, the summary also contains a “Coverage is below the threshold.” message (and you don’t get a banana, sorry).

Note that when thresholds are missed, node:test fails the run.

🍌 Test Monkey itself has 100% test coverage. (Anything less would be embarrassing.)

🪤 Using npm link? Test Monkey’s own code is normally kept out of your coverage statistics as it lives in your project’s node_modules folder which Node excludes from coverage by default. However, when you use npm link @small-web/test-monkey to use a local development version of Test Monkey, it lives outside your project’s node_modules folder and so it is included in coverage. To exclude it, use --test-coverage-exclude='**/test-monkey/**'. Furthermore, any --test-coverage-exclude switches off node’s own default of leaving your test files out, so you will want --test-coverage-exclude='test/**' alongside it. (This note is really only relevant if you’re developing on Test Monkey and testing it.)

Debug output

The opposite of TEST_MONKEY_QUIET is TEST_MONKEY_DEBUG.

Everything your program prints – console.log(), console.error(), anything else on stdout or stderr – is shown as it happens, along with any diagnostics your tests emit using t.diagnostic(). These are normally hidden, under all isolation modes.

Node’s own end-of-run statistics (tests 12, pass 12, duration_ms …) are filtered out even in debug mode as Test Monkey already shows them in the summary.

Exit codes

Exit codes come from node:test, with one exception:

When the test runner cannot find any tests, Test Monkey forces an exit with error code 1, where node would have exited with 0 (success). Having no tests run usually means something went wrong.

Watch mode

Test Monkey works well with node:test’s watch mode (node --test --watch). Totals, timings, and buffered output are reset at the start of each run rather than accumulating over the session.

💡 Coverage is only reported on the first run of a watch session. A missing coverage table on a re-run is standard node:test behaviour; not a bug in Test Monkey.

Support for --test-isolation=none

Your test files run in the runner’s own process in this mode, which means their output normally goes directly to the terminal rather than being relayed to the reporter. To make this mode behave the same way as --test-isolation=process (the default), Test Monkey captures the streams (stdout and stderr) itself and carries out its own processing.

Two kinds of output still go directly to the terminal and we have no control over that:

  • A child process your tests spawn with inherited stdio writes to the terminal directly, without passing through JavaScript, so we can’t capture it.
  • Output from --test-global-setup . Node runs this before it loads Test Monkey.

Testing Test Monkey

Test Monkey’s own tests are, of course, displayed by none other than *drumroll* Test Monkey.

Run tests

npm run test

Run coverage

npm run coverage

When Test Monkey, a test reporter, is reporting on itself, its own bugs can appear like a broken test run.

If the output from Test Monkey’s own tests is suspect, use the npm run -s test:spec script which uses Node’s built-in spec reporter to diagnose it.

Recording the screencasts

To record/update all the screencasts in this README, run:

screencasts/record

To record/update a single screencast, pass the name of its tape file (sans file extension). e.g.,

screencasts/record passing

For more details, see the screencasts README.

Like this? Fund us!

Small Technology Foundation is a tiny, independent not-for-profit.

We exist in part thanks to patronage by people like you. If you share our vision and want to support our work, please become a patron or donate to us today and help us continue to exist.

Copyright

© 2026-present Aral Balkan, Small Technology Foundation.

License

AGPL version 3.0.