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

nit-app

v0.0.3

Published

Nit - Visual, Figma-style commenting for live prototypes with state-aware anchoring

Readme

Nit

The missing feedback layer for AI-generated UI

Figma-style comments for live prototypes. One script tag, click anywhere, leave feedback.


What is Nit?

More and more designers are leaning into live prototypes. Static mocks have found a new place in workflows. We now find ourselves prompting functional prototypes into existence using v0, Cursor, Lovable, and Bolt.

Nit is the bridge between your prompt and your final design. It's a lightweight, zero-config setup that lets you pin design feedback directly to the elements in your prototypes. If a Figma comment and a React component had a baby, this would be it.

Why Nit?

Because a screenshot can't click a button. Traditional design tools are great for static layouts, but when you're vibe-coding / prototyping, the "design" is the interaction, the state, and the flow. Nit brings the feedback into the browser.


Quick Start

Option 1: Ask your AI assistant (recommended)

Paste this into Cursor, Windsurf, or Copilot:

Add Nit visual feedback to my project.

1. Install: npm install nit

2. Add this before </body> in my root HTML (or use <Script> for Next.js):
   <script src="https://usenit.dev/widget.js?project=GENERATE_A_SLUG"></script>
   Generate a random slug like "swift-otter-42".

3. In my root component, add useNitState to capture UI state:

   import { useNitState } from 'nit';
   useNitState({
     // key: [value, setter] for each piece of conditional UI state
   });

   Find every useState controlling modals, drawers, tabs, panels.
   Add each as a [value, setter] pair.

4. Create a .nit file in the repo root with just the slug.

The agent reads your codebase, finds your modals and tabs, and wires everything up. It takes 30 seconds.

Option 2: CLI

npx nit-app init

Detects your framework, generates a project slug, injects the script tag, and creates a .nit file.

Then generate state hooks automatically:

npx nit-app hooks

Option 3: Manual

Add before </body>:

<script src="https://usenit.dev/widget.js?project=my-project-42"></script>

State Capture

Nit can capture and restore UI state (modals, tabs, drawers) so clicking a comment in the panel re-opens the exact view. Use the useNitState hook:

import { useNitState } from 'nit';

function App() {
  const [modalOpen, setModalOpen] = useState(false);
  const [activeTab, setActiveTab] = useState(0);

  useNitState({
    modalOpen: [modalOpen, setModalOpen],
    activeTab: [activeTab, setActiveTab],
  });
}

One line per state slice. The hook handles NIT_CAPTURE_STATE, NIT_RESTORE_STATE, and NIT_DESCRIBE_STATE automatically.

Without state hooks, comments still work — you just can't click-to-restore hidden elements from the panel.


CLI

The CLI reads the project ID from .nit and queries the same Supabase backend as the widget.

npx nit-app init

Framework detection + script tag injection + .nit file creation.

npx nit-app hooks

Scans your codebase for useState calls that control UI visibility, generates a useNitState() call, and injects it.

npx nit-app status

swift-otter-42 — 5 open comments

/dashboard (3)
  bug      Button overflow on mobile           Jason, 2h ago
  design   Spacing inconsistent in nav         Wild Fox, 3h ago
  question Should we add search?               Swift Otter, 1d ago

/pricing (2)
  blocker  Prices not loading on Safari        Jason, 4h ago
  idea     Add annual pricing toggle           Wild Fox, 1d ago

3 resolved this week

Flags: --json for machine-readable output, --type bug to filter, --page /dashboard to scope.


How Sync Works

Same project slug = same comments everywhere.

localhost:5173  <-->  Supabase  <-->  preview.vercel.app
You, building        Real-time       PM, reviewing
                     sync

The script tag is in your code, so every deploy (local, preview, staging) gets the widget. Comments sync in real-time.


Features

  • Pin to DOM — Comments anchor to elements. If the element moves, the comment follows.
  • Floating comments — Click empty space to leave feedback not tied to any element.
  • Real-time sync — See feedback instantly across tabs and collaborators via Supabase.
  • URL aware — Feedback is scoped to specific routes.
  • State fingerprinting — Comments know about app state (modals, tabs, query params).
  • Anonymous identity — Auto-generated names ("Swift Otter") with stable IDs. No login required.
  • Ownership-based delete — Only the comment author can delete their own comments.
  • Zero config — One script tag. No accounts.

Architecture

nit (npm library)

React hooks for state fingerprinting and state capture.

Exports:

  • useNitState() — Register UI state for capture/restore
  • useStateFingerprint() — Framework-agnostic URL + state tracking
  • useReactRouterFingerprint() — React Router v6+ integration
  • useNextFingerprint() — Next.js App Router integration
  • hashObject() — Deterministic DJB2 hashing utility
  • TypeScript types for StateFingerprint, Comment, etc.

nit-widget (script tag)

Standalone browser widget. Built as a single IIFE bundle with Supabase baked in. Includes: toolbar, element selection overlay, comment composer, pins, side panel, popovers, settings, and debug panel.

nit-app CLI (npx nit-app)

Terminal client for project setup and comment management. Commands: init, hooks, status.


Development

Prerequisites

  • Node.js 18+
  • npm

Setup

npm install          # Root (library + CLI)
cd widget && npm install
cd demo && npm install

Dev mode

npm run dev          # Widget watch + copy + Vite demo server

Building

npm run build        # Library → dist/
cd widget && npm run build  # Widget → widget/dist/widget.global.js

Testing

npm test             # All tests
npm run lint         # TypeScript type checking
npm run check        # Supabase connectivity check

Widget environment

The widget requires Supabase credentials at build time. Create widget/.env:

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_PUBLISHABLE_KEY=sb_...

Project Structure

.
├── src/                    # NPM library (React hooks)
│   ├── hooks/              # useNitState, useStateFingerprint, etc.
│   ├── utils/              # hashObject (DJB2 hashing)
│   ├── types.ts            # Shared TypeScript types
│   └── index.ts            # Public exports
├── cli/                    # CLI (npx nit-app)
│   ├── index.mjs           # Entry point + arg parsing
│   ├── utils.mjs           # Slug generation, framework detection, Supabase client
│   └── commands/           # init, hooks, status
├── widget/                 # Standalone browser widget (IIFE)
│   ├── src/
│   │   ├── components/     # Toolbar, Overlay, Composer, Pins, Panel, etc.
│   │   ├── utils/          # identity, DOM, animation, classifier
│   │   ├── storage/        # Supabase + localStorage adapters
│   │   ├── supabase.ts     # Supabase facade + project ID resolution
│   │   ├── fingerprint.ts  # URL + state fingerprinting
│   │   └── index.ts        # NitWidget singleton
│   └── tsup.config.ts      # IIFE build config
├── demo/                   # React + Vite demo app
├── INSTALL_PROMPT.md       # AI assistant install prompt
├── TESTING.md              # Manual testing guide
└── tsconfig.json           # TypeScript config

License

MIT

Credits

Built for builders by Jason Calleiro