oxmutate

Configuration

Every key oxmutate reads: Stryker's keys, read from stryker.config.* as they stand, the keys only oxmutate reads, and the Stryker keys it does not use, each with the reason.

oxmutate reads two files from the project root, and a command-line flag beats both:

  1. stryker.config.{mjs,js,cjs,json,mts,ts}, as it stands. A JS config may export an object or a function that returns one.
  2. oxmutate.config.* (the same extensions), which wins where both set a key. --config <file> names a different file.

The keys only oxmutate reads belong in oxmutate.config.*. Stryker never opens that file, so a project can run both tools while it compares them.

Stryker's keys oxmutate uses

KeyDefaultWhat it does
mutatesrc/**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs}, minus *.test.*, *.spec.* and *.d.tsThe files to mutate, as globs; a ! glob excludes
testRunnerVitest'command' runs commandRunner.command once per mutant instead of the warm Vitest runner
commandRunner{ command: 'npm test' }The command for testRunner: 'command'; any non-zero exit kills the mutant
vitest—{ configFile }: the Vitest config to run, when it is not the default one
concurrencycores − 1, at most 8Worker processes (--concurrency)
timeoutMS500Absolute slack per mutant, in ms; Stryker's default is 5000 (--mutant-timeout)
timeoutFactor1.5The multiple of a test's dry-run time a mutant may take before the slack
thresholds{ high: 80, low: 60, break: null }Score bands for the report; below break the run exits 1 (--break)
mutator—{ excludedMutations }: mutator names never generated
ignoreStaticfalseSkip static mutants (code that runs at import) instead of scoring them
reporters['clear-text', 'json']Any of clear-text, json, html, sarif (--reporter)
jsonReporterreports/mutation/mutation.json{ fileName } of the JSON report
htmlReporterreports/mutation/mutation.html{ fileName } of the HTML report
incrementalfalseReuse verdicts whose source and covering tests did not change (--incremental)
incrementalFilereports/oxmutate-incremental.jsonWhere those verdicts are kept
dryRunOnlyfalseStop after the dry run: proves the suite runs under oxmutate
dryRunTimeoutMinutes5Budget for the dry run; over it the run stops with exit 3
buildCommand—Run once before the dry run, split on spaces, with no shell
testRunnerNodeArgs[]Node flags for every Vitest worker
allowEmptyfalseA dry run that finds no tests scores nothing instead of failing
warningstruefalse (or { unknownOptions: false }) hides the line that lists unused keys
checkers[]['typescript'] type-checks each survivor; one that does not compile is not counted
tsconfigFiletsconfig.jsonThe tsconfig that type check uses

// Stryker disable next-line <Mutator>[,<Mutator>]: <reason> comments are honoured, and // oxmutate disable next-line … is the same directive. A directive with no reason is an error, because a mutant switched off without one cannot be reviewed.

Keys only oxmutate reads

KeyDefaultWhat it does
ignore[]Calls whose subtrees are not mutated, as data: { call: 'console.*', reason: '…' }. * stops at a dot, ** does not
specOracles[]Formal models whose traces are replayed against each mutant (Spec oracles)
strykerCompatfalseReproduce Stryker 10.0.0's skips: no mutants inside as casts or enums (--stryker-compat)
flakyReruns2Re-runs for a verdict whose covering tests behaved differently across two dry runs; 0 disables
sarifReportreports/mutation/mutation.sarifWhere the SARIF report goes
typeCheckerthe project's tsgo, else npx tscThe compiler command the type check runs

--report-dir <dir> writes mutation.json, mutation.sarif and mutation.html into one directory, whatever the config says.

Stryker's keys oxmutate does not use

Each is listed in the run's output with its reason, so a config written for Stryker is never misread in silence.

KeyWhy
inPlace, tempDirName, cleanTempDir, symlinkNodeModules, ignorePatternsoxmutate never copies or rewrites the project; instrumented sources are served from memory
plugins, appendPlugins, ignorersNo runtime plugin loading: mutators and ignore rules are data (ignore)
coverageAnalysisAlways perTest
disableBailoxmutate always stops a mutant at its first killing test
maxTestRunnerReuseWorkers are replaced on pollution and runaways, automatically
testFilesTest files come from the Vitest config
packageManageroxmutate never installs anything
disableTypeChecksAlways on: instrumented files carry // @ts-nocheck, and the checker reads the original sources
allowConsoleColorsColour follows the terminal
clearTextReporterThe summary is always printed
forceUse a run without --incremental
dashboardThe Stryker Dashboard reporter is not built yet
eventReporter, logLevel, fileLogLevel, checkerNodeArgsNot implemented

On this page