PostHog Node.js integration for event tracking, feature flags, and error tracking in server-side applications
npx @tessl/cli install tessl/npm-posthog-node@5.13.0PostHog 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.
npm install posthog-nodeimport { PostHog } from 'posthog-node';For CommonJS:
const { PostHog } = require('posthog-node');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();PostHog Node.js is built around several key components:
PostHogBackendClient providing all functionality*Immediate methods)Initialize and configure the PostHog client with various options including personal API keys for local flag evaluation, custom fetch implementations, and privacy settings.
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>;
}Capture user events with properties, groups, and feature flag context. Supports both queued and immediate capture modes.
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>;
}Identify users with properties, create aliases, and manage group analytics for organization-level tracking.
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;
}Evaluate feature flags locally or remotely with support for multivariate flags, payloads, group targeting, and experiments.
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>;
}Capture exceptions manually or automatically with full stack traces, source context, and rate limiting.
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>;
}Automatic error tracking middleware for Express.js applications.
function setupExpressErrorHandler(
posthog: PostHog,
app: { use: (middleware: ExpressMiddleware | ExpressErrorMiddleware) => unknown }
): void;Bi-directional integration linking PostHog users with Sentry errors.
// 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
);
}Advanced caching capabilities for distributed environments.
// 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>;
}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;interface SendFeatureFlagsOptions {
onlyEvaluateLocally?: boolean;
personProperties?: Record<string, any>;
groupProperties?: Record<string, Record<string, any>>;
flagKeys?: string[];
}interface PostHogFlagsAndPayloadsResponse {
featureFlags: Record<string, FeatureFlagValue>;
featureFlagPayloads: Record<string, JsonType>;
}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.
// Same API works in edge runtimes
import { PostHog } from 'posthog-node';
const client = new PostHog('your-api-key');