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

@rachelallyson/stratum-posthog-js

v1.0.8

Published

A PostHog plugin for Stratum Observability that enables seamless integration between your application's observability events and PostHog analytics.

Downloads

39

Readme

Stratum PostHog Plugin

A PostHog plugin for Stratum Observability that enables seamless integration between your application's observability events and PostHog analytics.

Features

  • Event Publishing: Send Stratum events to PostHog with full type safety
  • User Identification Event Types: Handle user identification through flexible event types
  • Flexible Event Naming: Name your events anything you want while using PostHog identification
  • Browser Support: Full browser integration with PostHog JS SDK
  • Type Safety: Complete TypeScript support with generics
  • Flexible Configuration: Support for both configuration-based and pre-initialized PostHog instances
  • Stratum Integration: Properly registered event types with Stratum framework

Installation

npm install @rachelallyson/stratum-posthog-js

Quick Start

1. Basic Setup

import { PosthogService, PosthogPlugin, PosthogEventTypes } from '@rachelallyson/stratum-posthog-js';

// Define your event catalog using Stratum's standard pattern
const catalog = {
  BUTTON_CLICK: {
    id: "BUTTON_CLICK",
    description: "User clicked a button",
    eventType: PosthogEventTypes.CAPTURE,
    properties: {
      button_name: "string",
      page: "string",
    },
  },
  USER_LOGIN: {
    id: "USER_LOGIN",
    description: "User logged in",
    eventType: PosthogEventTypes.CAPTURE,
    properties: {
      login_method: "string",
      user_id: "string",
    },
  },
  // User identification events - name them anything you want!
  USER_SIGNED_IN: {
    id: "USER_SIGNED_IN",
    description: "User signed in and identified with PostHog",
    eventType: PosthogEventTypes.IDENTIFY,
    properties: {
      distinct_id: "string",
      person_properties: "object",
      anonymous_id: "string",
    },
  },
  USER_SIGNED_OUT: {
    id: "USER_SIGNED_OUT",
    description: "User signed out and reset PostHog",
    eventType: PosthogEventTypes.RESET,
    properties: {
      previous_distinct_id: "string",
      reset_device_id: "string",
    },
  },
  USER_LINKED: {
    id: "USER_LINKED",
    description: "User linked with another ID",
    eventType: PosthogEventTypes.ALIAS,
    properties: {
      distinct_id: "string",
      alias: "string",
    },
  },
  // Alternative naming examples
  CUSTOMER_ONBOARDED: {
    id: "CUSTOMER_ONBOARDED",
    description: "Customer completed onboarding",
    eventType: PosthogEventTypes.IDENTIFY,
    properties: {
      distinct_id: "string",
      person_properties: "object",
      anonymous_id: "string",
    },
  },
  SESSION_ENDED: {
    id: "SESSION_ENDED",
    description: "User session ended",
    eventType: PosthogEventTypes.RESET,
    properties: {
      previous_distinct_id: "string",
      reset_device_id: "string",
    },
  },
  ACCOUNT_MERGED: {
    id: "ACCOUNT_MERGED",
    description: "User accounts merged",
    eventType: PosthogEventTypes.ALIAS,
    properties: {
      distinct_id: "string",
      alias: "string",
    },
  },
};

// Create the service
const service = new PosthogService({
  catalog: { items: catalog },
  plugins: [
    PosthogPlugin({
      POSTHOG_KEY: "your-posthog-key",
      config: {
        api_host: "https://your-posthog-host.com",
        autocapture: true,
      },
    }),
  ],
  productName: "my-app",
  productVersion: "1.0.0",
});

2. Publishing Events

// Publish a regular event with properties
await service.publish("BUTTON_CLICK", {
  pluginData: {
    PosthogPlugin: {
      properties: {
        button_name: "submit",
        page: "checkout",
      },
    },
  },
});

// Publish a simple event without properties
await service.publish("PAGE_VIEW", {
  pluginData: {
    PosthogPlugin: {
      properties: {},
    },
  },
});

// Or even simpler - the plugin will work with empty properties
await service.publish("PAGE_VIEW", {
  pluginData: {
    PosthogPlugin: {},
  },
});

User Identification (Event Types)

Following Stratum's principle that "Events are first-class citizens," user identification is handled through event types rather than specific event names. This gives you complete flexibility in naming your events!

Available Event Types

  • PosthogEventTypes.IDENTIFY - Calls PostHog's identify() method
  • PosthogEventTypes.RESET - Calls PostHog's reset() method
  • PosthogEventTypes.ALIAS - Calls PostHog's alias() method

Identifying Users

When a user logs in, publish an event with the IDENTIFY event type:

// Get the current anonymous ID before identification
const anonymousId = service.getDistinctId();

