Skip to content

About

Privacy-first event tracking for Expo / React Native and web apps

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

SunGlasses — Privacy-First Analytics for React Native & Expo

SunGlasses

Privacy-first event tracking for React, React Native & Expo — with zero PII, zero drama.

Track what matters. Protect what doesn't. Ship with confidence.

Documentation · Quickstart · API Reference · Changelog


The problem with most analytics SDKs

Most event tracking libraries are built to collect as much as possible and ask permission later. They leak PII into event payloads, require you to wire up your own consent gate, and leave you scrambling when GDPR audits arrive.

SunGlasses flips that model. Users start opted out. PII is stripped automatically before events ever touch storage or the network. You get rich, actionable analytics — without the liability.

What makes SunGlasses different

SunGlasses Typical SDKs
Default consent state Opted out Opted in
PII sanitization Automatic, built-in Your problem
Anonymous ID source Fresh UUID v4 Often derived from device/user data
Self-hostable Yes — S3 + DuckDB Rarely
Cross-platform (web + RN) One SDK surface Usually separate libs
Open source Yes Sometimes

Features

  • Opt-out by default — zero data collected until the user explicitly consents. Flip to opt-in with a single config flag.
  • Automatic PII sanitization — emails, phone numbers, and card patterns are stripped from every event before it touches storage or the wire. Not opt-in. Always on.
  • Anonymous-by-design identities — stable UUIDs generated locally, never derived from user data. identify() is the only bridge between anonymous and known.
  • Built-in error capture — captureException, SunglassesErrorBoundary, global error handlers, console patching, and unhandled rejection tracking. Drop Sentry for the error events you actually need.
  • Middleware pipeline — drop, transform, or enrich events before they leave the device. Composable and async.
  • Pluggable storage & output — persist to localStorage, AsyncStorage, or push via HTTP. Bring your own adapter.
  • Self-hosted analytics dashboard — query your events with DuckDB over S3 Parquet. Dark mode. No third-party cloud required.
  • TypeScript-first — every interface, event shape, and config option is fully typed.

Quickstart

React Native / Expo

pnpm add @drakkar.software/sunglasses-core @drakkar.software/sunglasses-react-native @drakkar.software/sunglasses-storage-async-storage
pnpm add @react-native-async-storage/async-storage react-native-get-random-values
// app/_layout.tsx
import { SunglassesProvider } from '@drakkar.software/sunglasses-react-native';
import { AsyncStorageAdapter } from '@drakkar.software/sunglasses-storage-async-storage';
import { HttpPushAdapter } from '@drakkar.software/sunglasses-storage-http';

export default function RootLayout() {
  return (
    <SunglassesProvider
      config={{
        adapters: [
          new AsyncStorageAdapter(),
          new HttpPushAdapter({ url: 'https://your-ingest.example.com/events' }),
        ],
        autoCaptureErrors: true,  // global handlers + unhandled rejections
      }}
    >
      <Stack />
    </SunglassesProvider>
  );
}
// anywhere in your app
import { useSunglasses } from '@drakkar.software/sunglasses-react-native';

function CheckoutButton() {
  const { capture } = useSunglasses();

  return (
    <Button
      title="Buy now"
      onPress={() => capture('checkout_started', { plan: 'pro' })}
    />
  );
}

See the React Native setup guide for Expo Router screen tracking and error boundary integration.

Web (React)

pnpm add @drakkar.software/sunglasses-core @drakkar.software/sunglasses-react @drakkar.software/sunglasses-storage-localstorage

See the web setup guide.


Privacy that actually works

// This event is safe to send — SunGlasses strips PII automatically
client.capture('form_submitted', {
  email: 'user@example.com',      // → "[REDACTED]"
  phone: '+1 555-867-5309',       // → "[REDACTED]"
  plan: 'pro',                    // ✓ kept
});

// Consent gate — zero I/O until the user opts in
await client.optIn();   // now events start flowing
await client.optOut();  // immediately stops all capture and network calls

The PII sanitizer runs unconditionally as the first step in the middleware pipeline — before storage, before the network, before anything else. It cannot be removed or reordered.


Error capture without the bloat

// Wrap your tree — render errors captured automatically
<SunglassesGlobalErrorBoundary fallback={<ErrorScreen />}>
  <App />
</SunglassesGlobalErrorBoundary>

// Capture anywhere
import { captureException } from '@drakkar.software/sunglasses-core';

try {
  await riskyOperation();
} catch (err) {
  captureException(client, err, { handled: true });   // stack included by default
}

All error events are deduplicated within a 1 s window — no duplicate $error floods from an error boundary and a global handler firing on the same exception.


Self-hosted analytics dashboard

SunGlasses ships with a read-only analytics app that runs DuckDB queries over your S3 Parquet data — no third-party cloud, no per-seat pricing.

  • Overview KPIs: DAU, event volume, error rate
  • Top events & screens with time-series charts
  • Day-N retention cohorts
  • Grouped error explorer with stack traces
  • Per-app filtering
  • Ad-hoc SQL console
  • Light / dark mode
cd apps/analytics-dashboard
pnpm dev   # http://localhost:8788

Packages

Package Platform Description
@drakkar.software/sunglasses-core Any Platform-agnostic event engine + all interfaces
@drakkar.software/sunglasses-react Web React context provider + hooks
@drakkar.software/sunglasses-react-native RN / Expo React Native provider + screen tracking hooks
@drakkar.software/sunglasses-storage-localstorage Web localStorage persistence adapter
@drakkar.software/sunglasses-storage-async-storage React Native AsyncStorage persistence adapter
@drakkar.software/sunglasses-storage-http Any Batched HTTP push output adapter
@drakkar.software/sunglasses-adapter-starfish Any Push events to Starfish (Parquet, server-side)

Documentation

Topic Link
Getting started /getting-started/intro
Consent & privacy /privacy/consent
Error capture /guides/error-capture
Self-hosted ingest /backend/ingest-server
API reference /reference/config

Contributing

See CLAUDE.md and the contributing docs.

License

See package licenses on npm.

About

Privacy-first event tracking for Expo / React Native and web apps

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages