# PostHog Node.js

PostHog Node.js is a comprehensive server-side analytics and feature management library that enables event tracking, user identification, feature flags with local evaluation, error tracking, and group analytics for Node.js and edge runtime environments.

## Package Information

- **Package Name**: posthog-node
- **Package Type**: npm
- **Language**: TypeScript
- **Installation**: `npm install posthog-node`

## Core Imports

```typescript
import { PostHog } from 'posthog-node';
```

For CommonJS:

```javascript
const { PostHog } = require('posthog-node');
```

## Basic Usage

```typescript
import { PostHog } from 'posthog-node';

// Initialize the client
const client = new PostHog('your-api-key', {
  host: 'https://app.posthog.com',
});

// Capture an event
client.capture({
  distinctId: 'user_123',
  event: 'button_clicked',
  properties: {
    button_name: 'signup',
    page: 'homepage'
  }
});

// Identify a user
client.identify({
  distinctId: 'user_123',
  properties: {
    email: 'user@example.com',
    plan: 'premium'
  }
});

// Check feature flag
const isEnabled = await client.isFeatureEnabled('new-feature', 'user_123');

// Gracefully shutdown
await client.shutdown();
```

## Architecture

PostHog Node.js is built around several key components:

- **PostHog Client**: Main class extending `PostHogBackendClient` providing all functionality
- **Event Queue**: Batches events for efficient sending (or immediate sending via `*Immediate` methods)
- **Feature Flags Poller**: Polls for feature flag definitions to enable local evaluation
- **Error Tracking**: Automatic and manual exception capture with stack trace processing
- **Memory Storage**: In-memory persistence for client state
- **Integrations**: First-party integrations for Express and Sentry

## Capabilities

### Client Initialization

Initialize and configure the PostHog client with various options including personal API keys for local flag evaluation, custom fetch implementations, and privacy settings.

```typescript { .api }
class PostHog {
  constructor(apiKey: string, options?: PostHogOptions);

  // Debug and privacy controls
  debug(enabled?: boolean): void;
  enable(): Promise<void>;
  disable(): Promise<void>;

  // Shutdown
  shutdown(shutdownTimeoutMs?: number): Promise<void>;
}
```

[Client Configuration](./client-configuration.md)

### Event Tracking

Capture user events with properties, groups, and feature flag context. Supports both queued and immediate capture modes.

```typescript { .api }
interface EventMessage {
  distinctId: string;
  event: string;
  properties?: Record<string | number, any>;
  groups?: Record<string, string | number>;
  sendFeatureFlags?: boolean | SendFeatureFlagsOptions;
  timestamp?: Date;
  uuid?: string;
  disableGeoip?: boolean;
}

class PostHog {
  capture(props: EventMessage): void;
  captureImmediate(props: EventMessage): Promise<void>;
}
```

[Event Tracking](./event-tracking.md)

### User and Group Identification

Identify users with properties, create aliases, and manage group analytics for organization-level tracking.

```typescript { .api }
interface IdentifyMessage {
  distinctId: string;
  properties?: Record<string | number, any>;
  disableGeoip?: boolean;
}

interface GroupIdentifyMessage {
  groupType: string;
  groupKey: string;
  properties?: Record<string | number, any>;
  distinctId?: string;
  disableGeoip?: boolean;
}

class PostHog {
  identify(data: IdentifyMessage): void;
  identifyImmediate(data: IdentifyMessage): Promise<void>;
  alias(data: { distinctId: string; alias: string; disableGeoip?: boolean }): void;
  aliasImmediate(data: { distinctId: string; alias: string; disableGeoip?: boolean }): Promise<void>;
  groupIdentify(data: GroupIdentifyMessage): void;
}
```

[User and Group Identification](./identification.md)

### Feature Flags

Evaluate feature flags locally or remotely with support for multivariate flags, payloads, group targeting, and experiments.

```typescript { .api }
type FeatureFlagValue = boolean | string;

class PostHog {
  isFeatureEnabled(
    key: string,
    distinctId: string,
    options?: {
      groups?: Record<string, string>;
      personProperties?: Record<string, string>;
      groupProperties?: Record<string, Record<string, string>>;
      onlyEvaluateLocally?: boolean;
      sendFeatureFlagEvents?: boolean;
      disableGeoip?: boolean;
    }
  ): Promise<boolean | undefined>;

  getFeatureFlag(
    key: string,
    distinctId: string,
    options?: {...}
  ): Promise<FeatureFlagValue | undefined>;

  getFeatureFlagPayload(
    key: string,
    distinctId: string,
    matchValue?: FeatureFlagValue,
    options?: {...}
  ): Promise<JsonType | undefined>;

  getAllFlags(distinctId: string, options?: {...}): Promise<Record<string, FeatureFlagValue>>;
  getAllFlagsAndPayloads(distinctId: string, options?: {...}): Promise<PostHogFlagsAndPayloadsResponse>;

  // Local evaluation control
  isLocalEvaluationReady(): boolean;
  waitForLocalEvaluationReady(timeoutMs?: number): Promise<boolean>;
  reloadFeatureFlags(): Promise<void>;
}
```

[Feature Flags](./feature-flags.md)

### Error Tracking

Capture exceptions manually or automatically with full stack traces, source context, and rate limiting.

```typescript { .api }
class PostHog {
  captureException(
    error: unknown,
    distinctId?: string,
    additionalProperties?: Record<string | number, any>
  ): void;

  captureExceptionImmediate(
    error: unknown,
    distinctId?: string,
    additionalProperties?: Record<string | number, any>
  ): Promise<void>;
}
```

[Error Tracking](./error-tracking.md)

### Express Integration

Automatic error tracking middleware for Express.js applications.

```typescript { .api }
function setupExpressErrorHandler(
  posthog: PostHog,
  app: { use: (middleware: ExpressMiddleware | ExpressErrorMiddleware) => unknown }
): void;
```

[Express Integration](./express-integration.md)

### Sentry Integration

Bi-directional integration linking PostHog users with Sentry errors.

```typescript { .api }
// Sentry v8 (function-based)
function sentryIntegration(
  posthog: PostHog,
  options?: SentryIntegrationOptions
): SentryIntegration;

// Sentry v7 (class-based)
class PostHogSentryIntegration {
  static readonly POSTHOG_ID_TAG: string;
  constructor(
    posthog: PostHog,
    organization?: string,
    prefix?: string,
    severityAllowList?: SeverityLevel[] | '*',
    sendExceptionsToPostHog?: boolean
  );
}
```

[Sentry Integration](./sentry-integration.md)

### Experimental APIs

Advanced caching capabilities for distributed environments.

```typescript { .api }
// Import from 'posthog-node/experimental'
interface FlagDefinitionCacheProvider {
  getFlagDefinitions(): Promise<FlagDefinitionCacheData | undefined> | FlagDefinitionCacheData | undefined;
  shouldFetchFlagDefinitions(): Promise<boolean> | boolean;
  onFlagDefinitionsReceived(data: FlagDefinitionCacheData): Promise<void> | void;
  shutdown(): Promise<void> | void;
}

interface FlagDefinitionCacheData {
  flags: PostHogFeatureFlag[];
  groupTypeMapping: Record<string, string>;
  cohorts: Record<string, PropertyGroup>;
}
```

[Experimental APIs](./experimental.md)

## Types

### PostHogOptions

```typescript { .api }
type PostHogOptions = {
  host?: string;
  flushAt?: number;
  flushInterval?: number;
  requestTimeout?: number;
  maxQueueSize?: number;
  maxRetries?: number;
  disabled?: boolean;
  captureMode?: 'form' | 'json';

  // Feature flags
  personalApiKey?: string;
  featureFlagsPollingInterval?: number;
  enableLocalEvaluation?: boolean;
  evaluationEnvironments?: readonly string[];
  flagDefinitionCacheProvider?: FlagDefinitionCacheProvider;

  // Privacy and filtering
  privacyMode?: boolean;
  custom_blocked_useragents?: string[];
  sendFeatureFlagEvent?: boolean;

  // Error tracking
  enableExceptionAutocapture?: boolean;

  // Advanced
  persistence?: 'memory';
  maxCacheSize?: number;
  fetch?: (url: string, options: PostHogFetchOptions) => Promise<PostHogFetchResponse>;
  before_send?: BeforeSendFn | BeforeSendFn[];

  // Preview features
  __preview_capture_bot_pageviews?: boolean;
};

type BeforeSendFn = (event: EventMessage | null) => EventMessage | null;
```

### SendFeatureFlagsOptions

```typescript { .api }
interface SendFeatureFlagsOptions {
  onlyEvaluateLocally?: boolean;
  personProperties?: Record<string, any>;
  groupProperties?: Record<string, Record<string, any>>;
  flagKeys?: string[];
}
```

### PostHogFlagsAndPayloadsResponse

```typescript { .api }
interface PostHogFlagsAndPayloadsResponse {
  featureFlags: Record<string, FeatureFlagValue>;
  featureFlagPayloads: Record<string, JsonType>;
}
```

## Environment-Specific Usage

### Edge Runtime Support

For edge runtimes like Cloudflare Workers or Vercel Edge Functions, the package automatically uses the appropriate entry point through conditional exports. The API remains the same, but the underlying implementation is optimized for edge environments.

```typescript
// Same API works in edge runtimes
import { PostHog } from 'posthog-node';

const client = new PostHog('your-api-key');
```

### Node.js vs Edge Differences

- **Node.js**: Includes advanced error tracking with source context and module resolution
- **Edge**: Simplified error tracking without filesystem-dependent features
- Both support the same API surface for events, feature flags, and identification