Pug is open-source product analytics. Capture events, identify the people behind them, and query the result back out - from a browser, a mobile app, your backend, or any language that can POST JSON. Run it on Pug Cloud or self-host the entire stack.
Custom event names work with no setup. Beyond those, Pug ships
127 typed events across 19 families
(commerce, auth, billing, media, support), each with a validated property
schema, so purchase and signup mean the same thing in your data as they do
in everyone else’s. Capture is
cookieless by default: events flow from the first
hit, and nothing is stored on the device until the reader consents.
Initialize, then track
The whole integration, on every platform. Pick yours - the choice follows you into the SDK reference.
import { init, track } from '@pug-sh/browser'
init('YOUR_PROJECT_ID', {
apiKey: 'pub_YOUR_PUBLIC_KEY'
})
track('page_view')import 'package:pug_flutter/pug_flutter.dart';
await Pug.init(
'YOUR_PROJECT_ID',
const PugOptions(apiKey: 'pub_YOUR_PUBLIC_KEY'),
);
Pug.track('page_view');import { Pug } from '@pug-sh/node'
// Server-side - authenticate with your private key.
const pug = new Pug({ apiKey: process.env.PUG_PRIVATE_KEY! })
// A server has no ambient user - name the distinctId.
pug.track('user-123', 'page_view')# No SDK? POST events to the Connect RPC ingest endpoint.
# See /sdks for the full request shape.
curl -X POST https://api.pugs.dev/sdk.events.v1.EventsService/BatchCreate \
-H "x-api-key: pub_YOUR_PUBLIC_KEY" \
-H "Connect-Protocol-Version: 1" \
-H "Content-Type: application/json" \
-d '{"events":[{"eventId":"01J9...","kind":"page_view","distinctId":"anon-1","sessionId":"01J9...","occurTime":"2026-06-05T10:00:00Z"}]}'Ways to integrate
Web app
Install the Web SDK (@pug-sh/browser) - auto-track page views and clicks,
identify users on sign-in. Quickstart
Mobile app
Typed event tracking, screen and lifecycle auto-tracking, and identity for Flutter apps. Flutter setup
Backend or any language
Send events and read analytics from Node with @pug-sh/node - or POST
straight to the Connect RPC API from anywhere else.
Node SDK
Query your data
Read insights and profiles programmatically with your private key, via the Node SDK or the Connect API. API reference
Self-host
Run the full stack - Postgres, ClickHouse, NATS, Dragonfly and the Go workers - on your own infrastructure. Self-hosting guide
How it works
Events flow from your app through an async pipeline into analytics storage. The same data powers Live, Insights, and Profiles.
Ingestion is near-real-time: events appear in Live within seconds and in Insights within the same minute. See Core concepts for the full model.
Jump straight in
import { track } from '@pug-sh/browser'
track('button_clicked', { label: 'Sign up' })
track('purchase', {
productId: 'sku_123',
amount: 29.99,
currency: 'USD'
}, { immediate: true })import { identify, reset } from '@pug-sh/browser'
// On sign-in - merges prior anonymous activity into the profile.
await identify('user-123', {
email: 'user@example.com',
plan: 'pro'
})
// On sign-out.
reset()