@telemetry-kit/browser
v0.1.0
Published
Privacy-first telemetry for browsers - lightweight (~1.4KB gzipped) with Proof of Work anti-spam
Maintainers
Readme
@telemetry-kit/browser
Privacy-first telemetry for browsers. Lightweight (~2KB gzipped) with Proof of Work anti-spam protection.
Features
- Zero dependencies - No external packages required
- Tiny bundle size - ~2KB gzipped
- Privacy-first - Respects
navigator.doNotTrackand GPC - No secrets required - Uses Proof of Work instead of API keys
- Reliable delivery - Uses
navigator.sendBeaconfor page unload events - Modern Web APIs - Uses Web Crypto API for SHA-256 hashing
Installation
npm install @telemetry-kit/browserQuick Start
import { TelemetryKit } from '@telemetry-kit/browser';
// Initialize
const telemetry = new TelemetryKit({
appId: 'your-app-id',
endpoint: 'https://api.telemetry-kit.dev/v1/collect'
});
// Track events
telemetry.track('button_click', { button: 'submit' });
// Track page views
telemetry.trackPageView();
// Track features
telemetry.trackFeature('dark_mode', { enabled: true });
// Track errors
telemetry.trackError('api_failed', { status: 500 });Configuration
const telemetry = new TelemetryKit({
// Required: Your application ID
appId: 'your-app-id',
// Optional: Ingestion endpoint (default: telemetry-kit.dev)
endpoint: 'https://api.telemetry-kit.dev/v1/collect',
// Optional: Proof of Work difficulty (default: 4)
// Higher = more spam protection, but slower (~10ms at 4)
difficulty: 4,
// Optional: Respect navigator.doNotTrack (default: true)
respectDNT: true,
// Optional: Auto-flush interval in ms (default: 5000)
flushInterval: 5000,
// Optional: Max events before auto-flush (default: 10)
maxQueueSize: 10,
// Optional: Debug logging (default: false)
debug: false
});How Proof of Work Works
Instead of requiring API secrets (which can't be hidden in browser code), this SDK uses Proof of Work (PoW) to prevent spam:
- Each event requires solving a SHA-256 hash puzzle
- Finding a valid nonce takes ~10ms for legitimate users
- Mass-generating fake events becomes computationally expensive
- No secrets needed in client code
Difficulty | Leading Zeros | Avg Iterations | Time
-----------+---------------+----------------+------
3 | 000 | ~4,096 | ~1ms
4 | 0000 | ~65,536 | ~10ms
5 | 00000 | ~1,048,576 | ~150msPrivacy Features
Do Not Track
By default, the SDK respects:
navigator.doNotTrack === '1'navigator.globalPrivacyControl === '1'
// Disable DNT checking
const telemetry = new TelemetryKit({
appId: 'app',
respectDNT: false
});Anonymous Sessions
- Session IDs are random UUIDs
- No persistent identifiers stored
- No cookies or localStorage used
Manual Control
// Disable tracking
telemetry.setEnabled(false);
// Enable tracking
telemetry.setEnabled(true);
// Check status
const isEnabled = telemetry.getEnabled();API Reference
new TelemetryKit(config)
Create a new TelemetryKit instance.
track(type: string, data?: Record<string, unknown>): Promise<void>
Track a custom event with optional data.
trackPageView(path?: string): Promise<void>
Track a page view. Defaults to current window.location.pathname.
trackFeature(feature: string, metadata?: Record<string, unknown>): Promise<void>
Track feature usage.
trackError(error: string, metadata?: Record<string, unknown>): Promise<void>
Track an error.
flush(): Promise<void>
Immediately flush queued events to the server.
setEnabled(enabled: boolean): void
Enable or disable tracking.
getEnabled(): boolean
Get current enabled state.
destroy(): void
Stop the flush timer and flush remaining events.
Framework Integration
React
import { useEffect } from 'react';
import { TelemetryKit } from '@telemetry-kit/browser';
const telemetry = new TelemetryKit({ appId: 'my-app' });
function App() {
useEffect(() => {
telemetry.trackPageView();
return () => telemetry.destroy();
}, []);
const handleClick = () => {
telemetry.track('button_click', { button: 'cta' });
};
return <button onClick={handleClick}>Click me</button>;
}Vue
import { onMounted, onUnmounted } from 'vue';
import { TelemetryKit } from '@telemetry-kit/browser';
const telemetry = new TelemetryKit({ appId: 'my-app' });
onMounted(() => {
telemetry.trackPageView();
});
onUnmounted(() => {
telemetry.destroy();
});Next.js
// app/providers.tsx
'use client';
import { useEffect } from 'react';
import { TelemetryKit } from '@telemetry-kit/browser';
const telemetry = new TelemetryKit({ appId: 'my-app' });
export function TelemetryProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
telemetry.trackPageView();
return () => telemetry.destroy();
}, []);
return <>{children}</>;
}Self-Hosting
For self-hosted telemetry-kit servers, just change the endpoint:
const telemetry = new TelemetryKit({
appId: 'my-app',
endpoint: 'https://your-server.com/v1/collect'
});License
MIT OR Apache-2.0
