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

@tryinget/ts-mutate

v0.1.0

Published

Mutation testing for TypeScript and JavaScript using AST-discovered mutation sites.

Downloads

40

Readme


summary: "Package README for ts-mutate, the TypeScript/JavaScript mutation testing tool." read_when:

  • "You are using ts-mutate from the monorepo"
  • "You need package-level CLI behavior, worker model, or manifest semantics" type: "reference"

ts-mutate

Published as @tryinget/ts-mutate.

Mutation testing for TypeScript and JavaScript, inspired by clj-mutate but implemented with the TypeScript compiler API and sidecar manifests. ts-mutate stands on its own as a publishable CLI, but it works especially well with @tryinget/crap4ts, which ranks the next hotspot from real LCOV. The repo keeps them as separate packages so teams can adopt mutation testing without forcing the full companion workflow.

Features

  • Discovers mutation sites from the AST
  • Supports arithmetic, increment/decrement, comparison, equality, boolean, conditional, logical, and 0/1 constant mutations
  • Records mutation index, original text, mutant text, line, column, category, and top-level declaration anchor
  • Optionally uses LCOV to skip uncovered lines
  • Runs a configurable test command per mutant
  • Supports isolated parallel workers
  • Supports differential mutation via a persisted manifest of top-level declarations/functions

Usage

npm exec --yes --package @tryinget/ts-mutate -- ts-mutate src/foo.ts
npm exec --yes --package @tryinget/ts-mutate -- ts-mutate src/foo.ts --scan
npm exec --yes --package @tryinget/ts-mutate -- ts-mutate src/foo.ts --lines 12,48
npm exec --yes --package @tryinget/ts-mutate -- ts-mutate src/foo.ts --max-workers 4
npm exec --yes --package @tryinget/ts-mutate -- ts-mutate src/foo.ts --test-command "npm test -- --runInBand"
npm exec --yes --package @tryinget/ts-mutate -- ts-mutate src/foo.ts --since-last-run
npm exec --yes --package @tryinget/ts-mutate -- ts-mutate src/foo.ts --mutate-all

Monorepo root workflow

From this repo's root, prefer the wrapper for explicit targeted runs. The normal path is a src/ file, but you can also point it at a prebuilt dist/ JS file when you need to work from existing artifacts.

just mutate ts-mutate src/mutate-text.ts
npm run mutate:target -- --package ts-mutate --file src/mutate-text.ts --lines 4 --max-workers 1

The wrapper forwards normal ts-mutate flags and defaults the current Node-based packages to:

npm run build --workspace packages/ts-mutate && cd packages/ts-mutate && node --preserve-symlinks --preserve-symlinks-main --test dist/__tests__/*.test.js

Override that with --test-command "..." when you want a narrower suite. If the custom command still uses Node's test runner, keep both preserve-symlinks flags.

If package-local LCOV exists at packages/<package>/coverage/lcov.info and you do not pass --lcov, the root wrapper forwards that file automatically.

Coverage-aware workflow

Generate source-mapped LCOV from the package test suite:

npm run coverage --workspace packages/ts-mutate

Then either run ts-mutate directly with that LCOV or let the root wrapper auto-detect it:

npm run mutate:target -- --package ts-mutate --file src/workflow.ts
npm run mutate:target -- --package ts-mutate --file src/workflow.ts --lcov packages/ts-mutate/coverage/lcov.info

For an opinionated next-step suggestion, generate a repo-level quality receipt:

just quality ts-mutate

# npm equivalent
npm run quality -- --package ts-mutate

That flow uses crap4ts as the companion ranking step and then prints the exact next ts-mutate command.

CLI options

  • --scan: structural scan only, no tests
  • --update-manifest: rewrite the sidecar manifest without running tests
  • --lines <L1,L2,...>: restrict mutations to selected source lines
  • --since-last-run: mutate only changed top-level declarations/functions
  • --mutate-all: disable differential filtering and test all covered mutations
  • --lcov <path>: explicit LCOV file path
  • --timeout-factor <n>: timeout multiplier relative to the baseline run. Defaults to 10
  • --test-command <command>: test command to run per mutant. Defaults to npm test -- --runInBand
  • --max-workers <n>: worker limit
  • --mutation-warning <n>: warning threshold for large files. Defaults to 50
  • --cwd <path>: override working directory
  • --help: print usage

Manifest behavior

Only clean full mutation passes write a sidecar JSON manifest under .ts-mutate/manifests/.

A run is considered clean when:

  • the baseline test command passes,
  • the mutation run is not line-filtered,
  • no mutants survive,
  • no mutants time out.

The manifest stores a module hash plus hashes of each top-level declaration or statement. If a manifest exists, default runs become differential unless --mutate-all is passed.

Dirty runs do not advance the differential receipt:

  • baseline failures,
  • survivor runs,
  • timeout runs,
  • --lines runs,
  • runs that did not execute a full mutation pass.

Exit behavior

ts-mutate exits non-zero when:

  • the baseline test command fails,
  • one or more mutants survive,
  • one or more mutants time out,
  • CLI argument parsing fails.