1. Install
Use Node.js 22.12 or newer and native ES modules. Install the package in your project:
npm install vanilla-testA successful install exits with status 0. Add "type": "module" to package.json if the project does not already use ESM.
3. Run it in Node.js
A small adapter maps result.ok to the process exit status expected by shells and CI.
// test/node.js
import run from './shared-suite.js';
const result = await run();
process.exitCode = result.ok ? 0 : 1;node ./test/node.jsThe full report prints there. Exit status 0 means the suite passed; 1 means at least one test failed.
4. Run it in Chrome
vanilla-test works with bundlers and without a bundler. Bundlers resolve bare package imports normally. Native browser ESM needs the complete import map below and no build or transpilation step.
Every mapped path is relative to this HTML document. Serve it over HTTP(S), ensure the server exposes the mapped files, and do not open it through file://.
<!-- browser.html at the project root -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Browser tests</title>
<script type="importmap">
{
"imports": {
"vanilla-test": "./node_modules/vanilla-test/index.js",
"ansi-colors-es6": "./node_modules/ansi-colors-es6/index.js",
"strong-type": "./node_modules/strong-type/index.js"
},
"scopes": {
"./node_modules/vanilla-test/": {
"ansi-colors-es6": "./node_modules/ansi-colors-es6/index.js",
"strong-type": "./node_modules/strong-type/index.js"
}
}
}
</script>
</head>
<body>
<p data-status>Running…</p>
<script type="module">
import run from './test/shared-suite.js';
const result = await run();
document.querySelector('[data-status]').textContent =
result.ok ? 'Passed' : 'Failed';
</script>
</body>
</html>If npm nests a conflicting dependency, keep the ./node_modules/vanilla-test/ scope and point that dependency to ./node_modules/vanilla-test/node_modules/<dependency>/index.js. The canonical browser contract shows the complete nested-layout map.
npx serve .The terminal shows the local URL. Open the page there, then open DevTools to see vanilla-test progress, assertion errors, and the final report.
5. Add CLI coverage
Create vanilla-test.config.json at the project root. The entry is the shared module; each runtime gets its own include scope.
{
"entry": "./test/shared-suite.js",
"reportsDirectory": "./coverage",
"thresholds": {
"statements": 100,
"branches": 100,
"functions": 100,
"lines": 100
},
"timeoutMs": 30000,
"node": {
"include": ["src/**/*.js"]
},
"chrome": {
"include": ["src/**/*.js"],
"imports": {},
"scopes": {},
"headless": true,
"executablePath": null
}
}"executablePath": null enables portable Chrome discovery: vanilla-test checks CHROME_PATH, standard Chrome Stable locations, then executable names on PATH. Use a string only for a known custom installation.
npx vanilla-test coverage allNode and Chrome run independently and write separate reports below coverage/. Use the terminal exit status in CI.
Next steps
Understand every API contract
Review lifecycle guards, return values, immutable snapshots, completion events, and error behavior.
Open the API reference →Edit and run immediately
Try a suite safely in the browser and inspect its mirrored output.
Open the playground →