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

todoage

v0.1.0

Published

Scan your codebase for TODO/FIXME/HACK/XXX/BUG comments and use git blame to show how old each one is and who wrote it. Flags tech debt older than N days. CI-friendly, zero dependencies.

Readme

todoage

How old is your tech debt? todoage scans your codebase for TODO / FIXME / HACK / XXX / BUG comments, then uses git blame to show how old each one is and who wrote it — and flags anything that's been rotting longer than your threshold.

Zero dependencies. Zero config. Read-only — it never writes to your repo.

npx todoage
AGE   TAG    LOCATION              AUTHOR          TEXT
418d  FIXME  src/auth/session.js:71  Alice Dev       refresh tokens before they expire
402d  TODO   src/billing/charge.js:12  Alice Dev     validate the amount before charging
311d  HACK   src/api/proxy.ts:88    Bob Maintainer  works around the upstream 1.4 bug
9d    TODO   src/ui/cart.tsx:140    Carol           wire up the empty-cart state

summary:  4 markers · 3 older than 90d

The red rows are your stalest debt — the stuff that quietly became permanent.

Why it exists

tickgit (324★) promised exactly this — blame + age tracking for your TODOs — and then went quiet in 2020 having never shipped it. VS Code's todo-tree solves IDE visibility, but there's no small CLI that does the age + author part for a CI report or a Markdown summary.

So that's all todoage is: the missing CLI. It answers one question — which of these TODOs has been here so long it's basically a lie? — and answers it in a way you can drop into a CI gate.

How it works

It walks your tree (skipping .git, node_modules, .venv, dist, build artifacts and obvious binaries), matches comment markers in real comment contexts (//, #, /* */, <!-- -->, --, ;, leading *), and asks git blame for the author and author-date of each matching line. Age is whole days from the commit that introduced the line.

Markers are case-sensitive UPPER, so todomvc and fixme_helper don't trigger false positives — only an actual // TODO does.

Not in a git repo? It still lists every marker; age and author just show as ?.

Install

npx todoage              # no install, run on demand
npm i -g todoage         # or install the `todoage` command globally

There's an identical Python build too: pipx run todoage / pip install todoage (see todoage-py). Both ports are tested against the same vectors, so they produce byte-for-byte identical output.

Usage

todoage [path] [options]

| Option | Description | | --- | --- | | --max-age <days\|90d> | Staleness threshold (default 90). Suffixes: d w m y (e.g. 12w, 6m, 1y). | | --tags <list> | Comma-separated markers to scan for (default TODO,FIXME,HACK,XXX,BUG). | | --author <substr> | Only items whose blame author contains this substring. | | --json | Emit compact JSON instead of a table. | | --fail-on-stale | Exit 1 if any item is stale — a one-line CI gate. | | --no-color | Disable ANSI color. Also respects NO_COLOR. | | -h, --help | Show help. | | -v, --version | Print version. |

Exit codes: 0 nothing stale · 1 stale found (with --fail-on-stale) · 2 usage error.

Examples

# fail CI if any TODO is older than a quarter
npx todoage --max-age 90d --fail-on-stale

# just the FIXMEs Alice left behind
todoage --tags FIXME --author alice

# feed a dashboard / Markdown summary
todoage --json | jq '.items[] | select(.stale)'

# scan one subtree, tighter threshold
todoage src/ --max-age 30d

Design notes

  • One pure core, two runtimes. scanLine, ageDays, and isStale are pure functions with no I/O, clock, or git — driven by a shared input→output vectors table that the Node and Python suites both run. That's what proves the two ports agree.
  • Age math never touches a Date. It's integer milliseconds → whole days, so the result is deterministic and identical across languages.
  • Read-only. It blames, it prints, it exits. No state, no cache, no config file, nothing written to your tree.

License

MIT