// Identify the user using any event name you want!
await service.publish("USER_SIGNED_IN", {
  pluginData: {
    PosthogPlugin: {
      properties: {
        distinct_id: "user123",
        person_properties: {
          email: "[email protected]",
          name: "John Doe",
          subscription_tier: "premium",
          first_login_at: new Date().toISOString(),
        },
        anonymous_id: anonymousId || "",
      },
    },
  },
});

// Or use a different event name
await service.publish("CUSTOMER_ONBOARDED", {
  pluginData: {
    PosthogPlugin: {
      properties: {
        distinct_id: "user123",
        person_properties: {
          email: "[email protected]",
          onboarding_step: "completed",
        },
        anonymous_id: anonymousId || "",
      },
    },
  },
});

User Logout (Reset)

When a user logs out, publish an event with the RESET event type:

// Reset user using any event name you want!
await service.publish("USER_SIGNED_OUT", {
  pluginData: {
    PosthogPlugin: {
      properties: {
        previous_distinct_id: "user123",
        reset_device_id: "false", // or "true" to reset device ID
      },
    },
  },
});

// Or use a different event name
await service.publish("SESSION_ENDED", {
  pluginData: {
    PosthogPlugin: {
      properties: {
        previous_distinct_id: "user123",
        reset_device_id: "false",
      },
    },
  },
});

User Aliasing

Use an event with the ALIAS event type to link multiple distinct IDs to the same user:

// Alias a user using any event name you want!
await service.publish("USER_LINKED", {
  pluginData: {
    PosthogPlugin: {
      properties: {
        distinct_id: "frontend_user_123",
        alias: "backend_user_456",
      },
    },
  },
});

// Or use a different event name
await service.publish("ACCOUNT_MERGED", {
  pluginData: {
    PosthogPlugin: {
      properties: {
        distinct_id: "account_123",
        alias: "account_456",
      },
    },
  },
});

Getting Current User ID

// Get the current distinct ID (anonymous or identified)
const distinctId = service.getDistinctId();
console.log("Current user ID:", distinctId);

Complete User Management Example

class UserManager {
  constructor(private service: PosthogService) {}

  async login(userId: string, userData: any) {
    // Get current anonymous ID
    const anonymousId = this.service.getDistinctId();

    // Identify the user - name the event anything you want!
    await this.service.publish("USER_SIGNED_IN", {
      pluginData: {
        PosthogPlugin: {
          properties: {
            distinct_id: userId,
            person_properties: {
              email: userData.email,
              name: userData.name,
              login_method: "email",
              first_login_at: new Date().toISOString(),
            },
            anonymous_id: anonymousId || "",
          },
        },
      },
    });

    // Track login event
    await this.service.publish("USER_LOGIN", {
      pluginData: {
        PosthogPlugin: {
          properties: {
            login_method: "email",
            user_id: userId,
          },
        },
      },
    });
  }

  async logout(userId: string) {
    // Track logout event
    await this.service.publish("USER_LOGOUT", {
      pluginData: {
        PosthogPlugin: {
          properties: {
            user_id: userId,
            session_duration: "30 minutes",
          },
        },
      },
    });

    // Reset PostHog user - name the event anything you want!
    await this.service.publish("USER_SIGNED_OUT", {
      pluginData: {
        PosthogPlugin: {
          properties: {
            previous_distinct_id: userId,
            reset_device_id: "false",
          },
        },
      },
    });
  }

  async updateUserProperties(userId: string, properties: any) {
    // Update user properties - name the event anything you want!
    await this.service.publish("USER_SIGNED_IN", {
      pluginData: {
        PosthogPlugin: {
          properties: {
            distinct_id: userId,
            person_properties: properties,
            anonymous_id: "", // Empty string for no change
          },
        },
      },
    });

    // Track property update event
    await this.service.publish("USER_PROPERTIES_UPDATED", {
      pluginData: {
        PosthogPlugin: {
          properties: {
            user_id: userId,
            updated_properties: properties,
          },
        },
      },
    });
  }
}

Configuration Options

Basic Configuration

PosthogPlugin({
  POSTHOG_KEY: "your-posthog-key",
  config: {
    api_host: "https://your-posthog-host.com",
    autocapture: true,
    capture_pageview: true,
    disable_session_recording: false,
    persistence: 'localStorage',
  },
})

Using Pre-initialized PostHog Instance

import posthog from 'posthog-js';

// Initialize PostHog elsewhere in your app
const posthogInstance = posthog.init("your-posthog-key", {
  api_host: "https://your-posthog-host.com",
  autocapture: true,
});

// Use the pre-initialized instance
PosthogPlugin({
  posthogInstance: posthogInstance,
})

Configuration Options Reference

| Option | Type | Description | |--------|------|-------------| | POSTHOG_KEY | string | Your PostHog project API key | | POSTHOG_HOST | string | Legacy support for PostHog host URL | | config | PosthogConfig | PostHog configuration options | | posthogInstance | PostHog | Pre-initialized PostHog instance | | DEBUG | boolean | Enable debug logging |

