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

@exodus/typestripped-diff

v1.0.0

Published

Compare TypeScript source files (with type annotations stripped) against the original JavaScript at a git base ref. Reviewer aid for JS→TS migration PRs.

Readme

@exodus/typestripped-diff

A code-review helper for JS→TS migration PRs.

After a migration, git diff master -- <pkg>/ is dominated by TS additions (annotations, interfaces) and git mv renames, making behavioral changes hard to spot. This tool strips type annotations from the package's TS source (via Node's stripTypeScriptTypes, position-preserving), pairs each with the original JS at a git base ref, and diffs.

What survives in the output: identifier renames, control-flow refactors, added/removed runtime checks, import/export changes — in source AND test files.

Requirements

  • Node 22.6+ (uses built-in node:module.stripTypeScriptTypes)
  • A POSIX diff (default mode) — already on every dev machine
  • Optionally Prettier in the consuming repo (used opportunistically to normalise both halves before diffing — silently skipped if absent; pass --no-prettier to skip explicitly)
  • Optionally difftastic (brew install difftastic) for --difft
  • Optionally the code CLI shim for --vscode

Install

yarn add -D @exodus/typestripped-diff

Or invoke without installing:

npx @exodus/typestripped-diff <package-path> <pre-migration-base-ref>

Usage

# Default: per-file unified diff (Prettier-normalised + diff -w -B)
typestripped-diff features/<pkg> <pre-migration-base-ref>

# Skip Prettier normalisation (if it's slow, missing, or unwanted):
typestripped-diff features/<pkg> <ref> --no-prettier

# Semantic AST diff per file (whitespace-tolerant by design):
typestripped-diff features/<pkg> <ref> --difft

# Open each file pair in VS Code's side-by-side diff view:
typestripped-diff features/<pkg> <ref> --vscode

For piping to less while keeping color:

LESS='-RFX' typestripped-diff <pkg> <ref> | less
LESS='-RFX' DFT_COLOR=always typestripped-diff <pkg> <ref> --difft | less

How it works

  1. Reads the package's tsconfig.{build.,}json to determine:
    • the source root (compilerOptions.rootDir or a single non-glob include[] entry; defaults to src)
    • the output dir to skip during walk (compilerOptions.outDir, plus the always-skipped node_modules, lib, dist).
  2. Walks the source root for .ts, .tsx, .cts, .mts files (skipping only .d.ts). Test files (*.test.* and anything in __tests__/) are included — reviewers want to see test changes alongside source changes.
  3. Strips TypeScript type annotations using Node's stripTypeScriptTypes(source, { mode: 'strip' }). Position-preserving — type annotations become whitespace of the same length, source positions unchanged.
  4. Pairs each stripped file with its original at the base ref via git show <ref>:<path>. Tries both <pkg>/<rel> (migration moved files INTO <sourceRoot>/) and <pkg>/<sourceRoot>/<rel> (migration kept files in <sourceRoot>/ and just renamed the extension).
  5. If Prettier is available in the consuming repo (and --no-prettier was not passed), pipes both halves through prettier --stdin-filepath <original-path> so the host repo's local config drives normalisation. Failures fall back to raw content with a one-time warning.
  6. Diffs with diff -u -w -B (default) or the chosen tool.

Why Prettier normalization

stripTypeScriptTypes preserves positions exactly, but that's not enough on its own:

  • Multi-line type annotations (e.g. discriminated-union return types) leave multi-line whitespace blocks against a single-line original — diff -w -B does not merge lines, so the structural reflow appears as a {- single-line +} {+ multi-line +} pair.
  • Migrators sometimes rewrap arguments or expressions while moving to TS; without Prettier those show up as noise on top of real changes.

Running both halves through the host repo's Prettier collapses semicolons, quote style, indentation, trailing commas, and wrapping — so only behavioural changes remain. diff -w -B is kept as a safety net for --no-prettier mode and for files Prettier fails on.

Extensions handled

| TS source | Looks for original at | | --------- | --------------------------------- | | *.ts | *.js | | *.tsx | *.jsx (then *.js as fallback) | | *.cts | *.cjs | | *.mts | *.mjs |

Exit codes

| Code | Meaning | | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | 0 | Run completed; diffs (if any) printed. Diffs do not constitute failure. | | 2 | Bad invocation, unsupported TS (e.g. enum rejected by stripTypeScriptTypes), unknown git ref, or a hard tool failure (missing diff/difft, etc.). |

The tool is a review aid, not a CI gate — a 0 exit does not mean "no diffs."

Limitations

  • Source location is derived from tsconfig.json. Packages with no tsconfig fall back to src/. If your TS sources live somewhere unusual without an include or rootDir entry, set one or pass that path as <package-path>.
  • Cross-extension migrations (.tsx → .jsx, .ts → .js) are supported; arbitrary file renames within the migration are not — pairing is purely by relative path with the extension swapped.