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

@mutineerjs/mutineer

v0.7.0

Published

A fast, targeted mutation testing framework for JavaScript and TypeScript

Downloads

986

Readme

                  _   _
                 | | (_)
  _ __ ___  _   _| |_ _ _ __   ___  ___ _ __
 | '_ ` _ \| | | | __| | '_ \ / _ \/ _ \ '__|
 | | | | | | |_| | |_| | | | |  __/  __/ |
 |_| |_| |_|\__,_|\__|_|_| |_|\___|\___|_|

       === ~> !== · && ~> || · + ~> -

Mutineer is a fast, targeted mutation testing framework for JavaScript and TypeScript. Mutineer introduces small code changes (mutations) into your source files and runs your existing tests to see if they catch the defect. If a test fails, the mutant is "killed" -- meaning your tests are doing their job. If all tests pass, the mutant "escaped" -- revealing a gap in your test coverage.

Built for Vitest with first-class Jest support. Other test runners can be added via the adapter interface.

Author: Billy Jones

How It Works

  1. Baseline -- runs your test suite to make sure everything passes before mutating
  2. Mutate -- applies AST-safe operator replacements to your source files (not your tests)
  3. Test -- re-runs only the tests that import the mutated file, using temp files in __mutineer__ dirs loaded via Vite plugin / Jest resolver
  4. Report -- prints a summary with kill rate, escaped mutants, and per-file breakdowns

Mutations are applied using Babel AST analysis, so operators inside strings and comments are never touched. Mutated code is written to a temporary __mutineer__ directory next to each source file, then loaded at runtime via Vite plugins (Vitest) or custom resolvers (Jest).

Supported Mutations (WIP)

