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

@lobehub/analytics

v1.6.0

Published

A modern, type-safe analytics library for tracking user events across multiple providers, built by LobeHub

Readme

A modern, type-safe analytics library for tracking user events across multiple providers, built by LobeHub

Changelog · Report Bug · Request Feature

TOC

✨ Features

  • 🎯 Type-safe - Full TypeScript support with predefined events
  • 🔌 Multi-provider - Built-in PostHog support, extensible for other providers
  • 🌐 Global Instance Management - Singleton pattern and named global instances
  • 📊 SPM Auto-Prefixing - Automatic Source Page Medium tracking with business prefixes
  • ⚛️ React integration - Enhanced Provider with auto-registration and hooks
  • 🎛️ Easy configuration - Simple setup with business context
  • 🪶 Lightweight - Minimal dependencies and optimized bundle size
  • 🔧 Developer-friendly - Comprehensive error handling and debugging
  • 🧪 Test-friendly - Built-in reset and cleanup functions

📦 Installation

To install @lobehub/analytics, run the following command:

npm install @lobehub/analytics

# Additional installation for server-side usage
npm install posthog-node # Server-side only

This library includes PostHog analytics provider out of the box. For React integration:

npm install react # if not already installed

⚠️ Client-side vs Server-side Usage

🌐 Client-side Usage (Browser Environment)

import { createAnalytics } from '@lobehub/analytics';

const analytics = createAnalytics({
  business: 'my-app',
  providers: {
    posthog: { enabled: true, key: 'client_key' },
  },
});

🖥️ Server-side Usage (Node.js Environment)

import { createServerAnalytics } from '@lobehub/analytics/server';

const analytics = createServerAnalytics({
  business: 'my-app',
  providers: {
    // ✅ Client-side PostHog (browser compatible)
    posthog: {
      enabled: true,
      key: 'phc_xxxxx',
      api_host: 'https://app.posthog.com',
    },
    // ✅ Server-side PostHog (Node.js only)
    posthogNode: {
      enabled: true,
      key: 'server_key',
      host: 'https://app.posthog.com',
    },
  },
});

🔥 Separation Solution: Clear entry point separation ensures posthogNode is completely excluded from client-side builds!

Import Structure

The library provides separate entry points for client-side, server-side, and React integration:

// Client-side analytics (browser safe)
import { AnalyticsManager, createAnalytics } from '@lobehub/analytics';
// Global instance management
import {
  createSingletonAnalytics,
  getGlobalAnalytics,
  getSingletonAnalytics,
} from '@lobehub/analytics';
// React hooks (separate import)
import {
  AnalyticsProvider,
  useAnalytics,
  useAnalyticsStrict,
  useEventTracking,
} from '@lobehub/analytics/react';
// Server-side analytics (includes posthog-node)
import { PostHogNodeAnalyticsProvider, createServerAnalytics } from '@lobehub/analytics/server';

🚀 Quick Start

Basic Usage

import { createAnalytics } from '@lobehub/analytics';

// Configure analytics with business context
const analytics = createAnalytics({
  business: 'my-app', // Required: business name for SPM prefixing
  debug: process.env.NODE_ENV === 'development',
  providers: {
    posthog: {
      enabled: !!process.env.POSTHOG_KEY,
      key: process.env.POSTHOG_KEY!,
      host: process.env.POSTHOG_HOST, // optional
    },
  },
});

// Initialize
await analytics.initialize();

// Track events with automatic SPM prefixing
await analytics.trackEvent('user_signup', {
  method: 'email',
  source: 'landing_page',
  spm: 'homepage.cta', // Will become: 'my-app.homepage.cta'
});

// Identify users
await analytics.identify('user_123', {
  email: '[email protected]',
  plan: 'pro',
});

Global Instance Management

Singleton Pattern (Recommended for simple apps):

import { createSingletonAnalytics, getSingletonAnalytics } from '@lobehub/analytics';

// Create singleton (usually in app initialization)
const analytics = createSingletonAnalytics({
  business: 'my-app',
  providers: {
    posthog: {
      enabled: true,
      key: process.env.POSTHOG_KEY!,
    },
  },
});

await analytics.initialize();

// Access from anywhere in your application
export function trackUserAction() {
  const analytics = getSingletonAnalytics();
  analytics.trackEvent('button_click', {
    button_name: 'signup',
    page: 'home',
  });
}

Named Global Instances (For complex apps):

import { getGlobalAnalytics, setGlobalAnalytics } from '@lobehub/analytics';

