npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ts-mutate

v1.0.2

Published

Minimal TypeScript mutation-testing wrapper for Stryker

Readme

ts-mutate

ts-mutate is a minimal TypeScript mutation-testing wrapper around StrykerJS that adds a small API inspired by the practical targeting surface of slither-mutate:

  • class-based targeting
  • function and method selector targeting
  • mutator category selection
  • strict post-run verification that Stryker only mutated the requested scope

The wrapper resolves TypeScript symbols with ts-morph, generates a temporary Stryker config with narrow mutate ranges, runs Stryker's command runner, and optionally validates the JSON mutation report.

Status

MVP / experimental. The mutator registry is pinned to StrykerJS 9.6.1 and is intended for focused mutation runs, not as a replacement for Stryker's full CLI.

Requirements

  • Node.js 22 or newer
  • npm
  • A TypeScript project with a valid tsconfig.json
  • A test command that succeeds before mutation testing

Install from source

git clone https://github.com/stevennevins/ts-mutate.git
cd ts-mutate
npm ci --ignore-scripts
npm run build

Run the local CLI:

node dist/cli.js --help

Or link it locally:

npm link

Then use:

ts-mutate <project> [options]

CLI usage

ts-mutate <project> \
  --class-names <names> \
  --target-functions <selectors> \
  --mutators <categories> \
  --test-cmd <command> \
  --output-dir <path> \
  --strict

At least one of --class-names or --target-functions is required. --test-cmd is required unless you are only inspecting validation errors before Stryker runs.

Options

| Option | Required | Description | | --- | --- | --- | | <project> | yes | Project root to mutate. | | --class-names <names> | no | Comma-separated class names to target. | | --target-functions <selectors> | no | Comma-separated function/method selectors. | | --mutators <categories> | no | Comma-separated mutator categories. Defaults to all. | | --test-cmd <command> | yes | Command passed to Stryker's command runner. | | --config <path> | no | Base Stryker config to merge. | | --tsconfig <path> | no | TypeScript config. Defaults to <project>/tsconfig.json. | | --output-dir <path> | no | Output directory. Defaults to <project>/reports/mutation. | | --dry-run | no | Resolve targets and write config without running Stryker. | | --allow-multiple | no | Allow one selector to resolve to multiple symbols. | | --strict | no | Verify final mutants are in-scope and use allowed mutators. |

Examples

Target classes

ts-mutate . \
  --class-names AuthService,UserService \
  --test-cmd "npm test" \
  --strict

Target a method

ts-mutate . \
  --target-functions "AuthService.verifySignature" \
  --test-cmd "npm test" \
  --strict

Target by parameter signature

ts-mutate . \
  --target-functions "verifySignature(string,string),AuthService.canWithdraw(number)" \
  --test-cmd "npm test" \
  --strict

Restrict mutator categories

ts-mutate . \
  --target-functions "AuthService.verify" \
  --mutators conditionals,logical,boolean \
  --test-cmd "npm test" \
  --strict

Dry-run target resolution

ts-mutate . \
  --class-names AuthService \
  --test-cmd "npm test" \
  --dry-run

The command prints JSON including the generated Stryker config path and resolved source ranges.

Supported target selectors

| Selector form | Meaning | | --- | --- | | functionName | Top-level function declaration, function expression, or const arrow function. | | functionName(type,type) | Function with matching normalized parameter types. | | ClassName.methodName | Method inside a class. | | ClassName.methodName(type,type) | Class method with matching normalized parameter types. |

Class targeting is provided separately through --class-names.

Out of scope for the MVP: raw line ranges, namespace selectors, file.ts:functionName, decorator-specific selectors, and PR-diff targeting.

Mutator categories

ts-mutate translates category inclusion into Stryker's mutator.excludedMutations setting.

Supported categories:

  • all
  • conditionals
  • logical
  • arithmetic
  • boolean
  • string
  • array
  • object
  • function-call
  • typescript

The registry is version-pinned in src/mutators.ts for StrykerJS 9.6.1. Unknown report mutators fail under --strict.

Strict verification

With --strict, ts-mutate reads Stryker's JSON report after the run and checks that every non-ignored mutant:

  1. has a source location,
  2. is inside one of the resolved target ranges,
  3. uses a known mutator, and
  4. uses a mutator enabled by the requested categories.

Strict mode fails if the JSON report is missing, a mutant is out of range, or a mutator is unknown/disallowed. Surviving mutants are not a wrapper failure; they mean the target project's tests did not kill those mutants.

Generated Stryker config

The generated config uses Stryker's command runner by default:

{
  "testRunner": "command",
  "commandRunner": {
    "command": "npm test"
  },
  "coverageAnalysis": "off",
  "incremental": true,
  "checkers": ["typescript"],
  "reporters": ["clear-text", "json"]
}

coverageAnalysis is intentionally off because arbitrary command-runner test commands cannot safely use per-test coverage.

Programmatic API

import { runTsMutate } from "ts-mutate";

const result = await runTsMutate({
  project: ".",
  targetFunctions: ["AuthService.verifySignature(string,string)"],
  mutators: ["conditionals", "logical", "boolean"],
  testCmd: "npm test",
  strict: true,
});

console.log(result.exitCode, result.verification);

Key exported types include:

  • TsMutateOptions
  • MutatorCategory
  • ResolvedTarget
  • VerificationResult
  • TsMutateResult

Development

npm ci --ignore-scripts
npm test -- --run
npm run build

CI runs the same install, test, and build steps on Node.js 22.x and 24.x.

Limitations

  • Uses Stryker's command runner only.
  • Does not implement a custom mutation engine or native Stryker plugin.
  • Does not support raw source ranges or PR-diff targeting.
  • Mutator category names depend on the pinned StrykerJS version.
  • The target project's baseline test command must pass before Stryker can run.

License

ISC