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

emend-cli

v0.2.1

Published

Verified AI dependency migrations. Finds which of your lines a version bump actually breaks, fixes them, and proves the result still compiles and passes your tests.

Readme

Emend

Verified AI migrations for dependency upgrades.

Emend finds which of your lines a version bump actually breaks, migrates them with an agent in a throwaway worktree, then proves the result compiles and your tests still pass — or refuses to call it fixed.

npm CI node licence

emend scan output

That "+ 1930" line is the product. zod 4 ships 1,934 breaking changes. Four of them touch this repository. Everything downstream operates on those four — and on the line below the summary, which says how much of the repository went unexamined, because a summary that cannot be wrong about its own coverage is the only kind worth reading.


Try it in 30 seconds

No API key. No config. scan is fully deterministic and never calls a model.

npx emend-cli@latest demo ./emend-demo
npx emend-cli@latest scan ./emend-demo --only zod

That scaffolds a repo with genuine dependency drift and shows you exactly the output above. Requires Node 22.6+.

Then point it at something real:

npx emend-cli@latest scan . --only zod,axios

Why this isn't another AI migration tool

Most tools in this category end at "the model edited your files." Emend treats that as the start of the problem, because a model that edits confidently and wrongly is worse than one that does nothing.

Every migration runs in a throwaway git worktree:

  1. baseline — typecheck + tests run before any edit
  2. apply the edits, bump the dependency
  3. post — typecheck + tests run again, and the two are compared

Without step 1, a repository that was already failing has its pre-existing failures blamed on the migration. Emend distinguishes verified / regression / pre-existing-failure / typecheck-only / unverified, and never reports the last three as success. Nothing touches your working tree; the worktree is thrown away unless it verifies.

A second pass — a read-only behaviour review — then answers what a green build cannot: whether the change still means the same thing. Its own edits are re-verified, and reverted wholesale if they don't hold.

Honesty rules, enforced in code

Not conventions. These are properties the test suite holds to:

  • A package with no type declarations is unanalyzable, never "clean".
  • A truncated surface walk suppresses removal reporting — absence past a cutoff is not deletion.
  • Verification that didn't run is unverified, never "passing".
  • No test script means typecheck-only, never "tests pass".
  • Breaking changes detected but not located in your code are counted and reported, not silently dropped — static analysis cannot see client[name]().
  • Skipped packages are counted separately from analyzed ones. Skipped ≠ clean.
  • A run that cannot reach a model repairs nothing and says so. Could not fix is not the same as nothing to fix.

How it works

  package.json + node_modules              npm registry
            │                                    │
            ▼                                    ▼
      installed version  ────────────►  .d.ts of BOTH versions
                                                 │
                                                 ▼
                                       public API surface diff
                                    (removed / signature / deprecated)
                                                 │
   TypeScript program over your repo             │
   (imports + type-checker resolution)           │
            │                                    │
            └──────────────► INTERSECTION ◄──────┘
                                  │
                                  ▼
                              FINDINGS  (symbol, file:line, severity)
                                  │
             ┌────────────────────┼────────────────────┐
             ▼                    ▼                    ▼
     deterministic plan    harness (opencode+MCP)  dashboard / PR
             └──────────► isolated git worktree ◄──────┘
                                  │
                    baseline → apply → verify → compare
                                  │
                                  ▼
                    behaviour review (read-only model)
                                  │
                                  ▼
             verified · regression · unverified · unreviewed