// Register multiple instances
setGlobalAnalytics(mainAnalytics, 'main');
setGlobalAnalytics(adminAnalytics, 'admin');

// Use specific instances
getGlobalAnalytics('main').trackEvent('user_action', {});
getGlobalAnalytics('admin').trackEvent('admin_action', {});

React Integration

Enhanced AnalyticsProvider with auto-registration:

import React from 'react';
import { createAnalytics } from '@lobehub/analytics';
import {
  AnalyticsProvider,
  useAnalytics,
  useAnalyticsStrict
} from '@lobehub/analytics/react';

// Create analytics instance
const analytics = createAnalytics({
  business: 'my-app',
  providers: {
    posthog: {
      enabled: true,
      key: process.env.REACT_APP_POSTHOG_KEY!,
    },
  },
});

// Provider with auto-registration
function App() {
  return (
    <AnalyticsProvider
      client={analytics}
      autoInitialize={true}      // Auto-initialize on mount
      registerGlobal={true}      // Auto-register as global instance
      globalName="main"          // Optional: custom global name
    >
      <MyComponent />
    </AnalyticsProvider>
  );
}

// Use in components
function MyComponent() {
  const { analytics, isReady, isInitializing, error } = useAnalytics();

  // Safe usage with state checking
  if (isInitializing) return <div>Loading analytics...</div>;
  if (error) return <div>Analytics error: {error.message}</div>;
  if (!isReady) return <div>Analytics not ready</div>;

  const handleClick = () => {
    analytics?.trackEvent('button_click', {
      button_name: 'cta',
      page: 'home',
    });
  };

  return <button onClick={handleClick}>Track Event</button>;
}

// Strict mode (throws if not initialized)
function StrictComponent() {
  const analytics = useAnalyticsStrict(); // Throws if not ready

  const handleClick = () => {
    analytics.trackEvent('button_click', { button_name: 'strict-button' });
  };

  return <button onClick={handleClick}>Strict Track</button>;
}

Access analytics outside React components:

import { getGlobalAnalytics } from '@lobehub/analytics/react';

// In service functions, API handlers, etc.
export async function apiCall() {
  try {
    const response = await fetch('/api/data');

    // Track success
    const analytics = getGlobalAnalytics('main');
    analytics.trackEvent('api_call', {
      endpoint: '/api/data',
      success: true,
    });

    return response.json();
  } catch (error) {
    // Track error
    const analytics = getGlobalAnalytics('main');
    analytics.trackEvent('api_call', {
      endpoint: '/api/data',
      success: false,
      error: error.message,
    });
    throw error;
  }
}

SPM (Source Page Medium) Auto-Prefixing

The library automatically handles SPM prefixing with your business name:

const analytics = createAnalytics({
  business: 'my-app', // This will prefix all SPM values
  // ... other config
});

// These events will have SPM auto-prefixed:
analytics.trackEvent('button_click', {
  button_name: 'signup',
  spm: 'homepage.hero', // Becomes: 'my-app.homepage.hero'
});

analytics.trackEvent('page_view', {
  page: '/dashboard',
  spm: 'dashboard.main', // Becomes: 'my-app.dashboard.main'
});

// If no SPM provided, uses business name as default
analytics.trackEvent('user_login', {
  method: 'email',
  // spm will be: 'my-app'
});

📖 API Reference

Core Functions

createAnalytics(config: AnalyticsConfig): AnalyticsManager

Creates a configured analytics manager.

AnalyticsManager

Main class for managing analytics providers.

Methods:

  • initialize(): Promise<void> - Initialize all providers
  • track(event: AnalyticsEvent): Promise<void> - Track custom event
  • trackEvent<K>(eventName: K, properties): Promise<void> - Track predefined event
  • identify(userId: string, properties?): Promise<void> - Identify user
  • trackPageView(page: string, properties?): Promise<void> - Track page view
  • reset(): Promise<void> - Reset user identity
  • setGlobalContext(context: EventContext): this - Set global context
  • getStatus(): { initialized: boolean; providersCount: number } - Get status

Global Instance Management

Singleton Pattern

// Create singleton
createSingletonAnalytics(config: AnalyticsConfig): AnalyticsManager

// Get singleton
getSingletonAnalytics(): AnalyticsManager
getSingletonAnalyticsOptional(): AnalyticsManager | null

// Check singleton
hasSingletonAnalytics(): boolean
resetSingletonAnalytics(): void // For testing

Named Global Instances

