Skip to content
trakoo
Esc
navigateopen⌘Jpreview
On this page

Core Concepts

The five ideas behind trakoo — events, providers, the client/server split, user identification, and type safety.

trakoo is small, but a few ideas do the heavy lifting. Read these in order and you’ll understand everything the rest of the docs build on.

The shape of the API

Everything comes back to three moves: define events, create an instance with providers, and track.

// 1. Define events once
import { defineEvents, typed } from 'trakoo';
import { createClientAnalytics } from 'trakoo/client';
import { PostHogClientProvider } from 'trakoo/providers/client';

export const appEvents = defineEvents({
  buttonClicked: {
    name: 'button_clicked',
    category: 'engagement',
    properties: typed<{ buttonId: string }>()
  }
});

// 2. Create an instance with your providers
const analytics = createClientAnalytics({
  events: appEvents,
  providers: [new PostHogClientProvider({ token: 'xxx' })]
});

// 3. Track — fully typed
await analytics.track('button_clicked', { buttonId: 'cta' });

The root import supplies environment-neutral registry helpers and shared types. Factories and providers stay on their client/server subpaths. Every factory call returns a fresh application-owned instance; passing events gives it the registry and all inferred types.

Client tracking is stateful: identify() once, and later events carry that user until you reset(). Server tracking is stateless: pass user context with each track(), then shutdown() to flush. Client vs Server covers the difference in full.

Before you start

These guides assume you’ve run through the Quick Start, installed trakoo with at least one provider, and are comfortable with basic TypeScript.

Start with Events →

Was this page helpful?