Everything the built-in node:test reporters don't do: live interactive trees,
browser-viewable runs you can share by link, GitHub Actions annotations, an
interactive watch REPL, bail-on-failure, the whole mocha reporter ecosystem —
and a multiplexer that picks the right ones per environment, so one
--test-reporter flag covers your laptop and your CI.
That report at link is @reporters/web's run being delivered
— it opens as an interactive tree in the browser
(live demo):
Register @reporters/mux once and let a config decide per
environment: a live interactive tree while developing, a GitHub-annotated log
plus a shareable browser report in CI.
npm i -D @reporters/mux @reporters/live @reporters/gh @reporters/web @reporters/sink// mux.config.mjs
import { httpServer } from '@reporters/web/sink';
import { gist } from '@reporters/sink';
export default {
local: [
{ reporter: '@reporters/live', sink: 'stdout' }, // live tree, browse failures interactively
{ reporter: '@reporters/web', sink: httpServer() }, // same run in the browser, on localhost
],
ci: [
{ reporter: '@reporters/gh', sink: 'stdout' }, // readable log + PR annotations + job summary
{ reporter: '@reporters/web', sink: gist() }, // uploads the run, links the hosted viewer
],
};// package.json
{ "scripts": { "test": "node --test-reporter=@reporters/mux --test" } }That's it — npm test everywhere. mux detects CI, picks the profile, and in
GitHub Actions adds a View report link to the job summary (the gist()
sink needs a token — two-line setup).
Not ready for a config file? Every reporter also works standalone with plain
--test-reporter flags — start with one from the table below.
| Package | What it does |
|---|---|
| live (npm) | Live, React-powered tree in the terminal — tests flip ✓/✗ as they finish, failures expand interactively |
| web (npm) | The run in the browser — interactive tree with search, diffs, and a hosted viewer for shared links |
| testwatch (npm) | Jest-style interactive watch REPL — rerun and filter by file/test from the keyboard |
| Package | What it does |
|---|---|
| gh (npm) | All-in-one GitHub Actions reporter: readable log + inline PR annotations + job summary |
| github (npm) | Annotations + job summary only — layer it on top of the reporter you already use |
| junit (npm) | JUnit XML for Jenkins, GitLab, CircleCI, Buildkite, Azure, … |
| Package | What it does |
|---|---|
| bail (npm) | Abort the whole run on the first failure — the missing --bail |
| slow (npm) | List the tests over 250ms, color-coded, slowest first |
| silent (npm) | No output at all — just the exit code |
| mocha (npm) | Run any mocha reporter (nyan! mochawesome!) on node:test |
| Package | What it does |
|---|---|
| mux (npm) | Environment-aware routing: tee the run to multiple reporters, each into its own sink, per profile |
| sink (npm) | Delivery sinks for mux: upload the run to a gist or S3 so the hosted viewer can render it |
(live and web share one tree model, tree-core
(npm) — useful if you're
building a tree-shaped reporter of your own.)
- "I just want nicer local output" → live
- "I want a TDD loop" → testwatch, and bail for fail-fast
- "I want PR annotations" → gh (or github — see below)
- "My CI wants JUnit XML" → junit
- "I want to share a run with a teammate" → web + sink
- "My suite is slow and I don't know why" → slow
- "I miss my mocha reporter" → mocha
- "Several of the above, depending where it runs" → mux — that's the TL;DR setup
Reporters compose without mux too — node:test accepts the flag repeatedly:
node \
--test-reporter=@reporters/github --test-reporter-destination=stdout \
--test-reporter=@reporters/junit --test-reporter-destination=junit.xml \
--test-reporter=spec --test-reporter-destination=stdout \
--testBoth @reporters/gh and @reporters/github add GitHub Actions annotations (inline errors + diagnostics) and a job summary. The difference is whether they also produce the human-readable test log:
@reporters/gh |
@reporters/github |
|
|---|---|---|
| Human-readable log | ✅ built in (spec-style, collapsible per-test groups) | ❌ none — pair with another reporter |
| Annotations + job summary | ✅ | ✅ |
| Reporters needed | one | two (it + e.g. spec) |
| Output outside GitHub Actions | spec-style log | nothing (no-op) |
| Best when | you want a single reporter that does everything | you already have a reporter you like and just want to add annotations |
In short: reach for gh for the batteries-included experience, or github to layer annotations onto your own choice of reporter.
# gh — one reporter: readable log + annotations + summary
node --test-reporter=@reporters/gh --test
# github — annotations + summary, paired with spec for the readable log
node \
--test-reporter=@reporters/github --test-reporter-destination=stdout \
--test-reporter=spec --test-reporter-destination=stdout \
--test