// Register/unregister
setGlobalAnalytics(instance: AnalyticsManager, name?: string): void
removeGlobalAnalytics(name?: string): boolean
clearGlobalAnalytics(): void

// Access
getGlobalAnalytics(name?: string): AnalyticsManager
getGlobalAnalyticsOptional(name?: string): AnalyticsManager | null

// Utilities
hasGlobalAnalytics(name?: string): boolean
getGlobalAnalyticsNames(): string[]

React Hooks & Provider

AnalyticsProvider

<AnalyticsProvider
  client={AnalyticsManager}
  autoInitialize?: boolean      // Default: true
  registerGlobal?: boolean      // Default: true
  globalName?: string           // Default: '__default__'
>
  {children}
</AnalyticsProvider>

React Hooks

// Safe access with state
useAnalytics(): {
  analytics: AnalyticsManager | null;
  isReady: boolean;
  isInitialized: boolean;
  isInitializing: boolean;
  error: Error | null;
}

// Strict access (throws if not ready)
useAnalyticsStrict(): AnalyticsManager

// State only
useAnalyticsState(): {
  isReady: boolean;
  isInitialized: boolean;
  isInitializing: boolean;
  error: Error | null;
}

// Optional access
useAnalyticsOptional(): AnalyticsManager | null

// Legacy hook (for backward compatibility)
useEventTracking(manager: AnalyticsManager): {
  trackButtonClick: (buttonName: string, properties?: any) => void;
  // ... other convenience methods
}

Types

AnalyticsConfig

interface AnalyticsConfig {
  business: string; // Required: business name for SPM prefixing
  debug?: boolean;
  providers: {
    posthog?: PostHogProviderAnalyticsConfig;
    umami?: UmamiProviderAnalyticsConfig;
    ga?: GoogleProviderAnalyticsConfig;
  };
}

PostHogProviderAnalyticsConfig

interface PostHogProviderAnalyticsConfig {
  enabled: boolean;
  key: string;
  host?: string;
  debug?: boolean;
  // ... other PostHog config options
}

PredefinedEvents

interface PredefinedEvents {
  // UI interactions
  button_click: {
    button_name: string;
    page?: string;
    section?: string;
    spm?: string;
    [key: string]: any;
  };

  // User actions
  user_signup: {
    method: 'email' | 'oauth' | 'phone';
    source?: string;
    spm?: string;
    [key: string]: any;
  };

  user_login: {
    method: 'email' | 'oauth' | 'phone';
    spm?: string;
    [key: string]: any;
  };

  // Chat interactions
  chat_message_sent: {
    message_length: number;
    model?: string;
    conversation_id?: string;
    spm?: string;
    [key: string]: any;
  };

  // Page tracking
  page_view: {
    page: string;
    referrer?: string;
    spm?: string;
    [key: string]: any;
  };

  // Form interactions
  form_submit: {
    form_name: string;
    success: boolean;
    spm?: string;
    [key: string]: any;
  };
}

🛠️ Development

# Clone the repository
git clone https://github.com/lobehub/@lobehub/analytics.git
cd @lobehub/analytics

# Install dependencies
npm install

# Start development
npm run dev

# Build the library
npm run build

# Run tests
npm test

# Run examples
npm run example

Project Structure

@lobehub/analytics/
├── src/
│   ├── base.ts           # Base analytics provider
│   ├── manager.ts        # Analytics manager
│   ├── config.ts         # Configuration factory
│   ├── global.ts         # Global instance management
│   ├── types.ts          # TypeScript definitions
│   ├── providers/        # Analytics providers
│   │   └── posthog.ts    # PostHog implementation
│   ├── react/            # React integration
│   │   ├── provider.tsx  # Enhanced Provider component
│   │   └── hooks.ts      # Legacy hooks
│   └── index.ts          # Main exports
├── examples/             # Usage examples
└── dist/                 # Built files (generated)

Examples

See the examples/ directory for comprehensive usage examples:

  • examples/library-usage.ts - Basic library usage and design principles
  • examples/enhanced-react-usage.tsx - Advanced React integration
  • examples/singleton-enhanced-usage.ts - Singleton pattern examples
  • examples/global-usage.ts - Global instance management
  • examples/business-spm-example.ts - SPM prefixing demonstration
  • examples/usage-summary.md - Complete feature overview

🤝 Contributing

Contributions of all types are more than welcome, if you are interested in contributing code, feel free to check out our GitHub Issues to get stuck in to show us what you're made of.


📝 License

Copyright © 2025 LobeHub. This project is MIT licensed.