Skip to main content
meow has a test runner built in. Each test file runs in its own deterministic V8 isolate, so suites can’t leak state into each other and every run is reproducible by construction.
meow test

Writing tests

Import the API from the meow:test built-in module. There’s nothing to install.
math.test.ts
import { test, expect } from "meow:test";

test("adds", () => {
  expect(2 + 2).toBe(4);
});

test("builds the right shape", () => {
  expect({ ok: true }).toEqual({ ok: true });
});

test("throws on bad input", () => {
  expect(() => JSON.parse("{")).toThrow();
});

Discovery

meow test walks the project and runs every file whose name ends in .test. or .spec. with a JS/TS extension (.ts, .tsx, .js, .jsx, .mts, .mjs, .cts, .cjs). It skips node_modules, target, vendor, and hidden directories.

Matchers

The expect() API covers the essentials, each with a .not inverse:
MatcherPasses when
toBe(v)Object.is(actual, v) (identity / primitive equality)
toEqual(v)deep structural equality
toBeNull()value is null
toBeDefined()value is not undefined
toBeTruthy() / toBeFalsy()truthiness
toThrow()calling the function throws
.notinverts any of the above
expect(user.name).not.toBe("");

Output

math.test.ts
  ✓ adds
  ✓ builds the right shape
  ✓ throws on bad input
╭─ meow test ─────────────────────────────────╮
│ 🐾 3 passed · 1 file                          │
╰──────────────────────────────────────────────╯
A failure shows the assertion and the first stack line, and the runner exits non-zero:
sum.test.ts
  ✗ adds
    expect(5).toBe(4)
╭─ meow test ─────────────────────────────────╮
│ ✗ 0 passed, 1 failed · 1 file                 │
╰──────────────────────────────────────────────╯

Determinism is the default

Tests always run in a deterministic strict-web isolate, no matter your project mode. The clock is frozen, randomness is seeded, and the timezone is pinned — so time- and random-dependent tests are stable instead of flaky. If a test genuinely needs real time or host access, that’s a deliberate grant, not the default.
Because each file gets a fresh isolate, there’s no shared global state to reset between files and no cross-test contamination.

The meow:test API

Full type signatures for test() and expect().