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

@arthurreira/analytics

v0.23.0

Published

Analytics SDK for af-analytics (browser client + helpers)

Readme

@arthurreira/analytics

Lightweight analytics SDK with three usage modes:

| Mode | Use when | | --- | --- | | <Analytics /> component | Next.js / React apps — zero-config, drop it in the root layout | | useAnalytics hook | React, need custom events from individual components | | Vanilla script tag | Any HTML page — no framework required |

Tracks pageviews, clicks, scroll depth, text copies, JS errors, CTAs, searches, and session duration — with automatic session management and optional real-time presence via WebSocket.


Installation

React / Next.js

pnpm add @arthurreira/analytics
# or
npm install @arthurreira/analytics

Peer dependencies: react ^18 || ^19, next ^14 || ^15 || ^16

Vanilla JS (no package manager)

<script
  src="https://unpkg.com/@arthurreira/[email protected]/dist/af-analytics.umd.js"
  data-api-key="proj_xxx"
  data-url="https://your-edge-worker.dev"
></script>

Drops a global AfAnalytics object and auto-initialises on DOMContentLoaded — no other code needed.

WordPress

Option A — functions.php (recommended for theme/child-theme)

Add to your theme's functions.php:

function af_analytics_enqueue() {
    wp_enqueue_script(
        'af-analytics',
        'https://unpkg.com/@arthurreira/[email protected]/dist/af-analytics.umd.js',
        [],
        null,
        true // load in footer
    );
    // Attach data attributes after the script tag is output
    add_filter( 'script_loader_tag', function ( $tag, $handle ) {
        if ( $handle !== 'af-analytics' ) return $tag;
        return str_replace(
            '<script ',
            '<script data-api-key="proj_xxx" data-url="https://your-edge-worker.dev" ',
            $tag
        );
    }, 10, 2 );
}
add_action( 'wp_enqueue_scripts', 'af_analytics_enqueue' );

Option B — "Insert Headers and Footers" plugin (no code)

  1. Install the Insert Headers and Footers plugin.
  2. Go to Settings → Insert Headers and Footers.
  3. Paste the snippet below into the Scripts in Footer box and save:
<script
  src="https://unpkg.com/@arthurreira/[email protected]/dist/af-analytics.umd.js"
  data-api-key="proj_xxx"
  data-url="https://your-edge-worker.dev"
></script>

Replace proj_xxx with your project API key and https://your-edge-worker.dev with your Edge Worker URL. The script auto-tracks pageviews, clicks, scroll depth, and JS errors with no further configuration.


Quick start

Option A — <Analytics /> component (Next.js, recommended)

Add it once in your root layout. Automatically tracks pageviews, clicks, scroll-depth milestones (25 / 50 / 75 / 100 %), text copies, and uncaught JS errors.

// app/layout.tsx
import { Analytics } from '@arthurreira/analytics/client'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        {children}
        <Analytics
          apiUrl={process.env.NEXT_PUBLIC_ANALYTICS_URL!}
          apiKey={process.env.NEXT_PUBLIC_ANALYTICS_KEY!}
        />
      </body>
    </html>
  )
}

Option B — useAnalytics hook (custom events)

Use the hook when you need to fire custom events from your own components.

'use client'
import { useAnalytics } from '@arthurreira/analytics/client'

export function SearchBar() {
  const { trackSearch, trackCTA } = useAnalytics(
    process.env.NEXT_PUBLIC_ANALYTICS_URL!,
    process.env.NEXT_PUBLIC_ANALYTICS_KEY!,
  )

  return (
    <input
      onKeyDown={(e) => {
        if (e.key === 'Enter') trackSearch(e.currentTarget.value)
      }}
    />
  )
}

Option C — Vanilla JS script tag

Works with any HTML page or server-rendered site. Config is read from data-* attributes on the script tag itself.

<script
  src="/sdk/af-analytics.umd.js"
  data-api-key="proj_xxx"
  data-url="https://your-edge-worker.dev"
></script>

Auto-tracks the same events as the React component. No configuration code required. Call AfAnalytics.init() manually if you need to reinitialise after the script was loaded dynamically.


API reference

<Analytics /> props

