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

opentrack-analytics

v1.2.0

Published

A Segment-compatible client-side analytics library for OpenTrack. Drop-in replacement for Analytics.js with TypeScript support.

Downloads

344

Readme

OpenTrack Analytics

A Segment-compatible client-side analytics library for OpenTrack. This library provides the same interface as Segment's Analytics.js but sends data to your own OpenTrack instance.

Features

  • Segment-Compatible API: Drop-in replacement for Segment's Analytics.js
  • Universal Support: Works in browser, Node.js, and SSR environments (Next.js, Astro, etc.)
  • Multiple Build Formats: ESM, CommonJS, UMD, and IIFE builds included
  • TypeScript Support: Full TypeScript definitions included
  • Browser Beacon API: Uses navigator.sendBeacon() for reliable event delivery
  • Automatic Identity Management: Persists user identity across sessions using localStorage
  • Manual Page Tracking: Call analytics.page() explicitly to track page views
  • Event Queuing: Automatic batching and flushing of events
  • Modular Architecture: Clean separation of concerns with utility modules
  • Configurable Storage: Customizable localStorage keys and prefixes
  • Cryptographically Secure: Uses crypto.getRandomValues() for secure ID generation
  • Lightweight: ~6KB minified and gzipped

Installation

npm install opentrack-analytics
# or
yarn add opentrack-analytics
# or
pnpm add opentrack-analytics

Usage

Framework-Specific Setup

Next.js (App Router)

// app/lib/analytics.ts
import analytics from 'opentrack-analytics'

analytics.load('your-write-key', {
  host: 'https://your-opentrack-instance.com',
  debug: process.env.NODE_ENV === 'development',
})

export default analytics

// app/components/Analytics.tsx
'use client'
import { useEffect } from 'react'
import analytics from '../lib/analytics'

export default function Analytics() {
  useEffect(() => {
    // Track page view
    analytics.page()
  }, [])

  return null
}

// app/layout.tsx
import Analytics from './components/Analytics'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  )
}

Next.js (Pages Router)

// lib/analytics.ts
import analytics from 'opentrack-analytics'

analytics.load('your-write-key', {
  host: 'https://your-opentrack-instance.com',
  debug: process.env.NODE_ENV === 'development',
})

export default analytics

// pages/_app.tsx
import type { AppProps } from 'next/app'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import analytics from '../lib/analytics'

export default function App({ Component, pageProps }: AppProps) {
  const router = useRouter()

  useEffect(() => {
    const handleRouteChange = (url: string) => {
      analytics.page()
    }

    router.events.on('routeChangeComplete', handleRouteChange)
    return () => router.events.off('routeChangeComplete', handleRouteChange)
  }, [router.events])

  return <Component {...pageProps} />
}

Astro

---
// src/components/Analytics.astro
---
<script>
  import analytics from 'opentrack-analytics'

  analytics.load('your-write-key', {
    host: 'https://your-opentrack-instance.com',
    debug: import.meta.env.DEV,
  })

  // Track page view
  analytics.page()
</script>

<!-- layouts/Layout.astro -->
---
import Analytics from '../components/Analytics.astro'
---
<html lang="en">
  <head>
    <!-- head content -->
  </head>
  <body>
    <slot />
    <Analytics />
  </body>
</html>

SvelteKit

// src/lib/analytics.ts
import analytics from 'opentrack-analytics'

analytics.load('your-write-key', {
  host: 'https://your-opentrack-instance.com',
  debug: import.meta.env.DEV,
})

export default analytics

// src/app.html
<script>
  import { page } from '$app/stores'
  import { onMount } from 'svelte'
  import analytics from '$lib/analytics'

  onMount(() => {
    analytics.page()
  })

  // Track route changes
  $: if ($page.url) {
    analytics.page()
  }
</script>

Vue.js / Nuxt.js

// plugins/analytics.client.ts (Nuxt 3)
import analytics from 'opentrack-analytics'

export default defineNuxtPlugin(() => {
  analytics.load('your-write-key', {
    host: 'https://your-opentrack-instance.com',
    debug: process.dev,
  })

  // Track initial page
  analytics.page()

  return {
    provide: {
      analytics,
    },
  }
})

// composables/useAnalytics.ts
export const useAnalytics = () => {
  const { $analytics } = useNuxtApp()
  return $analytics
}

Server-Safe Usage

For server-side rendering, you can use the server-safe import:

// This won't break in SSR environments
import analytics from 'opentrack-analytics/server'

// Or conditionally import
const analytics = process.browser ? await import('opentrack-analytics') : await import('opentrack-analytics/server')

Direct Browser Usage (Script Tag)

<!DOCTYPE html>
<html>
  <head>
    <title>My App</title>
  </head>
  <body>
    <!-- Load the analytics library -->
    <script src="https://unpkg.com/[email protected]/dist/analytics.iife.js"></script>

    <script>
      // Initialize with your OpenTrack instance
      analytics.load('your-write-key', {
        host: 'https://your-opentrack-instance.com',
        debug: false,
      })
    </script>
  </body>
</html>

API Methods

Track Events

analytics.track('Button Clicked', {
  buttonText: 'Get Started',
  location: 'homepage',
})

Identify Users

