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

@usecaliper/annotation

v1.0.2

Published

Build-time annotation plugins for the Inline Edit Tool — stamp source locations onto the DOM so rendered text can be traced back to the file it came from (React, Vue, Svelte, Angular)

Readme

@usecaliper/annotation

Build-time plugins that stamp source locations onto the DOM, so rendered text can be traced back to the file it came from.

Part of the Inline Edit Tool, but useful on its own to anyone who wants data-edit-file / data-edit-line on their markup.

npm install --save-dev @usecaliper/annotation

What it emits

On qualifying text-bearing elements:

<h1 data-edit-file="src/components/Hero.tsx"
    data-edit-line="12"
    data-edit-col="4"
    data-editable="true"
    data-edit-framework="react">
  Build things that matter
</h1>

On <html>, describing the build itself:

<html data-edit-branch="feature/pricing"
      data-edit-commit="9f1c2ab…"
      data-edit-repo="acme/site">

Elements whose text comes from a translation function get the key instead, so the copy can be traced to a locale file:

<p data-edit-i18n-key="home.cta.subtitle">…</p>

When it runs

Inert unless INLINE_EDIT is truthy, or the bundler reports a dev build.

INLINE_EDIT=1 npm run build      # preview deployment
npm run build                    # production: no annotations

Annotations expose your source layout. Never ship them to production.

Setup

React / Next.js

{ "plugins": ["@usecaliper/annotation/react"] }

Vue / Nuxt

import inlineEdit from '@usecaliper/annotation/vue';

export default { plugins: [vue(), inlineEdit()] };

Nuxt

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@usecaliper/annotation/nuxt'],
});

Nuxt needs a module rather than the Vite plugin. It renders its HTML through Nitro, so Vite's transformIndexHtml never runs — and that is the hook the plain plugin uses to stamp the branch and commit onto <html>. Register the Vite plugin by hand and the annotations appear while the build metadata does not, which leaves the extension unable to tell which build it is editing.

To run the editor on the page as well, without installing the extension (development only):

modules: [
  ['@usecaliper/annotation/nuxt', {
    preview: {
      extensionDist: '/path/to/inline-edit-tool/extension/dist',
      autoOpen: false,   // summon with Cmd/Ctrl+Shift+E instead
    },
  }],
],

The toolbar opens on load by default. On a project where the module stays in nuxt.config that means it appears on every reload during ordinary development, so autoOpen: false leaves it to the shortcut. The shortcut toggles it either way.

Svelte / SvelteKit

import inlineEdit from '@usecaliper/annotation/svelte';

export default { plugins: [inlineEdit(), sveltekit()] };

Order matters: the Svelte compiler turns a component into JavaScript, so the plugin has to see the file first. It runs enforce: 'pre' for that reason.

Unlike the Vue plugin this has no peer dependency — it scans the markup itself. svelte/compiler changed its AST between Svelte 4 (html, Element) and 5 (fragment, RegularElement), and a plugin that silently stops annotating on a major upgrade is worse than one that never depended on the version at all.

Angular

Requires @angular-builders/custom-webpack. In angular.json:

{
  "customWebpackConfig": {
    "path": "./node_modules/@usecaliper/annotation/angular/webpack.config.js",
    "mergeStrategies": { "module.rules": "prepend" }
  }
}

Build metadata

Branch, commit and repository are read from CI environment variables — Vercel, Netlify, GitHub Actions, Amplify, Cloudflare Pages and Render are detected automatically.

Git is only a last resort: build hosts check out a detached HEAD, where git rev-parse --abbrev-ref HEAD returns the literal string "HEAD", and some build images ship no .git at all.

Override with INLINE_EDIT_BRANCH, INLINE_EDIT_COMMIT, INLINE_EDIT_REPO.

What gets annotated

Text-bearing HTML elements — p, h1–h6, span, a, button, label, li, td, th, strong, em, small, b, i — that contain literal text rather than an interpolation.

<script> and <style> bodies are blanked before scanning, so a <p> in a string literal or a p { } selector is never mistaken for markup. This matters most for Svelte, where every component has a script block.

Deliberately skipped:

  • Elements whose content is an expression ({title}), because there is no literal in the source to change
  • Elements mixing literal text with markup, because rewriting the whole content would destroy the markup
  • Components (<Hero>), as opposed to native tags
  • A translation call mixed with literal text, because which part was edited would be ambiguous