@traxel/sdk
v0.1.0
Published
Analytics SDK for Chrome MV3 extensions. Survives service worker termination. The analytics platform built specifically for Chrome extensions — not a website analytics tool ported to MV3.
Maintainers
Readme
Why Traxel exists
GA4, Mixpanel, Amplitude, PostHog — none of them understand Chrome extensions.
- Uninstalls are invisible.
chrome.runtime.setUninstallURLis unknown to web analytics. - Retention model is wrong. GA4 anchors to sessions. Extensions need install-date cohorts.
- Remote code is banned. MV3 prohibits loading
gtag.jsor any remotely-hosted JS. - Events vanish silently. The service worker dies after 30 seconds idle. If your in-memory buffer isn't flushed before then, those events disappear. No warning. No retry.
Traxel is purpose-built for these constraints. Storage-backed queue. Alarm-driven flush cycle synced to the SW idle timer. Install-date-anchored retention. Native uninstall tracking.
Quick start
1. Install
npm install @traxel/sdk2. Add to your service worker
In background.js (or background.ts), add this at the very top — before any await:
import Traxel from '@traxel/sdk';
// Must be synchronous, before any await in your SW
Traxel.init({ projectId: 'YOUR_PROJECT_ID' });That's it. Traxel automatically tracks:
| Event | Trigger |
|-------|---------|
| install | First install (chrome.runtime.onInstalled) |
| update | Extension updated (with previous version) |
| uninstall | User uninstalls (chrome.runtime.setUninstallURL) |
| sw_cold_start | Service worker woken from idle termination |
| sw_termination | Service worker about to be killed |
| error | Unhandled errors and promise rejections |
| session_start / session_end | Popup/options/side panel open and close |
3. Track custom events
import Traxel from '@traxel/sdk';
Traxel.init({ projectId: 'YOUR_PROJECT_ID' }); // idempotent — safe everywhere
Traxel.track('export_clicked', { format: 'csv', row_count: 150 });
Traxel.track('shortcut_used', { shortcut: 'Ctrl+S' });
Traxel.track('feature_toggled', { feature: 'dark_mode', enabled: true });Event names can be any string up to 100 characters. Properties must be strings, numbers, booleans, or null — no nested objects, no arrays, no PII.
4. Make sure your manifest has these permissions
{
"permissions": ["storage", "alarms"],
"background": {
"service_worker": "background.js",
"type": "module"
}
}The SDK needs storage for the event queue and alarms for the flush timer. The SW must be a module ("type": "module") to use import syntax.
Configuration
Traxel.init({
projectId: 'YOUR_PROJECT_ID', // Required
// Optional — sensible defaults below
apiEndpoint: 'https://...', // Default: Traxel cloud ingest
flushIntervalSeconds: 28, // Default: 28s (just under SW idle timer)
maxQueueSize: 150, // Default: 150 events
maxBatchSize: 25, // Default: 25 events per flush
debug: false, // Set to true for console logs
// Auto-tracking toggles
trackErrors: true, // Capture unhandled errors
trackSWHealth: true, // SW cold start + termination telemetry
trackSessions: true, // Popup open/close tracking
// Uninstall survey
uninstallSurveyUrl: 'https://...', // Users see this after uninstalling
// Default properties on every event
defaultProperties: { plan: 'pro' },
// A/B flags — passed through to every event
flags: { experiment_v2: 'variant_b' },
});What you get
Go to traxel-theta.vercel.app to see:
- Install & uninstall trends — daily net, cumulative totals
- DAU/WAU/MAU — anchored to install date, not session
- Retention cohorts — D1 / D7 / D14 / D30 / D60 / D90 per weekly install cohort
- Feature usage — every
Traxel.track()call ranked by volume, with 7-day trend - Error monitor — unhandled errors grouped by message, with affected users and versions
- SW health — cold start count, P50/P95 latency, termination rate
- Update funnel — what % of users are on each extension version
- Live stream — events from your extension appear in real-time via WebSocket
Architecture
Your Extension (MV3)
└── @traxel/sdk (< 8 KB gzipped)
├── EventQueue (chrome.storage.local backed)
├── Flusher (chrome.alarms, survives SW termination)
├── IdentityManager (anonymous UUID, never PII)
└── HTTP transport → Traxel Ingest API
Traxel Ingest (Cloudflare Workers, global edge)
└── Validates → writes to database
Traxel Dashboard (Next.js)
└── All your charts, cohorts, and live eventsBundle size
The SDK adds ~3.8 KB gzipped to your extension. Zero runtime dependencies — pure Chrome APIs + fetch(). The flush alarm wakes the service worker at most once every 28 seconds, well within Chrome's lifetime budget.
Privacy
Traxel never collects browsing history, URLs, page content, or any personally identifiable information. A random anonymous UUID is generated per install — stable across sessions, but never linked to any identity, Google account, or browser fingerprint. Extension policy-compliant by design.
License
MIT
