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

@yourownmetric/sdk

v0.1.3

Published

Your Own Metric — Privacy-first analytics SDK

Readme

@yourownmetric/sdk

Privacy-first, lightweight analytics SDK for web and Node.js applications.

~4 KB gzipped · Zero dependencies · Tree-shakeable · TypeScript-first

Don't have an account yet? Sign up free at Your Own Metrics →


Table of Contents


Install

npm install @yourownmetric/sdk

Get your API key from the YOM Dashboard → API Keys.


Quick Start — JavaScript

import { YOM } from '@yourownmetric/sdk'

YOM.init({
    apiKey: 'yom_pk_...', // From your YOM dashboard → API Keys
    ingestUrl: 'https://ingest.yourownmetrics.aapastech.com',
    autoCapture: {
        pageviews: true, // SPA-aware — handles pushState + popstate
        errors: true, // Uncaught errors & unhandled rejections
        clicks: true, // Outbound links, downloads, data-yom-track elements
        performance: true, // Core Web Vitals (LCP, CLS, INP, FCP, TTFB)
    },
    privacy: {
        respectDNT: true, // Honor Do-Not-Track / Global Privacy Control
        cookieless: false,
    },
    debug: false, // Set true during development
})

// That's it! Pageviews, errors, clicks, and Core Web Vitals are tracked automatically.

Track Custom Events

// Fire-and-forget — events are batched automatically
YOM.track('signup_completed', { plan: 'pro', source: 'landing_page' })

// Track with revenue
YOM.track('purchase', { item: 'Premium Plan' }, { revenue: 49.99, currency: 'USD' })

Identify Users

// Call after user login to link anonymous sessions to authenticated users
YOM.identify('user_abc123', {
    name: 'Jane Doe',
    email: '[email protected]',
    plan: 'pro',
})

Lifecycle

// Flush pending events (e.g. before navigation)
await YOM.flush()

// Tear down the SDK (cleanup listeners, flush, stop timers)
await YOM.destroy()

Quick Start — React

import { YOMProvider, PageTracker } from '@yourownmetric/sdk/react'
import { BrowserRouter, Routes, Route } from 'react-router-dom'

const yomConfig = {
    apiKey: 'yom_pk_...',
    ingestUrl: 'https://ingest.yourownmetrics.aapastech.com',
    autoCapture: {
        pageviews: true,
        errors: true,
        clicks: true,
        performance: true,
    },
    privacy: { respectDNT: true },
}

function App() {
    return (
        <YOMProvider config={yomConfig}>
            <BrowserRouter>
                <PageTracker />
                <Routes>{/* your routes */}</Routes>
            </BrowserRouter>
        </YOMProvider>
    )
}

Using Hooks

import { useTrack, useIdentify } from '@yourownmetric/sdk/react'

function CheckoutButton() {
    const track = useTrack()
    const identify = useIdentify()

    const handlePurchase = () => {
        track('purchase', { item: 'Pro Plan' }, { revenue: 49.99, currency: 'USD' })
    }

    const handleLogin = user => {
        identify(user.id, { name: user.name, email: user.email })
    }

    return <button onClick={handlePurchase}>Buy Now</button>
}

React Hooks

| Hook | Description | | -------------------- | -------------------------------------------- | | useTrack() | Returns track(name, properties?, options?) | | useIdentify() | Returns identify(userId, traits?) | | usePageView(path?) | Tracks a pageview on mount / path change |

React Components

| Component | Description | | ---------------------------- | -------------------------------------------------------- | | <YOMProvider config={...}> | Context provider — initializes SDK, cleans up on unmount | | <PageTracker /> | Drop-in — tracks pageviews on every route change |


Quick Start — Node.js

import { YOMNode } from '@yourownmetric/sdk/node'

