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

ainnotations

v0.1.2

Published

Framework-agnostic visual feedback overlay for local dev — draw, highlight and comment on the running page; notes land in a markdown file for your coding agent to process.

Readme

AInnotations

Point at what's wrong on your running app. Your coding agent fixes it.

Draw on the page, highlight a phrase, drop a comment — each note lands in annotations.md, indexed with the exact element, the quoted text and a screenshot. No screenshots to crop, no "the third card on the left", no drag‑and‑drop.

npm node license


The 30 seconds you keep losing

You spot something off in the browser. Today, telling your agent about it costs:

spot it → crop a screenshot → switch to chat → drag it in →
type "the pricing card, third bullet, the one on the left…" →
agent hunts for the element in the pixels → sometimes guesses wrong → repeat

With AInnotations you circle it, say what's wrong, and move on. The selector, the exact words and the picture are captured for you.

| | screenshot + drag‑and‑drop | AInnotations | | --- | --- | --- | | point at the element | describe it in words, hope | draw / select — captured exactly | | what the agent receives | a flat image + your prose | element selector · quoted text · sketch · shot · viewport | | locate the source | agent eyeballs the screenshot | grep the quote → lands on the line | | per fix | ~90 s | ~12 s | | a pass of 8 fixes | ~12 min, and fragile | ~2 min, then process the annotations |

Illustrative, not a benchmark — but the shape is real: the cost isn't the typing, it's making the agent find the thing you're already looking at.

Where CLIs and chat fall apart: the batch

Leave ten remarks across three pages in one pass. In a chat you'd paste ten crops and a numbered list — then hope the agent reconciles shot #5 with instruction #5, on the right button, on the right page. It's a guessing game that gets worse the more you add.

AInnotations doesn't guess. Every note is self‑contained and addressed:

## `a1b2c3`  ·  /pricing  ·  2026-08-13 09:40  ·  1440×778
- **Note** swap these two paragraphs
- **Element** `main > article > div.prose > p:nth-of-type(3)`
- **At** 0.12,0.30
- **Draw** M40,10L80,60 M50,10L55,40
- **Shot** annotations/a1b2c3.png
- **Text** « the passage that was selected »

There's nothing to reconcile: each entry already knows its page, its element and its words. The agent reads the list, applies each one in order, and clears it. That's real indexing, not a pile of pictures.

Quick start

No SDK, no code change, no account. It's a proxy in front of your dev server — so it doesn't care whether you run Astro, Next, Nuxt, SvelteKit, Vue, Rails or Django.

# dev server on :4321 → browse the annotated app on :4000
npx ainnotations --target 4321

Open http://localhost:4000 instead of your dev server. The overlay appears at the bottom‑left. That's it.

| flag | default | meaning | | --- | --- | --- | | --target | — (required) | port your dev server already runs on | | --port | 4000 | port to serve the annotated app on | | --file | annotations.md | where notes are written (relative to cwd) |

Install it for good

npx is perfect for a one‑off. To keep it in a project and give your coding agent the skill permanently:

npm i -D ainnotations       # pin the CLI in your project
npx ainnotations init       # copy the skill into .claude/skills/ainnotations/

init installs the companion Claude Code skill at project scope, so anyone working on the repo can say "start ainnotations" and the agent runs the whole loop — start → process the annotations → stop. Commit .claude/skills/ainnotations/ to share it with the team.

Want it in every project instead of one? Install the skill globally:

mkdir -p ~/.claude/skills/ainnotations
cp node_modules/ainnotations/skill/SKILL.md ~/.claude/skills/ainnotations/

The overlay

  • draw — freehand over a region (circle it, arrow it — multiple strokes), then ✓ to comment. The ink is persistent and scrolls with the page. On send, a screenshot of your sketch over the page is attached to the note (one screen share grant per session, reused) — so the agent sees the intent, not raw path data. Decline it and the note still saves, minus the image.
  • text — select words; the exact quote is captured and stays highlighted until the note is handled. It's the best search key there is — grep it, land on the line.
  • list — opens a panel of every pending note; tap one to scroll straight to its pin and open it. The pins stay on the page the whole time — click any pin directly to read, edit or delete its note.

Dictation (🎤) and paste‑the‑selection are built in, and it all works on a phone. The toolbar itself is draggable: grab the handle to move it anywhere, and drop it against the left or right edge to stand it up vertically — its spot is remembered between reloads.

How it works

browser ──▶ :4000  ainnotations proxy ──▶ :4321  your dev server
                    ├─ injects the overlay <script> into every HTML response
                    ├─ serves /__ainnotations/client.js
                    ├─ /__ainnotations/notes  (GET/POST/PUT/DELETE) ⇄ annotations.md
                    └─ tunnels WebSocket upgrades, so HMR keeps working

The overlay is pure DOM, so it runs anywhere. The proxy handles the two things the browser can't: injecting itself into the page, and writing the file on disk.

For the agent

Notes accumulate in annotations.md. Read the Shot image (it's the user's view with the sketch), locate the source via Text (grep) or Element, apply Note, then remove the entry — deleting a note also deletes its screenshot.

A companion Claude Code skill (skill/SKILL.md) automates the whole loop — npx ainnotations init drops it into your project (see Install). Then start → process the annotations → stop. Say "start AInnotations" or "traite la liste" and it runs.

License

MIT © Florian Dupuis