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

docgen-drift

v0.1.0

Published

Symbol-level documentation drift detection for TypeScript and JavaScript

Readme

docgen

Symbol-level documentation drift detection for TypeScript and JavaScript. Catches docstrings that stopped being true. Regenerates them on demand.

Not a "document my whole repo with AI" button. Those exist, several were well funded, and all of them are archived (see DECISIONS.md). The failure mode was never cost or quality — it was that a 2,500-docstring pull request is unreviewable, so it gets rubber-stamped or closed, and nothing brings the user back a second week.

docgen inverts that. The default workflow produces zero docstrings on day one.

The workflow

docgen baseline          # record what exists today. writes no docs. no LLM calls.
docgen check             # CI gate: fail when a documented symbol changed but its doc didn't
docgen check --fix       # regenerate only the docs that drifted

baseline is the adoption path. You accept the docs you have, and from that moment forward the build fails when someone changes settleInvoice without touching the comment that describes it. Drift arrives one or two symbols per PR — a reviewable amount — and each one lands in the PR that caused it, where the author still has the context in their head.

Backfilling undocumented symbols is a separate, opt-in, deliberately noisy operation:

docgen fix --missing --path src/api    # bounded by path. review it like code.

For a large monorepo, configure package tsconfig.json files as separate projects and backfill one path at a time. Projects are processed sequentially by default so several compiler programs are not held in memory at once; lockfiles may be shared at the workspace root or kept per project.

An ordinary leading // comment can be useful source material even though it is not JSDoc. Attached line-comment groups are included in LLM context by default. They are preserved unless docs.leadingComments.onGenerate is explicitly set to "replace"; in that mode, an eligible group is atomically replaced only after generated JSDoc passes validation and the judge. Directives, licenses, trailing comments, and comments inside a body are never replacement candidates.

What makes the docstrings worth reading

A docstring that restates the signature is worse than no docstring — it costs review attention and goes stale. Documentation quality tracks the context the model was given, and the published failure mode is minimal context: "LLMs struggled with minimal code contexts. Short, simple methods with few dependencies produced lower-quality documentation."

So docgen is, structurally, a context assembly engine that happens to emit docstrings. For each symbol it assembles, in descending value-per-token:

  1. Attached leading comments — often the closest thing an undocumented symbol has to an intent statement
  2. Test names that reference the symbol — it("returns null when the user is soft-deleted") is already the docstring
  3. The symbol's own body
  4. Call sites (the line ±2), not caller bodies — argument names and the variable the result lands in
  5. Callee summaries, generated first — docs are produced in reverse topological order, so every dependency already has an English one-liner
  6. Referenced type declarations, fields only
  7. The commit subject that introduced the symbol (git log -L)

And it is allowed to say nothing. SKIP is a first-class model output, and a second cheap pass judges whether the produced docstring says anything the signature didn't. Silence beats filler.

Status

Version 0.1.0 implements extraction, baseline, and the LLM-free check path with human, JSON, and SARIF reports. Generation remains unimplemented. See PLAN.md for the build order and ARCHITECTURE.md for the design.

TypeScript and JavaScript first, via the TypeScript compiler API. Python and Go are planned behind a language adapter interface (see ARCHITECTURE.md) but no adapter beyond TS/JS will be written until the TS path is genuinely good.

Non-goals

  • Token efficiency as a headline. 5,000 symbols is a few dollars. Optimizing that is optimizing the wrong axis; rich context is worth paying for. Cost is a constraint, not a feature.
  • Generating prose documentation sites. Docstrings live next to code. Markdown drift is a different, more crowded problem.
  • Letting the model write JSDoc syntax. The model returns semantic strings. The AST layer renders and inserts them. See ADR-002.