const yom = new YOMNode({
    apiKey: 'yom_pk_...',
    ingestUrl: 'https://ingest.yourownmetrics.aapastech.com',
    flushIntervalMs: 10_000, // Flush every 10s (default: 5s)
    batchSize: 50, // Flush after 50 events (default: 20)
    maxRetries: 3,
})

// Track server-side events
yom.track('api_request', {
    endpoint: '/api/users',
    method: 'GET',
    statusCode: 200,
    durationMs: 45,
})

// Identify users from your backend
yom.identify('user_abc123', {
    name: 'Jane Doe',
    email: '[email protected]',
})

// IMPORTANT: Flush before process exit
process.on('SIGTERM', async () => {
    await yom.flush()
    process.exit(0)
})

Important:

  • Always flush before exit — the Node client buffers events in memory.
  • Create one YOMNode instance per process and import it where needed.
  • Import from @yourownmetric/sdk/node, not the default entry (which is browser-only).

CDN (No Build Step)

<!-- Add this before </head> — no build step required -->
<script type="module">
    import { YOM } from 'https://cdn.yourownmetrics.aapastech.com/sdk/latest/index.js'

    YOM.init({
        apiKey: 'yom_pk_...',
        ingestUrl: 'https://ingest.yourownmetrics.aapastech.com',
        autoCapture: {
            pageviews: true,
            errors: true,
            clicks: true,
            performance: true,
        },
    })
</script>

HTML Data Attributes

Track clicks without writing any JavaScript:

<!-- Auto-tracked by the clicks plugin -->
<button data-yom-track="cta_hero" data-yom-variant="blue">Get Started Free</button>

<!-- The click plugin reads data-yom-* attributes as event properties -->
<!-- Above will fire: { name: "cta_hero", variant: "blue", tagName: "button" } -->

Environment Variables

Keep your API key out of source code:

# .env or .env.local
VITE_YOM_API_KEY=yom_pk_...
VITE_YOM_INGEST_URL=https://ingest.yourownmetrics.aapastech.com
YOM.init({
    apiKey: import.meta.env.VITE_YOM_API_KEY,
    ingestUrl: import.meta.env.VITE_YOM_INGEST_URL,
    // ...
})

Integrating into an Existing Analytics Layer

If you already have a centralized dispatch for GA4, Facebook Pixel, Mixpanel, etc., add YOM alongside it with a single line:

import { YOM } from '@yourownmetric/sdk'

// 1. Initialize once at app boot
YOM.init({
    apiKey: 'yom_pk_...',
    ingestUrl: 'https://ingest.yourownmetrics.aapastech.com',
    autoCapture: { pageviews: true, errors: true, clicks: true, performance: true },
})

// 2. In your existing analytics utility / dispatch hub:
export function sendAnalyticsEvent(name: string, params: Record<string, unknown>) {
    // Existing services
    ga4.sendEvent(name, params)
    fbPixel.trackCustom(name, params)

    // Add YOM — one extra line:
    YOM.track(name, params)
}

Auto-Captured Events

When autoCapture flags are enabled, the SDK tracks these events out-of-the-box — zero code required:

| Event | Flag | Description | | ---------- | ------------------- | ------------------------------------------------------------------ | | Pageviews | pageviews: true | Every navigation, SPA-aware (pushState + popstate) | | Errors | errors: true | Uncaught errors & unhandled promise rejections | | Clicks | clicks: true | Outbound links, file downloads, buttons, data-yom-track elements | | Web Vitals | performance: true | LCP, CLS, FID/INP, FCP, TTFB — rated per Google thresholds | | Sessions | always on | session_start / session_end with 30-min idle timeout | | UTM Params | always on | Parsed from URL query string (utm_source, utm_medium, etc.) |


Configuration Reference