Best Practices

1. Use Event Types for User Identification

Use the appropriate event types instead of relying on specific event names:

// ✅ Good: Use event types
{
  id: "USER_SIGNED_IN",
  eventType: PosthogEventTypes.IDENTIFY,
  properties: { /* ... */ }
}

// ❌ Bad: Don't rely on event names
// The plugin will call PostHog methods based on eventType, not event name

2. Name Events Meaningfully

Since you can name events anything you want, use descriptive names that make sense for your business:

// Good: Business-specific event names
CUSTOMER_ONBOARDED: {
  id: "CUSTOMER_ONBOARDED",
  eventType: PosthogEventTypes.IDENTIFY,
  // ...
},
ACCOUNT_MERGED: {
  id: "ACCOUNT_MERGED", 
  eventType: PosthogEventTypes.ALIAS,
  // ...
},
SESSION_EXPIRED: {
  id: "SESSION_EXPIRED",
  eventType: PosthogEventTypes.RESET,
  // ...
}

3. Use Unique Distinct IDs

Ensure each user has a unique distinct ID to avoid data merging:

// Good: Use database user ID
await service.publish("USER_SIGNED_IN", {
  pluginData: {
    PosthogPlugin: {
      properties: {
        distinct_id: user.databaseId,
        person_properties: userProperties,
        anonymous_id: anonymousId,
      },
    },
  },
});

4. Always Reset on Logout

Even if users don't share computers, always publish a reset event on logout:

async function handleLogout() {
  // Track logout event
  await service.publish("USER_LOGOUT", { /* ... */ });
  
  // Reset PostHog user
  await service.publish("USER_SIGNED_OUT", { /* ... */ });
}

5. Set Person Properties During Identification

Pass all available person properties during identification to keep user profiles up to date:

await service.publish("USER_SIGNED_IN", {
  pluginData: {
    PosthogPlugin: {
      properties: {
        distinct_id: user.id,
        person_properties: {
          email: user.email,
          name: user.name,
          subscription_tier: user.subscription,
          signup_date: user.createdAt,
          last_login: new Date().toISOString(),
        },
        anonymous_id: anonymousId,
      },
    },
  },
});

6. Use Flexible Plugin Data

The PostHOG plugin is designed to be flexible and user-friendly. You can send events with or without properties:

// With rich properties
await service.publish("BUTTON_CLICK", {
  pluginData: {
    PosthogPlugin: {
      properties: {
        button_name: "submit",
        page: "checkout",
        user_type: "premium"
      },
    },
  },
});

// With minimal properties
await service.publish("PAGE_VIEW", {
  pluginData: {
    PosthogPlugin: {
      properties: {},
    },
  },
});

// Or even simpler - the plugin works with minimal configuration
await service.publish("PAGE_VIEW", {
  pluginData: {
    PosthogPlugin: {},
  },
});

All events are sent to PostHOG regardless of whether plugin data is provided, making the plugin easy to use in various scenarios.

6. Handle Anonymous Users

Anonymous users can still generate events before identification:

// This works even for anonymous users
await service.publish("PAGE_VIEW", {
  pluginData: {
    PosthogPlugin: {
      properties: {
        page: "home",
        referrer: document.referrer,
      },
    },
  },
});

API Reference

PosthogService Methods

| Method | Description | |--------|-------------| | publish(eventId, options?) | Publish an event to PostHog | | getDistinctId() | Get the current user's distinct ID | | isPostHogAvailable() | Check if PostHog is available and initialized |

Event Types

| Event Type | Description | PostHog Method Called | |------------|-------------|----------------------| | PosthogEventTypes.IDENTIFY | Identify a user with PostHog | posthog.identify() | | PosthogEventTypes.RESET | Reset the current user (logout) | posthog.reset() | | PosthogEventTypes.ALIAS | Alias a user (link multiple IDs) | posthog.alias() | | PosthogEventTypes.CAPTURE | Regular PostHog event | posthog.capture() | | PosthogEventTypes.ERROR | Error event | posthog.capture("$exception") |

Required Properties by Event Type

IDENTIFY Events

{
  distinct_id: "string",
  person_properties: "object",
  anonymous_id: "string",
}

RESET Events

{
  previous_distinct_id: "string",
  reset_device_id: "string",
}

ALIAS Events

{
  distinct_id: "string",
  alias: "string",
}

Types

interface PosthogPluginOptions {
  POSTHOG_KEY?: string;
  POSTHOG_HOST?: string;
  config?: PosthogConfig;
  posthogInstance?: PostHog;
  DEBUG?: boolean;
}

Examples

See the src/example/ directory for complete working examples including:

  • Basic event publishing
  • User identification workflow using event types
  • Flexible event naming examples
  • Login/logout management
  • User property updates
  • User aliasing

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

License

Apache-2.0