Why .d.ts diffing. Other approaches read version numbers (no idea what changed), OpenAPI specs (most SDK surface isn't in them), or changelogs (prose, and frequently silent about breaks). Type declarations are machine-readable, versioned, exhaustive, and already published by nearly every TypeScript SDK — no provider cooperation required.

Why the intersection matters. A diff alone is noise. Crossing it with real call sites turns "1,934 breaking changes" into a four-item work order with file and line numbers.

The deterministic core — detection, localisation, rename-class migrations, verification — runs with no model involved. The model runs only where the answer is a judgement. Full design in docs/architecture.md.


What it checks

| Tier | What it reads | Command | | --- | --- | --- | | Typed packages | Published .d.ts of both versions, crossed with your call sites | emend scan <repo> | | HTTP contracts | Each vendor's own published OpenAPI description, vs. your outbound calls | emend scan <repo> --contracts | | Version pins | Lockfile vs. the copies in Dockerfiles, CI matrices, .nvmrc | emend pins <repo> | | Vulnerabilities | The installed tree against OSV — no key, no rate limit | emend scan <repo> --vulns |

Calls to APIs you don't have a package for

Half the contracts a service depends on aren't packages at all:

const res = await fetch(`https://api.vendor.com/v1/audiences/${id}/contacts`);

No .d.ts, no lockfile entry, no type — a URL is a string that compiles whatever it says. --contracts resolves each vendor's own OpenAPI description and reports calls reaching a route the description no longer contains, guarded by provenance (is this really the vendor speaking?), currency (a first-party spec last touched in 2020 asserts nothing), and coverage (one host often serves several APIs).

A finding here is a lead to verify, not a proof — providers do serve endpoints they never wrote down, which is why it says not described by rather than removed. See docs/limitations.md.

Versions your repo writes down twice

A version lives in the lockfile, where the package manager keeps it honest. The same version copied into a Docker tag, an .nvmrc, or a CI matrix is a copy, and nothing keeps a copy honest.

$ emend pins ./my-service

  drift      node → 22 (the declared engines.node)
    → Dockerfile:1  node:18-alpine
    → .github/workflows/ci.yml:6  node-version: '22'

  VERIFIED  2 edit(s) applied of 1 repairable conflict(s)

Three files declaring three versions with nothing to arbitrate are reported as disagreeing and not repaired — picking a winner would be guessing, and that decision is yours.


Commands

| Command | What it does | | --- | --- | | emend demo [dir] | Scaffold a demo repo with real drift | | emend scan <repo> | Find API changes that intersect your code | | emend fix <repo> | Plan, apply, and verify migrations | | emend pr <repo> --finding <id> | Render the pull request (dry run by default) | | emend pins <repo> | Repair drifted version pins — no model involved | | emend eval | Measure the agent against a corpus | | emend serve | Local dashboard, or a hosted monitor with GitHub App credentials | | emend models | List models your LLM provider serves | | emend store list | What is stored locally | | emend mcp | Serve Emend's tools over MCP, so a coding agent can drive it |

Useful flags: --only pkg,pkg, --all, --json, --no-dev, --contracts, --features, --freshness, --vulns, --lint (scan); --finding <id>, --no-agent, --no-review, --untrusted, --keep (fix). emend --help has the full list.

emend mcp exposes seven tools — scan, plan_remediation, fix_vulnerability, fix_package, verify, advisory_status, impact — and every one returns what was measured, never a judgement. An agent claiming a vulnerability is fixed has to call advisory_status and read the lockfile's answer.


Repairing, not just scanning

scan needs nothing. Repairing additionally needs the opencode binary on your PATH and a key for a model it can reach. Emend's reviews and PR summaries work with any OpenAI-compatible endpoint:

export EMEND_LLM_PROVIDER=nebius     # or fireworks, together, groq,
                                     # deepinfra, openrouter, ollama, vllm
export NEBIUS_API_KEY=...
emend models                         # see what your provider serves today
export EMEND_LLM_MODEL=<id from above>

emend fix ./my-service

Or point it anywhere directly — a local Ollama works:

export EMEND_LLM_BASE_URL=http://localhost:11434/v1
export EMEND_LLM_MODEL=qwen3-coder:30b

The recommended defaults are open-weight. This follows the literature rather than the intuition: Byam (arXiv 2505.07522) found end-to-end LLM migration fully repaired only 27% of builds, improving markedly when given API diffs, failing lines and compiler feedback — all of which the harness is given. BigBag (arXiv 2606.24446) drives its agent through a harness for 78.6%.

Prompt changes are cheap to make and hard to judge, so there's a scored corpus: docs/evaluating-the-agent.md.


Can I use this at work?

Yes. Emend is MIT-licensed: run it on private code, in your CI, as a service for other people, or embedded in a product you ship — modified or not, commercial or not. The one condition is keeping the copyright and licence notice with copies of the code.


Running it as a service

emend serve is a local dashboard, and becomes a hosted monitor when GitHub App credentials are present:

export EMEND_GITHUB_APP_ID=...
export EMEND_GITHUB_PRIVATE_KEY="$(cat emend.private-key.pem)"
export EMEND_GITHUB_WEBHOOK_SECRET=...

emend serve --port 8080 --host 0.0.0.0     # POST /webhook is now live

Installing it on a repository queues a scan; pushes to the default branch queue another. Each scan reconstructs node_modules from the lockfile, finds the drift, migrates what it can, and opens a draft pull request per package.

Why it can run untrusted repositories in-process: analysis never executes anything from the repository or its dependency tree. Dependencies are symlinked from a tarball cache rather than installed, the bump passes --ignore-scripts, and the repository's test script is never invoked. The cost is that hosted verification is typecheck-only — Emend says so on the pull request rather than implying more, and reads the real verdict back from the check_suite webhook when your CI runs the tests.

Step-by-step: docs/github-app-setup.md · docs/deployment.md


Status

MVP / proof of concept. emend scan reads TypeScript/npm and Python/PyPI repositories; emend fix and pull requests are npm-only, and GitHub is the only host. Scanning, migration and pull requests are exercised against a real private repository; the GitHub App token exchange is the one link only a registered App can validate.

Emend is deliberately explicit about where it can be wrong or silent — docs/limitations.md documents each case, measured rather than hypothesised. If you only read one other page, read that one.

Issues and PRs welcome — CONTRIBUTING.md has the ground rules (npm run typecheck and npm test must be green; prompt changes need an emend eval table before and after).


Docs

| | | | --- | --- | | Getting started | Configure a model, scan a real repository, read the output | | Architecture | The three tiers of evidence, and where the model deliberately does not participate | | Known limitations | Every case where Emend can be wrong or silent, measured | | Evaluating the agent | The scored corpus, and why Pass and Clean are different columns | | GitHub App setup | Registering the App, step by step | | Deployment | Sizing, hosting, systemd/TLS |

Build from source:

git clone https://github.com/diyanbogdanov/emend.git && cd emend && npm install
npm run typecheck && npm test

A checkout runs its sources directly via native type stripping — no build step needed.


Licence

Copyright © 2026 Diyan Bogdanov. MIT — see LICENSE. Third-party material is listed in THIRD-PARTY-NOTICES.md.