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

@specscreen/analytics

v0.1.3

Published

Framework-agnostic analytics SDK with event tracking, auto-capture, and session/error capture. Works with React, Vue, Svelte, Next.js, Nuxt, SvelteKit, or plain JS.

Readme

@specscreen/analytics

Framework-agnostic analytics SDK for the browser. Event tracking, auto-capture, and session/error capture in one small, tree-shakeable package — with first-class adapters for React, Vue, and Svelte, and zero-dependency use in Next.js, Nuxt, SvelteKit, or plain JavaScript.

  • 🌳 ESM + CJS, fully typed, sideEffects: false
  • 🧩 Works anywhere; framework adapters are optional subpath imports
  • 🖥️ SSR-safe — every API is a no-op during server rendering
  • 📦 Batched transport with sendBeacon on unload (no lost events)
  • 🔌 Auto-capture clicks / page views / form submits, plus uncaught errors
  • 🔒 Privacy-aware: respectDoNotTrack, beforeSend redaction, data-ss-no-capture

Install

npm install @specscreen/analytics

react, vue, and svelte are optional peer dependencies — install only the one your app uses (or none, for the vanilla core).

Quick start (vanilla — any framework)

import { createAnalytics } from "@specscreen/analytics";

export const analytics = createAnalytics({
  apiKey: "pk_live_xxx",
  autoCapture: true,   // clicks, page views, form submits
  captureErrors: true, // uncaught errors + promise rejections
});

analytics.identify("user_123", { plan: "pro" });
analytics.track("Signup Completed", { plan: "pro" });

React / Next.js

// app/providers.tsx
"use client";
import { AnalyticsProvider } from "@specscreen/analytics/react";

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <AnalyticsProvider config={{ apiKey: "pk_live_xxx", autoCapture: true }}>
      {children}
    </AnalyticsProvider>
  );
}
// any client component
"use client";
import { useAnalytics, usePageView } from "@specscreen/analytics/react";
import { usePathname } from "next/navigation";

export function CheckoutButton() {
  const analytics = useAnalytics();
  usePageView(usePathname()); // track SPA navigations
  return <button onClick={() => analytics.track("Checkout Started")}>Buy</button>;
}

Vue / Nuxt

import { createApp } from "vue";
import { analyticsPlugin } from "@specscreen/analytics/vue";

const app = createApp(App);
app.use(analyticsPlugin, { apiKey: "pk_live_xxx", autoCapture: true });
<script setup lang="ts">
import { useAnalytics } from "@specscreen/analytics/vue";
const analytics = useAnalytics();
</script>

<template>
  <button @click="analytics.track('Checkout Started')">Buy</button>
</template>

For Nuxt, register the plugin in a client plugin file (plugins/analytics.client.ts).

Svelte / SvelteKit

<!-- src/routes/+layout.svelte -->
<script lang="ts">
  import { setAnalytics } from "@specscreen/analytics/svelte";
  setAnalytics({ apiKey: "pk_live_xxx", autoCapture: true });
</script>

<slot />
<!-- any child component -->
<script lang="ts">
  import { getAnalytics } from "@specscreen/analytics/svelte";
  const analytics = getAnalytics();
</script>

<button on:click={() => analytics.track("Checkout Started")}>Buy</button>

API

createAnalytics(config) / new Analytics(config)

| Method | Description | | --- | --- | | track(event, properties?) | Track a named event. | | page(name?, properties?) | Record a page view (automatic when autoCapture is on). | | identify(userId, traits?) | Associate the device with a known user. | | register(properties) | Attach properties to every subsequent event. | | reset() | Clear identity, rotate the anonymous id (call on logout). | | flush() | Force-send buffered events. | | enable() / disable() | Toggle event sending at runtime. | | shutdown() | Flush and detach all listeners. | | getAnonymousId() / getUserId() | Read current identity. |

Config

| Option | Default | Description | | --- | --- | --- | | apiKey | — | Required project write key. | | endpoint | SpecScreen ingest | Custom ingest URL. | | autoCapture | false | true, or { click, pageview, submit, maskSelector }. | | captureErrors | false | Capture uncaught errors + rejections. | | sessions | true | Attach a session id; emit $session_start. | | sessionTimeout | 1800000 | Inactivity (ms) before a new session. | | flushAt / flushInterval | 20 / 5000 | Batch size / max buffer time (ms). | | storage | "localStorage" | "localStorage" | "cookie" | "memory". | | respectDoNotTrack | false | Disable when the browser DNT signal is set. | | disabled | false | Start disabled (call enable() after consent). | | filter | — | Drop events by name or path: { events, paths }. | | beforeSend | — | Mutate or drop (return null) each event. | | redact | — | Strip PII keys before send. string[] or { keys, mask, emails }. | | transport | HTTP | Provide a custom { send(events) } transport. | | debug | false | Verbose console logging. |

Filtering events

Drop events you don't want to count — by event name or by URL path — without writing beforeSend logic:

createAnalytics({
  apiKey: "pk_live_xxx",
  autoCapture: true,
  filter: {
    events: ["$click"],                  // never send click events
    paths: ["/dashboard/**", "/admin/*"], // capture nothing on these paths
  },
});

* matches within a path segment, ** matches across segments. Filtered events are dropped before any network or session work, so they're free.

Tip: to stop capturing a whole category at the source (no listeners attached at all), prefer the granular auto-capture switch — autoCapture: { click: false } — over filter.events: ["$click"]. Use filter for paths and for custom events.

Privacy

  • Strip PII in the browser with redact — denied keys never leave the device:
    createAnalytics({
      apiKey: "pk_live_xxx",
      redact: ["email", "password", "ssn"],          // shorthand for { keys: [...] }
      // or: redact: { keys: ["email"], mask: "***", emails: true }
    });
    Applied recursively to properties and context, and runs last (after beforeSend) so denied keys can't escape. Use an opaque userId, not an email — redact can't scrub the identifier itself.
  • Add data-ss-no-capture to any element/subtree to exclude it from auto-capture.
  • Form field values are never captured — only ids/names/actions.
  • Use beforeSend for custom logic, or disabled: true + enable() to gate on consent.

Development

npm install
npm run build      # tsup → dist/ (ESM + CJS + .d.ts)
npm run typecheck  # tsc --noEmit

License

MIT © SpecScreen