| Category | Mutator | Transformation | | ------------ | ------------------- | ------------------------------------ | | Equality | flipStrictEQ | ===!== | | | flipStrictNEQ | !===== | | | flipEQ | ==!= | | | flipNEQ | !=== | | Boundary | relaxLE | <=< | | | relaxGE | >=> | | | tightenLT | <<= | | | tightenGT | >>= | | Logical | andToOr | &&\|\| | | | orToAnd | \|\|&& | | | nullishToOr | ??\|\| | | Arithmetic | addToSub | +- | | | subToAdd | -+ | | | mulToDiv | */ | | | divToMul | /* | | | modToMul | %* | | | powerToMul | *** | | Return value | returnToNull | return xreturn null | | | returnToUndefined | return xreturn undefined | | | returnFlipBool | return truereturn false | | | returnZero | return nreturn 0 | | | returnEmptyStr | return sreturn '' | | | returnEmptyArr | return [...]return [] |

Installation

npm i @mutineerjs/mutineer

Usage

Commands

| Command | Description | | ---------------- | --------------------------------------------------- | | mutineer init | Create a mutineer.config.ts with minimal defaults | | mutineer run | Run mutation testing | | mutineer clean | Remove leftover __mutineer__ temp directories |

Quick Start

Try it immediately with npx:

npx @mutineerjs/mutineer init
npx @mutineerjs/mutineer run

Or add scripts to your package.json (recommended for team projects):

{
  "scripts": {
    "mutineer": "mutineer run",
    "mutineer:init": "mutineer init"
  }
}
npm run mutineer:init
npm run mutineer

CLI Options (for mutineer run)

| Flag | Description | Default | | ------------------------ | ------------------------------------------ | ------------- | | --runner <type> | Test runner: vitest or jest | vitest | | --config, -c | Path to config file | auto-detected | | --concurrency <n> | Parallel workers (min 1) | CPUs - 1 | | --changed | Only mutate files changed vs base branch | -- | | --changed-with-deps | Include dependents of changed files | -- | | --only-covered-lines | Skip mutations on uncovered lines | -- | | --per-test-coverage | Run only tests that cover the mutated line | -- | | --coverage-file <path> | Path to Istanbul coverage JSON | auto-detected | | --min-kill-percent <n> | Fail if kill rate is below threshold | -- | | --progress <mode> | Display mode: bar, list, or quiet | bar |

Examples

Run mutations on only the files you changed:

npm run mutineer -- --changed

Run with Jest and a minimum kill rate:

npm run mutineer -- --runner jest --min-kill-percent 80

Focus on covered code with 2 parallel workers:

npm run mutineer -- --only-covered-lines --concurrency 2

Configuration

Create a mutineer.config.ts (or .js / .mjs) in your project root with mutineer init, or manually:

import { defineMutineerConfig } from 'mutineer'

export default defineMutineerConfig({
  source: 'src',
  runner: 'vitest',
  vitestConfig: 'vitest.config.ts',
  minKillPercent: 80,
  onlyCoveredLines: true,
})

Config Options

| Option | Type | Description | | ------------------- | -------------------- | ------------------------------------------------ | | source | string \| string[] | Glob patterns for source files to mutate | | targets | MutateTarget[] | Explicit list of files to mutate | | runner | 'vitest' \| 'jest' | Test runner to use | | vitestConfig | string | Path to vitest config | | jestConfig | string | Path to jest config | | include | string[] | Only run these mutators | | exclude | string[] | Skip these mutators | | excludePaths | string[] | Glob patterns for paths to skip | | maxMutantsPerFile | number | Cap mutations per file | | minKillPercent | number | Fail if kill rate is below this | | onlyCoveredLines | boolean | Only mutate lines covered by tests | | perTestCoverage | boolean | Use per-test coverage to select tests | | baseRef | string | Git ref for --changed (default: origin/main) | | testPatterns | string[] | Globs for test file discovery | | extensions | string[] | File extensions to consider |

Recommended Workflow

Large repos can generate thousands of mutations. These strategies keep runs fast and incremental.

1. PR-scoped runs (CI) — --changed-with-deps

Run only on files changed in the branch plus their direct dependents:

mutineer run --changed-with-deps
  • Tune the dependency graph depth with dependencyDepth in config (default: 1)
  • Add --per-test-coverage to only run tests that cover the mutated line
  • Recommended package.json script:
"mutineer:ci": "mutineer run --changed-with-deps --per-test-coverage"

2. Split configs by domain

Create a mutineer.config.ts per domain and run selectively:

mutineer run -c src/api/mutineer.config.ts

Each config sets its own source glob and minKillPercent. Good for monorepos or large modular projects — domains can also be parallelized in CI.

3. Combine filters to reduce scope

  • --only-covered-lines — skips lines not covered by any test (requires a coverage file)
  • maxMutantsPerFile — caps mutations per file as a safety valve
  • Combine for maximum focus:
mutineer run --changed-with-deps --only-covered-lines --per-test-coverage

File Support

  • TypeScript and JavaScript modules (.ts, .js, .tsx, .jsx)
  • Vue Single File Components (.vue with <script setup>)

Extending: Adding a New Test Runner

Mutineer uses an adapter pattern to support different test runners. To add a new one, implement the TestRunnerAdapter interface:

import type {
  TestRunnerAdapter,
  TestRunnerAdapterOptions,
  BaselineOptions,
  MutantPayload,
  MutantRunResult,
} from 'mutineer'

export function createMyRunnerAdapter(
  options: TestRunnerAdapterOptions,
): TestRunnerAdapter {
  return {
    name: 'my-runner',

    async init(concurrencyOverride?: number) {
      // Start worker pool, set up file-swap mechanism, etc.
    },

    async runBaseline(tests: readonly string[], opts: BaselineOptions) {
      // Run all tests without mutations.
      // Return true if they pass, false otherwise.
      // If opts.collectCoverage is true, write Istanbul-format JSON.
    },

    async runMutant(mutant: MutantPayload, tests: readonly string[]) {
      // Swap in the mutated code and run the relevant tests.
      // Return { status: 'killed' | 'escaped' | 'timeout' | 'error', durationMs }
    },

    async shutdown() {
      // Tear down workers and clean up resources.
    },

    hasCoverageProvider() {
      // Return true if the runner has coverage support available.
      return false
    },

    async detectCoverageConfig() {
      // Return { perTestEnabled, coverageEnabled } from runner config.
      return { perTestEnabled: false, coverageEnabled: false }
    },
  }
}

The key requirement is the file-swap mechanism -- the adapter needs a way to intercept module resolution so the mutated source code is loaded instead of the original file on disk. See the Vitest adapter (Vite plugin + ESM loader) and Jest adapter (custom resolver) for working reference implementations in src/runner/vitest/ and src/runner/jest/.

License

MIT