interface YOMConfig {
    apiKey: string // Required — your public API key
    ingestUrl?: string // Ingestion endpoint URL
    autoCapture?: {
        pageviews?: boolean // Default: false
        errors?: boolean // Default: false
        clicks?: boolean // Default: false
        performance?: boolean // Default: false
    }
    privacy?: {
        respectDNT?: boolean // Honor Do-Not-Track / GPC (default: false)
        cookieless?: boolean // No localStorage anonymous IDs (default: false)
    }
    batchSize?: number // Events before flush (default: 20, max: 100)
    flushIntervalMs?: number // Auto-flush interval (default: 5000)
    maxRetries?: number // Transport retries (default: 3)
    debug?: boolean // Console logging (default: false)
}

API Reference

Browser (@yourownmetric/sdk)

| Method | Description | | -------------------------------- | ------------------------------- | | YOM.init(config) | Initialize the SDK (idempotent) | | YOM.track(name, props?, opts?) | Track a custom event | | YOM.page(path?, opts?) | Track a pageview | | YOM.identify(userId, traits?) | Identify a user | | YOM.flush() | Send all queued events | | YOM.destroy() | Flush + cleanup listeners |

React (@yourownmetric/sdk/react)

| Export | Description | | ---------------------------- | ------------------------------------------------ | | <YOMProvider config={...}> | Context provider — init SDK, teardown on unmount | | <PageTracker /> | Tracks pageviews on every route change | | useTrack() | Returns track(name, properties?, options?) | | useIdentify() | Returns identify(userId, traits?) | | usePageView(path?) | Tracks pageview on mount / path change |

Node.js (@yourownmetric/sdk/node)

| Method | Description | | ------------------------------- | ------------------------- | | new YOMNode(config) | Create server-side client | | yom.track(name, props?) | Track an event | | yom.identify(userId, traits?) | Identify a user | | yom.flush() | Send all queued events | | yom.destroy() | Flush + stop timer |


Embed Widget

Display analytics data on any webpage using the <yom-dashboard> Web Component:

<script type="module" src="https://cdn.yourownmetrics.aapastech.com/embed/latest/index.js"></script>

<yom-dashboard
    token="YOUR_EMBED_TOKEN"
    dashboard-id="YOUR_DASHBOARD_ID"
    api-url="https://api.yourownmetrics.aapastech.com/v1"
    theme="auto"
></yom-dashboard>

| Attribute | Required | Description | | -------------- | -------- | ------------------------------------------------------------- | | token | Yes | Embed token (create in Settings → API Keys with "read" scope) | | dashboard-id | Yes | The ID of the dashboard to display | | api-url | No | API base URL (defaults to production) | | theme | No | "light", "dark", or "auto" (follows system preference) |


Privacy & Compliance

  • Do-Not-Track / GPC: When privacy.respectDNT: true, the SDK checks navigator.doNotTrack and navigator.globalPrivacyControl. If either is enabled, tracking is disabled entirely.
  • Cookieless mode: Set privacy.cookieless: true to disable localStorage-based anonymous IDs. Each page load gets a fresh random ID.
  • No PII by default: The SDK never captures form inputs, passwords, or personal data. User identification is opt-in via YOM.identify().

Batching & Delivery

  • Events are buffered in memory and sent in batches. Default: batch of 20 or every 5 seconds, whichever comes first.
  • On page close (visibilitychange → hidden), remaining events are sent via navigator.sendBeacon() for reliable delivery.
  • Failed requests retry with exponential backoff (up to 3 retries). Permanently failed events (4xx except 429) are dropped.

Troubleshooting

Events not showing up in the dashboard? Enable debug: true in your config. Check the browser console for [YOM] messages. Verify your API key is correct and not revoked.

CORS errors? The ingest endpoint accepts requests from any origin. If you're using a custom domain, make sure it matches your project's configured domain.

Events seem delayed? Events are batched (default: 20 events or 5s). In development, reduce flushIntervalMs to 1000 for faster feedback.

Duplicate pageviews in SPA? If you have autoCapture.pageviews enabled AND you're manually calling YOM.page(), you'll get duplicates. Choose one approach.


Links


License

MIT © AapasTech Private Limited