Skip to main content

stryker-js

Introduce StrykerJS mutation testing or assess JavaScript/TypeScript test quality. Use Git diff mutations in CI and surviving mutants locally to find missing cases and weak assertions, including tests generated by AI.

Source facts

Repository
mizchi/skills
Last source activity
October 2, 2026 at 07:16
Detected SKILL.md language
English
Stars
356
Forks
5

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
16 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
stryker-js
description
Introduce StrykerJS mutation testing or assess JavaScript/TypeScript test quality. Use Git diff mutations in CI and surviving mutants locally to find missing cases and weak assertions, including tests generated by AI.
# StrykerJS: measure test quality Use mutation testing to ask whether tests detect plausible defects in production code. A passing suite or high coverage alone does not answer that question. Mutate production source; improve the tests that fail to detect meaningful mutations. ## Choose the work - **Introduce Stryker:** read [setup.md](references/setup.md), adapt the assets, and verify the integration with a small real module before widening the scope. - **Review or improve tests locally:** read [evaluate-tests.md](references/evaluate-tests.md). Run mutations, inspect the surviving changes and covering tests, then improve the missing inputs or assertions. - **Add CI:** copy [mutation-diff.yml](assets/mutation-diff.yml) to `.github/workflows/mutation-diff.yml`, along with the selector scripts and package commands. CI must pass `--diff-only`. Retain the project's runner, configuration, workspace layout and package manager. The supplied integration targets pnpm, Node.js 24+ and Vitest; use the appropriate Stryker runner for Jest/Mocha rather than migrating tests just to use these snippets. Match `@stryker-mutator/core` and runner versions and check their actual peer dependencies. ## CI and local scope | Context | Command | Meaning | | ------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | | PR CI | `pnpm test:mutation:changed --base "$MUTATION_BASE" --diff-only` | Mutate changed production source relative to the merge-base; never expand to all source for test/config changes. | | Preview locally | `pnpm test:mutation:changed --base origin/main --diff-only --list` | Read-only selection, including local edits and untracked source. | | Local uncommitted work | `pnpm test:mutation:changed` | HEAD versus worktree; test/config/dependency changes widen to all configured source. | | Review one module's tests | `pnpm test:mutation --mutate 'src/fee.ts'` | Evaluate the full module, even if only tests changed. | | Review the suite | `pnpm test:mutation` | All configured production source; use when a full baseline is warranted. | | AI-readable result | `pnpm test:mutation:summary reports/mutation/changed.json` | Counts and concrete unresolved mutations with source locations and covering tests. | For new or renamed files and hunks that reduce the line count, the selector conservatively inspects the whole **changed file**. Deleted files have no current code to mutate. Pure test/config/doc changes in CI produce `scope: none`: **skipped, unmeasured**. They do not establish test quality. Evaluate affected modules locally after changing tests or shared test helpers. Run commands from the repository root. The supplied selector reads explicit positive/negative glob patterns from `stryker.config.json`; adapt includes/excludes to monorepos and exclude tests, declarations and generated code. It passes literal paths and ranges through Stryker's programmatic API, so commas in filenames are not split by a CLI parser. Missing history, invalid refs and unresolved conflicts fail instead of appearing as an empty diff. Keep Git diff selection separate from Stryker's `--incremental` cache. The CI selector disables incremental reuse. During local test improvement, rerun the affected module with fresh results; if using incremental mode, use `--force` when validating changed assertions. ## Local AI feedback loop 1. Establish that the original tests pass. Select the behavioral module under review and run Stryker with HTML and JSON output. Record the source revision/worktree, scope, versions and any exclusions. 2. Read the report, source, relevant tests and specification. For each meaningful `Survived` or `NoCoverage` result, identify the smallest legal input and observable difference between original and mutant. 3. Add a focused regression or a property using an independent oracle. The original must pass; the relevant mutant must fail. Improve assertions or input generation before changing production behavior. Use TDD for genuine production defects. 4. Rerun the module and summarize the result. If a supplied score target is unmet, continue fixing demonstrated gaps until it is met or a concrete blocker requires clarification. Do not invent a score target. See [evaluate-tests.md](references/evaluate-tests.md) for classification, property-based testing, and the evidence to report. Neither a mutation score of 100% nor a diff-only result proves the absence of bugs. ## Interpretation Stryker's score is `(Killed + Timeout) / (Killed + Timeout + Survived + NoCoverage) * 100`. Report timeouts separately; they can arise from an infinite-loop mutation or infrastructure problems. Compile/runtime errors, ignored mutants and pending mutants are also visible evidence, not successful assertion checks. The summary emits `null` when there are no valid mutants and marks pending results incomplete. The config snippet starts with `thresholds.break: 0` for measurement. CI records results but does not fail solely for survivors at this setting. If the project specifies a gate, set the agreed threshold and validate failure propagation; apply it to the selected diff scope. Keep ordinary tests/type checks in the project's existing CI. ## Assets | Asset | Destination / use | | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | | [stryker.config.json](assets/stryker.config.json) | Root config; adapt `mutate` and `vitest.configFile`. | | [package.scripts.json](assets/package.scripts.json) | Merge commands into existing `package.json`; preserve unrelated fields. | | [justfile](assets/justfile) | Append/adapt recipes in the project's justfile. | | [gitignore.snippet](assets/gitignore.snippet) | Append report/cache/temp paths to `.gitignore`. | | [mutation-plan.mjs](assets/scripts/mutation-plan.mjs) | `scripts/mutation-plan.mjs`: pure selection and read-only Git inspection. | | [mutation-changed.mjs](assets/scripts/mutation-changed.mjs) | `scripts/mutation-changed.mjs`: preview/run, fresh plan/report handling. | | [mutation-summary.mjs](assets/scripts/mutation-summary.mjs) | `scripts/mutation-summary.mjs`: JSON evidence for AI review. | | [mutation-diff.yml](assets/mutation-diff.yml) | `.github/workflows/mutation-diff.yml`: PR/manual diff-only CI. | | [shipping.ts](assets/examples/shipping.ts), [shipping.test.ts](assets/examples/shipping.test.ts) | Optional isolated setup/PBT smoke example; adapt the specified domain rather than copying assertions into unrelated tests. | | [Vitest 5 patch](assets/patches/vitest-runner-10-vitest-5.patch) | Version-specific fallback; read setup notes before using. | The helper tests live in [tests/mutation.test.mjs](tests/mutation.test.mjs). In `mizchi/skills`, run `just --justfile stryker.justfile test-stryker` to validate them without installing Stryker. ## Sources - [StrykerJS configuration](https://stryker-mutator.io/docs/stryker-js/configuration/): source patterns, ranges, reporters and thresholds. - [Vitest runner](https://stryker-mutator.io/docs/stryker-js/vitest-runner/): peer requirements, configuration and related tests. - [Mutant states and metrics](https://stryker-mutator.io/docs/mutation-testing-elements/mutant-states-and-metrics/): scoring and outcome semantics. - [Incremental mode](https://stryker-mutator.io/docs/stryker-js/incremental/): reuse and forced reruns. - [Working template](https://github.com/mizchi/nodeproj20261002): Vite Plus, fast-check, shrinking and Uneffect experiments; formal verification is separate from mutation testing.
View on GitHub