From mateonunez-skills
Sets up Node.js native node:test runner with borp reporter and c8 coverage for writing tests and measuring coverage, replacing Jest/Vitest.
How this skill is triggered — by the user, by Claude, or both
Slash command
/mateonunez-skills:node-native-testsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The Node.js runtime ships a test runner. I use it. No `jest`, no `vitest`, no `@types/jest`. The runner is `borp` (TAP reporter, parallel by default), coverage is `c8`.
The Node.js runtime ships a test runner. I use it. No jest, no vitest, no @types/jest. The runner is borp (TAP reporter, parallel by default), coverage is c8.
This is a single-tool-per-job choice: the standard library covers it, so no third-party test framework earns its place in package.json. The full ait testing setup — Docker test services, c8 invocation, package-mirroring test/ directory — is documented at personal/ait/references/best-practices-testing.md.
You are about to:
jest.mock, vi.mock, or @types/jest// package.json
{
"scripts": {
"test": "borp",
"test:coverage": "c8 borp -T --reporter spec"
},
"devDependencies": {
"borp": "^0.x",
"c8": "^10.x"
}
}
In monorepos with Docker-backed test infra (PostgreSQL, Qdrant, Redis), pre/post hooks bring services up and down:
{
"scripts": {
"test": "pnpm run:recursive test",
"pretest": "pnpm start:services:test",
"posttest": "pnpm stop:services:test"
}
}
// src/foo.spec.ts
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { foo } from './foo.ts';
describe('foo', () => {
it('returns ok for valid input', () => {
const r = foo('valid');
assert.equal(r.ok, true);
});
it('returns err with __type for invalid input', () => {
const r = foo('');
assert.equal(r.ok, false);
if (!r.ok) assert.equal(r.error.__type, 'empty-input');
});
});
File suffix is .spec.ts (or .spec.js). borp picks them up by default.
node:test ships mock from node:test:
import { describe, it, mock } from 'node:test';
const fn = mock.fn(() => 42);
fn();
assert.equal(fn.mock.callCount(), 1);
For module-level mocks, prefer dependency injection over runtime patching. If you really need module mocking, mock.module is in Node 22+.
@types/jest in devDependencies. That's the migration tell. Remove it.vi.mock, jest.mock, jest.fn() in new code. Use mock.fn from node:test.*.test.ts instead of *.spec.ts. Pick one. I use .spec.ts. Keep the codebase consistent.tsx or ts-node as a test dependency when node --experimental-strip-types (Node 22.6+) or native TS support (Node 23.6+) handles it../dist/. Test the source, not the build.Stop. Don't migrate unprompted. If there are 50 Jest tests, a silent rewrite is hostile. Note the existing setup, propose a migration as a separate task, and write new tests in the existing style for now. If I confirm the migration, do it in one commit with no other changes.
The exception: brand-new packages added to an existing monorepo can use node:test even if other packages use Jest. Each package owns its own test setup.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub mateonunez/skills