Introduction
Type-safe, provider-agnostic analytics for TypeScript applications
@stacksee/analytics is a highly typed, zero-dependency, provider-agnostic analytics library for TypeScript applications. Track events with full type safety across client and server environments.
Why @stacksee/analytics?
Fully Type-Safe
Define your events once, get autocomplete and type checking everywhere. No more typos or wrong properties.
Provider Agnostic
Use any analytics serviceβPostHog, Bento, Pirsch, or build your own. Switch providers without changing your code.
Universal API
Same API works on client and server. Write once, track everywhere.
Zero Dependencies
Core library has zero dependencies. Providers are optional and tree-shakeable.
Quick Example
import { createClientAnalytics } from '@stacksee/analytics/client';
import { PostHogClientProvider } from '@stacksee/analytics/providers/client';
// Define your events with full type safety
const appEvents = {
userSignedUp: {
name: 'user_signed_up',
category: 'user',
properties: {} as {
email: string;
plan: 'free' | 'pro' | 'enterprise';
}
}
} as const;
// Initialize with your providers
const analytics = createClientAnalytics<typeof appEvents>({
providers: [
new PostHogClientProvider({ token: 'your-key' })
]
});
// Track events with autocomplete and type checking
analytics.track('user_signed_up', {
email: 'user@example.com',
plan: 'pro' // β
TypeScript knows this must be 'free' | 'pro' | 'enterprise'
});Get Started in 3 Steps
Install the Library
pnpm install @stacksee/analyticsChoose Your Providers
Install the SDKs for your analytics services:
# PostHog
pnpm install posthog-js posthog-node
# Bento
pnpm install @bentonow/bento-node-sdk
# Pirsch
pnpm install pirsch-sdkStart Tracking
Define your events and start tracking:
import { createClientAnalytics } from '@stacksee/analytics/client';
const analytics = createClientAnalytics({
providers: [/* your providers */]
});
analytics.track('button_clicked', { buttonId: 'cta' });Key Features
π― Type-Safe Events
Define your events with TypeScript and get compile-time validation:
// β This will error - wrong property
analytics.track('user_signed_up', {
wrongProperty: 'value'
});
// β This will error - wrong event name
analytics.track('wrong_event', {});
// β
This works - fully typed
analytics.track('user_signed_up', {
email: 'user@example.com',
plan: 'pro'
});π Plugin Architecture
Add multiple providers and they all receive events:
const analytics = createClientAnalytics({
providers: [
new PostHogClientProvider({ token: 'xxx' }),
new BentoClientProvider({ siteUuid: 'xxx' }),
new PirschClientProvider({ identificationCode: 'xxx' })
]
});
// One call, all providers receive it
analytics.track('purchase', { amount: 99.99 });π Universal API
Same API works on both client and server:
// Client-side
import { createClientAnalytics } from '@stacksee/analytics/client';
// Server-side
import { createServerAnalytics } from '@stacksee/analytics/server';
// Both support the same methods
analytics.track();
analytics.identify();
analytics.pageView();π€ Automatic User Context
Identify users once, context flows to all events:
// Identify the user
analytics.identify('user-123', {
email: 'user@example.com',
plan: 'pro'
});
// All subsequent events include user context automatically
analytics.track('feature_used', {
feature: 'export'
});
// Providers receive: { userId: 'user-123', email: 'user@example.com', traits: {...} }