tracking
$
npx mdskill add BuilderIO/agent-native/trackingTrack analytics events across multiple providers without blocking requests.
- Enables agents to log user actions and system events reliably.
- Integrates with PostHog, Mixpanel, Amplitude, and custom backends.
- Decides event delivery by routing to all registered providers automatically.
- Delivers results by batching HTTP calls and flushing data periodically.
SKILL.md
.github/skills/trackingView on GitHub ↗
---
name: tracking
description: >-
Server-side analytics tracking with pluggable providers. Use when adding
analytics events, registering custom tracking providers, or configuring
built-in providers (PostHog, Mixpanel, Amplitude, Webhook).
---
# Tracking
## Rule
The tracking system provides a single `track()` call that fans out to all registered providers. Built-in providers auto-register from env vars -- set the var and tracking starts. Custom providers can be registered for any analytics backend. Tracking is server-side only, best-effort, and never blocks request handling.
## How It Works
1. At server startup, `registerBuiltinProviders()` checks env vars and registers any configured providers.
2. Application code calls `track(eventName, properties, meta)` from actions, plugins, or server routes.
3. The registry fans out the event to every registered provider. Errors are caught and logged -- a failing provider never crashes the caller.
4. Built-in providers batch HTTP calls (flush every 10 seconds or 50 events, whichever comes first).
## API
### `track(name, properties?, meta?)`
Fire an analytics event.
```ts
import { track } from "@agent-native/core/tracking";
track("meal.logged", { mealName: "Salad", calories: 350 }, { userId: "steve@builder.io" });
```
### `identify(userId, traits?)`
Identify a user with traits. Forwarded to providers that support it.
```ts
import { identify } from "@agent-native/core/tracking";
identify("steve@builder.io", { plan: "pro", company: "Builder.io" });
```
### `registerTrackingProvider(provider)`
Register a custom provider.
```ts
import { registerTrackingProvider } from "@agent-native/core/tracking";
registerTrackingProvider({
name: "my-analytics",
track(event) {
// Send event to your backend
},
identify(userId, traits) {
// Optional
},
flush() {
// Optional -- called on graceful shutdown
},
});
```
### `flushTracking()`
Flush all providers (call before process exit).
## Built-in Providers
Set the env var and the provider auto-registers at startup. No SDK dependencies -- all providers use raw HTTP.
| Provider | Env vars |
| ---------- | --------------------------------------------------------- |
| PostHog | `POSTHOG_API_KEY` (required), `POSTHOG_HOST` (optional, defaults to `https://us.i.posthog.com`) |
| Mixpanel | `MIXPANEL_TOKEN` |
| Amplitude | `AMPLITUDE_API_KEY` |
| Webhook | `TRACKING_WEBHOOK_URL` (required), `TRACKING_WEBHOOK_AUTH` (optional, sent as `Authorization` header) |
Multiple providers can be active simultaneously. All receive every event.
## Provider Interface
```ts
interface TrackingProvider {
name: string;
track(event: TrackingEvent): void | Promise<void>;
identify?(userId: string, traits?: Record<string, unknown>): void | Promise<void>;
flush?(): void | Promise<void>;
}
interface TrackingEvent {
name: string;
properties?: Record<string, unknown>;
timestamp?: string;
userId?: string;
}
```
## Design Decisions
- **globalThis singleton** -- the registry uses a `Symbol.for` key on globalThis so multiple ESM graph instances (dev-mode Vite + Nitro, symlinks) share one provider set.
- **Best-effort fan-out** -- provider errors are caught and logged, never propagated. A broken analytics integration must not break app functionality.
- **Batched HTTP** -- built-in providers enqueue events and flush every 10 seconds or 50 events, minimizing outbound requests.
- **NOT bridged to the event bus** -- tracking and the event bus are separate concerns. The event bus is for triggering automations; tracking is for analytics. Do not subscribe to `track()` calls from the event bus or vice versa.
## Key Files
| File | Purpose |
| ---------------------------------------------- | ------------------------------------------- |
| `packages/core/src/tracking/registry.ts` | `track()`, `identify()`, `registerTrackingProvider()`, `flushTracking()` |
| `packages/core/src/tracking/providers.ts` | Built-in providers (PostHog, Mixpanel, Amplitude, Webhook) and `registerBuiltinProviders()` |
| `packages/core/src/tracking/types.ts` | `TrackingEvent` and `TrackingProvider` interfaces |
## Related Skills
- `secrets` -- API keys for tracking providers can be registered as secrets
- `server-plugins` -- `registerBuiltinProviders()` is called by the core-routes plugin at startup
- `actions` -- call `track()` from action handlers to record user/agent activity
More from BuilderIO/agent-native