---
title: "@playstack/analytics"
description: "Runtime-neutral analytics fan-out with consent, PII scrubbing, and explicit provider capabilities."
tags: ["package","operations","analytics","privacy","pro"]
---

{/* package-access:start */}

> **Pro.** Covered by the Playstack Pro License. Registry access is required; check preview availability before installing. See [package access](/docs/packages#access-policy).

{/* package-access:end */}

`@playstack/analytics` provides runtime-neutral, fire-and-forget page, track, identify, and group calls with consent gating, PII scrubbing, isolated fan-out, and native provider access.

{/* package-install:start */}

## Install

After confirming [preview access](/docs/packages#access-policy), install the package at your application's shared Playstack version:

```sh
npm install --save-exact @playstack/analytics@0.1.0-beta.1
```

Check the peer requirements below before choosing a runtime or provider.

{/* package-install:end */}

## Install and compose

```ts
import { configureAnalytics } from '@playstack/analytics'
import { fathom } from '@playstack/analytics/fathom'
import { plausible } from '@playstack/analytics/plausible'

export const analytics = configureAnalytics({
  drivers: [fathom(fathomClient), plausible(plausibleClient)],
  consent: restoredConsent,
  development: import.meta.env.DEV,
  logger: console,
  onError: ({ method, driverId, error }) => {
    errors.captureError(error, { tags: { method, driverId: driverId ?? 'input' } })
  },
})

analytics.page({ url: '/pricing', properties: { source: 'navigation' } })
analytics.track('signup_completed', { plan: 'pro', value: 4900 })
```

Calls validate and scrub once before fan-out, return synchronously, and never throw. Sync and async provider failures are isolated through `onError`.

## Reporter configuration

| `ConfigureAnalyticsOptions` property | Required | Purpose                                                   |
| ------------------------------------ | -------- | --------------------------------------------------------- |
| `drivers`                            | Yes      | Uniquely named structural provider bridges.               |
| `consent`                            | No       | `unknown`, `granted`, or `denied`; defaults to `unknown`. |
| `development`                        | No       | Warn once for unsupported driver methods.                 |
| `logger`                             | No       | Receives development capability warnings.                 |
| `onError`                            | No       | Isolated input or driver failure observer.                |

Consent-required drivers receive events only while state is `granted`. Drivers marked `not-required` continue under unknown or denied consent. Dropped calls are never replayed.

## Provider bridge

```ts
interface AnalyticsProvider<TClient = unknown> {
  id: string
  client: TClient
  capabilities: {
    page: boolean
    track: false | 'goals' | 'events'
    identify: boolean
    group: false | 'partial' | 'full'
  }
  consent: 'required' | 'not-required'
  page?(page: AnalyticsPage): void | Promise<void>
  track?(event: string, properties: AnalyticsProperties): void | Promise<void>
  identify?(userId: string, traits: AnalyticsProperties): void | Promise<void>
  group?(groupId: string, traits: AnalyticsProperties): void | Promise<void>
}
```

`analytics.driver(id).client` returns the native SDK client. Capabilities document actual behavior rather than simulating missing features.

## Privacy contract

Properties are limited to 30 shallow string, number, boolean, or null values. PII-shaped keys and values are omitted before any provider sees them. `normalizeAnalyticsTrack` from `@playstack/analytics/validation` applies the same contract before a queue or framework adapter persists server events.

## Included adapters

- Fathom maps page views and named events; numeric `value` becomes `_value`.
- Plausible maps page views, events, and non-null custom properties.
- Basemarks supports `track()` with string-valued properties, not page/identify/group. Non-string properties require explicit `mapProperties` conversion or the event is rejected. Consent defaults to required; this gate does not control SDK auto-instrumentation. See the [Basemarks integration](/integrations/basemarks).

## Testing and boundary

`@playstack/analytics/testing` provides capture/no-op drivers and a driver contract suite. The core does not bundle or initialize SDKs, persist consent, reconcile identities, or decide whether browser and server events represent one logical event.

{/* package-reference:start */}

## API entry points and requirements

Reference snapshot: `@playstack/analytics@0.1.0-beta.1`. Import only the entry point your runtime needs. Paths below are relative to the installed package; use **Go to Definition** in your editor to inspect exact parameters, return types and overloads. Do not import the declaration-file paths directly.

| Public entry point | Declaration file |
| --- | --- |
| `@playstack/analytics` | `./dist/index.d.ts` |
| `@playstack/analytics/errors` | `./dist/errors.d.ts` |
| `@playstack/analytics/types` | `./dist/types.d.ts` |
| `@playstack/analytics/validation` | `./dist/validation.d.ts` |
| `@playstack/analytics/testing` | `./dist/testing.d.ts` |
| `@playstack/analytics/fathom` | `./dist/fathom.d.ts` |
| `@playstack/analytics/plausible` | `./dist/plausible.d.ts` |
| `@playstack/analytics/basemarks` | `./dist/basemarks.d.ts` |
| `@playstack/analytics/package.json` | No TypeScript declaration (asset or metadata export). |

Node.js engine requirement: `>=20`. This is not a claim that every entry point works in browsers or Workers.

### Peer dependencies

This package declares no peer dependencies. Its ordinary dependencies are resolved by the package manager.

For a complete first program, start with [Getting started](/docs/getting-started). For API lookup and partial-example conventions, see [Reading the reference](/docs/packages#reading-the-reference). Provider failures, lifecycle requirements and application responsibilities remain described in the guide above; types alone do not establish production safety.

{/* package-reference:end */}