| Prop | Type | Required | Description | | --- | --- | --- | --- | | apiUrl | string | yes | Base URL of your analytics backend (no trailing slash) | | apiKey | string | yes | Project API key | | wsUrl | string | no | WebSocket URL for real-time presence (default: wss://edge.arthurreira.dev/realtime) |

Auto-tracks: pageview, click, scroll (depth milestones), copy, error.


useAnalytics(apiUrl, apiKey, options?)

| Option | Type | Description | | --- | --- | --- | | options.wsUrl | string | Override the default presence WebSocket URL |

Events are queued internally until the session is ready — safe to call immediately on mount.

| Method | Signature | Description | | --- | --- | --- | | trackPageview | (path: string) => void | Manual pageview (SPA route changes) | | trackClick | (e: MouseEvent, element: HTMLElement) => void | Click with position + element metadata | | trackScroll | (depth: number) => void | Scroll depth percentage (0–100) | | trackCopy | () => void | Text copy event (captures selected text, up to 200 chars) | | trackError | (error: Error) => void | JS error with message + stack trace | | trackCTA | (ctaId: string, ctaVariant?: string) => void | CTA button interaction | | trackSearch | (query: string) => void | Search query |


Raw API helpers (server / build safe)

The default entry exports the low-level functions with no browser globals — safe to import in server components or Node.js scripts.

import {
  createSession,
  trackPageview,
  trackClick,
  trackScroll,
  trackCopy,
  trackError,
  trackCTA,
  trackSearch,
} from '@arthurreira/analytics'

All helpers take (apiUrl, apiKey, sessionId, ...) as their first arguments and call your backend directly via fetch.


Presence (real-time WebSocket)

Optional live-visitor presence tracking over WebSocket.

import { connectPresence, DEFAULT_WS_URL } from '@arthurreira/analytics'
import type { PresenceConnection } from '@arthurreira/analytics'

const conn: PresenceConnection = connectPresence(apiKey, sessionId, DEFAULT_WS_URL)

// later
conn.disconnect()

The connection retries up to 3 times with exponential back-off on unexpected close. When used via the <Analytics /> component or useAnalytics, presence connects automatically and disconnects on session end.


Package exports

| Import path | Format | Contents | Use in | | --- | --- | --- | --- | | @arthurreira/analytics | ESM | Raw API helpers + presence (no browser globals) | Server / Node | | @arthurreira/analytics/client | ESM | Analytics component + useAnalytics hook | React client | | dist/af-analytics.umd.js | IIFE | Self-contained auto-tracking script | Any HTML page |


Session management

  • A session is created on first load and stored in localStorage (af_session_id).
  • Sessions expire after 30 minutes of inactivity.
  • On tab hide (visibilitychange → hidden) or page unload (beforeunload) the SDK calls navigator.sendBeacon to close the session gracefully — no events are dropped.
  • Visitor identity persists across sessions via af_analytics_visitor_id (a random UUID in localStorage).

Data collected

On session start

| Field | Description | | --- | --- | | visitor_id | Persistent anonymous UUID | | language | navigator.language | | screen_width / height | Physical screen resolution | | viewport_width / height | Current browser viewport | | referrer | document.referrer | | landing_page | window.location.pathname | | timezone | IANA timezone string | | cpu_threads | navigator.hardwareConcurrency | | memory_gb | navigator.deviceMemory (Chrome only) | | gpu | WebGL unmasked renderer string | | network_type | effectiveType from Network Information API | | connection_speed_mbps | downlink from Network Information API | | utm_source/medium/campaign/term/content | UTM parameters from the landing URL |

On each event

session_id, event_type, path, page_url, plus event-specific fields:

| Event | Extra fields | | --- | --- | | pageview | page_title, referrer, scroll_depth: 0 | | click | x_position, y_position, element_id, element_class, element_text | | scroll | scroll_depth (25 / 50 / 75 / 100) | | copy | copied_text (up to 200 chars) | | error | error_message, stack_trace | | cta_click | cta_id, cta_variant | | search | search_query |


Environment variables (Next.js)

| Variable | Description | | --- | --- | | NEXT_PUBLIC_ANALYTICS_URL | Backend base URL, e.g. https://analytics.example.com | | NEXT_PUBLIC_ANALYTICS_KEY | Project API key |


Building locally

pnpm install
pnpm build

Outputs:

| File | Format | Entry | | --- | --- | --- | | dist/index.js + dist/index.d.ts | ESM | src/index.ts | | dist/client.js + dist/client.d.ts | ESM | src/client.ts | | dist/af-analytics.umd.js | IIFE/UMD | src/vanilla.ts |

Publishing

Tag a release after adding an NPM_TOKEN secret to the repository to trigger the CI publish workflow.


License

MIT