{"id":12904,"library":"brittle","title":"Brittle Test Runner","description":"Brittle is a lightweight, modern TAP (Test Anything Protocol) test runner for JavaScript, currently stable at version 3.19.1. It provides a clean API for writing both classic callback-based and modern async/await tests, supporting features like test plans, subtests, explicit exception/execution checks, and utilities for timeouts and teardowns. A key differentiator is its support for multiple JavaScript runtimes, including Node.js, Bare, and Pear, making it suitable for a wide range of environments. While a strict release cadence isn't published, it appears to be actively maintained with regular updates. Brittle aims to be a robust yet simple testing solution, focusing on developer experience and modern JavaScript paradigms without the overhead of larger test frameworks.","status":"active","version":"3.19.1","language":"javascript","source_language":"en","source_url":"https://github.com/holepunchto/brittle","tags":["javascript"],"install":[{"cmd":"npm install brittle","lang":"bash","label":"npm"},{"cmd":"yarn add brittle","lang":"bash","label":"yarn"},{"cmd":"pnpm add brittle","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Brittle v3+ is primarily an ESM package. Use `import` syntax. Default export is the `test` function.","wrong":"const test = require('brittle')","symbol":"test","correct":"import test from 'brittle'"},{"note":"The `test` function is also provided as a named export for explicit destructuring.","wrong":"import * as brittle from 'brittle'; brittle.test(...)","symbol":"test (named)","correct":"import { test } from 'brittle'"},{"note":"Other test modifiers and configuration utilities are available as named exports.","wrong":"import brittle from 'brittle'; brittle.solo(...)","symbol":"Utility functions","correct":"import { solo, skip, hook, todo, configure } from 'brittle'"}],"quickstart":{"code":"import test from 'brittle'\n\ntest('basic assertions and async behavior', async function (t) {\n  t.plan(4) // Expect 4 assertions\n\n  t.is(typeof Date.now(), 'number', 'Date.now() returns a number')\n  t.ok(Date.now() > 0, 'Timestamp is positive')\n\n  t.comment('Demonstrating async operations...')\n  await new Promise(resolve => setTimeout(resolve, 100))\n  t.pass('Async operation completed')\n\n  t.test('a subtest example', function (sub) {\n    sub.plan(1)\n    sub.alike({ a: 1 }, { a: 1 }, 'Objects should be deep equal in subtest')\n  })\n})\n\ntest('inverted test style with plan', async function (t) {\n  t.plan(1)\n  const result = await new Promise(r => setTimeout(() => r('done'), 50))\n  t.is(result, 'done', 'Inverted test can await its own completion')\n})\n","lang":"javascript","description":"Demonstrates basic synchronous and asynchronous tests, including assertions, plans, subtests, and the inverted test style."},"warnings":[{"fix":"Migrate your test files to use `import` statements (e.g., `import test from 'brittle'`). Ensure your `package.json` specifies `\"type\": \"module\"` or use a `.mjs` file extension for your test files.","message":"Brittle versions 3.0.0 and above are primarily designed as ES Modules (ESM). Direct `require()` statements for the main `brittle` package may lead to errors or unexpected behavior in Node.js environments unless specific CommonJS compatibility layers are used.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"For inverted tests, always define `t.plan(count)` at the beginning if you know the number of assertions, or explicitly call `t.end()` at the end of the test function if the number of assertions is dynamic or unknown.","message":"Inverted tests (where `test()` returns an `assert` object directly) require either `t.plan(n)` to be called with the expected number of assertions, or `t.end()` must be explicitly called to signal test completion. Failure to do so will result in the test hanging or potentially not completing correctly, especially if awaited.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always `await` promises returned by asynchronous functions within your tests. For inverted tests, `await t` will only resolve once `t.plan` is fulfilled or `t.end()` is called, ensuring that the main test runner waits for the inverted test's completion.","message":"When using `await test(...)` or `await t` for inverted tests, ensure all asynchronous operations within the test are properly awaited or chained. If a test completes before its async operations finish, assertions made later might not be reported or could cause test failures due to unhandled promises.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Update your module syntax to use `import test from 'brittle'` and ensure your Node.js environment is configured for ESM (e.g., `\"type\": \"module\"` in `package.json` or `.mjs` file extension).","cause":"Attempting to use `require('brittle')` in a CommonJS module when Brittle v3+ is primarily an ES Module.","error":"TypeError: Cannot assign to read only property 'exports' of object '#<Object>'"},{"fix":"Ensure `import test from 'brittle'` or `import { test } from 'brittle'` is present at the top of your test file.","cause":"Incorrect import statement or missing `import` declaration for the `test` function in an ESM context.","error":"ReferenceError: test is not defined"},{"fix":"For inverted tests, add `t.plan(N)` to declare the expected number of assertions, or call `t.end()` when the test has completed its work.","cause":"An inverted test was created and awaited, but no `t.plan()` was set, or `t.end()` was not called.","error":"Test finished without asserting anything"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}