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

@arinze-clinton/loupe

v0.2.19

Published

Timeline-first motion authoring tool — scrub, annotate, and review React animations against a deterministic timeline.

Readme

npm version downloads license

Loupe is a timeline-first motion authoring tool for React. Scrub your animations, annotate frames inline, and export structured feedback your AI coding agent can act on.

Install

Pick the command for your package manager. If you're not sure which one your project uses, check which lockfile is at the project root: package-lock.json (npm), pnpm-lock.yaml (pnpm), yarn.lock (yarn), bun.lockb (bun).

npm

npm install @arinze-clinton/loupe -D
npx loupe init

pnpm

pnpm add @arinze-clinton/loupe -D
pnpm exec loupe init

yarn

yarn add @arinze-clinton/loupe -D
yarn loupe init

bun

bun add @arinze-clinton/loupe -D
bun x loupe init

No registry config, no auth setup. loupe init walks you through wiring the panel into your app and installs the bundled Claude skill so you can talk to Loupe in plain English from your editor.

If Loupe is already installed in this project, loupe init will say so and show you the installed version instead of re-prompting.

The commands below use npx loupe …. If you're on pnpm, yarn, or bun, replace npx with your package manager's equivalent:

| Package manager | Replace npx with | |---|---| | npm | npx | | pnpm | pnpm exec | | yarn | yarn | | bun | bun x |

Example: pnpm exec loupe check, yarn loupe check, bun x loupe check.

Check your version

npx loupe check

Prints the version you have installed, what range package.json declares, and the latest on npm — plus an upgrade hint if you're behind.

Uninstall

npx loupe uninstall

Removes the @arinze-clinton/loupe dependency and the files loupe init wrote (loupe.example.tsx, .claude/skills/loupe/SKILL.md). Won't touch files you've edited. Auto-detects npm / pnpm / yarn / bun from your lockfile and uses the right uninstall command.

Troubleshooting

"npm error Cannot read properties of null (reading 'matches')" Your project uses a different package manager than npm — usually pnpm. Check for pnpm-lock.yaml / yarn.lock / bun.lockb at the project root and use the matching install command above.

"Unknown command: check" (or uninstall) You're hitting a cached older version. Force the latest:

npx @arinze-clinton/loupe@latest --version

Should print loupe v0.2.2 or higher. If not, clear npx's cache (rm -rf ~/.npm/_npx) and try again.

Usage

import {
  LoupeRegistryProvider,
  LoupePanel,
} from '@arinze-clinton/loupe';

function App() {
  return (
    <LoupeRegistryProvider>
      <YourApp />
      {import.meta.env.DEV && <LoupePanel />}
    </LoupeRegistryProvider>
  );
}

Wrap any animated scene in <TimelineProvider> and Loupe picks it up automatically.

import { TimelineProvider, useTimelineValue } from '@arinze-clinton/loupe';
import { motion } from 'framer-motion';

function MyScene() {
  return (
    <TimelineProvider
      config={{
        id: 'my-scene',
        label: 'My Scene',
        phaseOrder: ['idle', 'enter', 'hold', 'exit'],
        phaseDurations: { idle: 400, enter: 600, hold: 1200, exit: 500 },
      }}
    >
      <FadingBox />
    </TimelineProvider>
  );
}

function FadingBox() {
  const opacity = useTimelineValue(0, 1, { phase: 'enter' });
  return <motion.div style={{ opacity }}>Hello</motion.div>;
}

Features

  • Scrub any registered scene — pause, seek, restart, and play at 0.25× to 4× speed
  • Phase strip — every named phase is a clickable segment with proportional width
  • Element annotations — click any element on a paused frame and leave a note
  • Region annotations — draw a box around an empty area and leave a note there
  • Markdown export — one click copies all annotations as structured Markdown your AI agent can parse
  • Multi-scene panel — one floating UI controls every scene on the page; pick from a dropdown, the picked scene flashes
  • Persistent layout — drag the panel anywhere; position survives reloads
  • Mobile-aware — collapses to a compact two-row layout under 640px
  • CLI scannernpx loupe scan reports which animations are timeline-bound and which need refactoring
  • Claude skill bundledloupe init writes a skill into .claude/skills/ so the agent understands timeline-first motion

How it works

Loupe is built around one idea: every motion is a function of time. Time is the single source of truth — a shared MotionValue advanced by requestAnimationFrame. Scrubbing back is just time.set(0). Pausing is just clearing the frame loop. Reviewing your animation feels like reviewing a video edit, not poking at a black box.

Every <TimelineProvider> registers itself with the app-root LoupeRegistryProvider. The floating panel reads the active scene's state and drives it. Annotations are stored per-scene in localStorage and exported as Markdown for your AI agent.

Requirements

  • React 18+
  • Framer Motion 11+
  • Modern desktop or mobile browser

Docs

License

PolyForm Shield 1.0.0 — use it freely in any project, including commercial work. You may not fork it into a competing product.