analytics.identify('user-123', {
  email: '[email protected]',
  firstName: 'John',
  lastName: 'Doe',
  plan: 'premium',
})

Track Page Views

// Auto-capture page properties
analytics.page()

// Named page with category
analytics.page('Marketing', 'Landing Page', {
  campaign: 'spring-sale',
})

Group Users

analytics.group('company-456', {
  name: 'Acme Corp',
  industry: 'Technology',
  employees: 100,
})

Alias Users

analytics.alias('user-123', 'anonymous-456')

Configuration Options

analytics.load('your-write-key', {
  host: 'https://your-opentrack-instance.com', // Your OpenTrack endpoint
  flushAt: 20, // Flush when queue reaches this size
  flushInterval: 10000, // Flush interval in milliseconds
  debug: false, // Enable debug logging

  // Storage configuration
  storagePrefix: 'analytics_', // Prefix for localStorage keys
  userIdKey: 'analytics_user_id', // Custom key for user ID storage
  anonymousIdKey: 'analytics_anonymous_id', // Custom key for anonymous ID storage
  traitsKey: 'analytics_traits', // Custom key for traits storage
})

Configuration Reference

| Option | Type | Default | Description | | ---------------- | ------- | -------------------------- | ---------------------------------------------- | | host | string | '/' | Your OpenTrack instance URL | | writeKey | string | '' | Write key for authentication | | flushAt | number | 20 | Number of events to queue before auto-flushing | | flushInterval | number | 10000 | Time in milliseconds between auto-flushes | | debug | boolean | false | Enable console logging for debugging | | storagePrefix | string | 'analytics_' | Prefix for localStorage keys | | userIdKey | string | 'analytics_user_id' | localStorage key for user ID | | anonymousIdKey | string | 'analytics_anonymous_id' | localStorage key for anonymous ID | | traitsKey | string | 'analytics_traits' | localStorage key for user traits |

Note: If you provide a custom storagePrefix, the individual key names will be automatically updated unless explicitly overridden.

Utility Methods

// Get current user information
const user = analytics.user()
console.log(user.id()) // Current user ID
console.log(user.anonymousId()) // Anonymous ID
console.log(user.traits()) // User traits

// Reset user identity
analytics.reset()

// Manually flush events
analytics.flush()

// Wait for library to be ready
analytics.ready(() => {
  console.log('Analytics ready!')
})

Package Entry Points

This package provides multiple entry points for different use cases:

Main Entry Point

import analytics from 'opentrack-analytics'
// Uses the browser implementation when available, falls back to server-safe version

Browser-Specific Entry Point

import analytics from 'opentrack-analytics/browser'
// Always uses the full browser implementation

Server-Safe Entry Point

import analytics from 'opentrack-analytics/server'
// No-op implementation safe for server-side rendering

Build Outputs

The package includes multiple build formats:

  • ESM (*.esm.js): For modern bundlers and ES module environments
  • CommonJS (*.cjs.js): For Node.js and older bundlers
  • UMD (analytics.umd.js): Universal module definition for browser usage
  • IIFE (analytics.iife.js): For direct script tag usage, exposes OpenTrackAnalytics global

All builds include:

  • Source maps for debugging
  • Minification for production
  • TypeScript declaration files (.d.ts)

Demo

Open demo.html in your browser to see the library in action. The demo shows all available methods and includes debug output.

Integration with OpenTrack

This library sends events to the following OpenTrack endpoints:

  • POST /v1/track - For track events
  • POST /v1/identify - For identify events
  • POST /v1/page - For page events
  • POST /v1/group - For group events
  • POST /v1/alias - For alias events

All payloads are fully compatible with Segment's API specification.

Architecture

The library is built with a modular architecture for maintainability and extensibility:

src/
├── analytics.ts          # Main Analytics class
├── types.ts              # TypeScript interface definitions
├── config.ts             # Configuration management
└── utils/
    ├── id-generator.ts   # UUID and message ID generation
    ├── storage.ts        # localStorage abstraction
    ├── context.ts        # Browser context building
    ├── transport.ts      # HTTP transport layer
    └── index.ts          # Utility exports

Key Components

  • Analytics Class: Main API interface and event management
  • Storage Module: Handles all localStorage operations with configurable keys
  • Transport Module: Manages HTTP requests with beacon API and fetch fallback
  • Context Builder: Automatically captures browser and page information
  • ID Generator: Cryptographically secure UUID generation with Math.random fallback
  • Configuration: Centralized config management with intelligent defaults

Development

Local Development

# Install dependencies
pnpm install

# Build all formats
pnpm build

# Start development server (for testing)
pnpm dev

Publishing

The package is ready for npm publication with:

  • Proper package.json configuration with exports map
  • Multiple build formats (ESM, CJS, UMD, IIFE)
  • TypeScript declarations
  • Server-safe implementations
  • Framework compatibility
# Build for production
pnpm build

# Publish to npm
npm publish

Framework Compatibility

Next.js (App Router & Pages Router)
Astro
SvelteKit
Nuxt.js
Vue.js
React (Create React App, Vite)
Angular
Vanilla JavaScript
Server-Side Rendering (SSR)
Static Site Generation (SSG)

License

MIT License - see LICENSE file for details.