react-native-analytics-bridge
v1.0.0
Published
A navigator-agnostic analytics bridge for React Native with multi-provider support, session tracking, offline queuing, and GDPR privacy controls
Downloads
29
Maintainers
Readme
react-native-analytics-bridge
A navigator-agnostic analytics bridge for React Native. One unified API, multiple providers, with built-in session tracking, offline event queuing, GDPR privacy controls, and a flexible middleware pipeline.
Why?
Most analytics solutions for React Native are thin wrappers around a single provider. Switching providers means rewriting your entire tracking implementation. This package separates your tracking calls from your provider — swap Segment for PostHog, or run both simultaneously, without touching your app code.
Features
- Multi-provider: Segment, Mixpanel, Amplitude, Firebase, PostHog, RudderStack — or run multiple at once
- Auto screen tracking: Drop-in integrations for React Navigation and Expo Router
- Session management: Automatic session ID generation, session start/end events, background/foreground handling
- Offline event queue: Buffers events when offline, flushes on reconnect with exponential backoff retry
- GDPR / Privacy: Opt-out/opt-in support, PII field masking, consent management
- Middleware pipeline: Transform, filter, and enrich events before they reach any provider
- TypeScript first: Full type safety throughout
- Custom adapters: Implement your own provider in minutes
Installation
npm install react-native-analytics-bridge
# or
yarn add react-native-analytics-bridgeThen install the peer dependency for whichever provider(s) you use — see the Adapters section.
Quick Start
// analytics.ts
import {
createAnalytics,
createConsoleAdapter,
createSegmentAdapter,
} from 'react-native-analytics-bridge';
import { createClient } from '@segment/analytics-react-native';
const segmentClient = createClient({ writeKey: 'YOUR_SEGMENT_KEY' });
export const analytics = createAnalytics({
adapters: [
createConsoleAdapter(), // logs events in dev
createSegmentAdapter({ client: segmentClient }),
],
debug: __DEV__,
});
await analytics.initialize();// App.tsx
import { analytics } from './analytics';
import { useReactNavigationTracking } from 'react-native-analytics-bridge';
export default function App() {
const { ref, onStateChange } = useReactNavigationTracking();
return (
<NavigationContainer ref={ref} onStateChange={onStateChange}>
<Stack.Navigator>...</Stack.Navigator>
</NavigationContainer>
);
}// Any screen
import { useAnalytics } from 'react-native-analytics-bridge';
function CheckoutScreen() {
const { track } = useAnalytics();
const handlePurchase = () => {
track('purchase_completed', {
amount: 49.99,
currency: 'USD',
items: ['item_1', 'item_2'],
});
};
return <Button onPress={handlePurchase} title="Buy Now" />;
}Core API
createAnalytics(config)
Creates and returns the analytics manager. Call this once at app startup.
const analytics = createAnalytics({
adapters: [...], // required — at least one adapter
privacy: {
maskFields: ['email', 'phone'],
defaultOptOut: false,
},
queue: {
maxBatchSize: 20, // flush after this many events
flushInterval: 10000, // flush every N ms
maxRetries: 3,
},
session: {
sessionTimeout: 1800000, // 30 min inactivity = new session
autoTrackSessionEvents: true, // emit session_start / session_end
},
globalProperties: {
app_version: '2.0.0',
environment: 'production',
},
debug: __DEV__,
onError: (error, event) => console.error('Analytics error', error),
});
await analytics.initialize();getAnalytics()
Returns the existing analytics instance from anywhere in your app.
import { getAnalytics } from 'react-native-analytics-bridge';
getAnalytics().track('button_pressed', { button: 'cta' });Tracking methods
// Track a custom event
analytics.track('video_played', { video_id: 'abc123', duration: 60 });
// Track a screen view
analytics.screen('ProductDetail', { product_id: 'xyz' });
// Identify a user
await analytics.identify('user_123', {
name: 'Jane Doe',
plan: 'pro',
});
// Associate user with a group/org
await analytics.group('org_456', { name: 'Acme Corp', plan: 'enterprise' });
// Alias two user identities (e.g. anonymous → logged in)
await analytics.alias('user_123');
// Reset on logout
await analytics.reset();
// Force flush the event queue
await analytics.flush();Screen Tracking
React Navigation
import { useReactNavigationTracking } from 'react-native-analytics-bridge';
function App() {
const { ref, onStateChange } = useReactNavigationTracking({
extraProperties: { platform: 'ios' },
});
return (
<NavigationContainer ref={ref} onStateChange={onStateChange}>
...
</NavigationContainer>
);
}Expo Router
// app/_layout.tsx
import { useExpoRouterTracking } from 'react-native-analytics-bridge';
export default function RootLayout() {
useExpoRouterTracking();
return <Stack />;
}Per-screen tracking hook
import { useScreenTracking } from 'react-native-analytics-bridge';
function ProfileScreen({ userId }: { userId: string }) {
useScreenTracking('Profile', { user_id: userId }, [userId]);
return <View>...</View>;
}Hooks
useAnalytics()
Access all analytics methods inside components.
const { track, identify, reset, optOut, optIn } = useAnalytics();useSession()
Access current session info.
const session = useSession();
console.log(session?.sessionId, session?.screenCount);Middleware
Middleware runs on every event before it reaches any adapter.
import {
createPropertyEnricher,
createEventFilter,
createEventTransformer,
createAttributionEnricher,
createScreenFilter,
} from 'react-native-analytics-bridge';
// Add global properties to all events
analytics.addEventMiddleware(
createPropertyEnricher({ app_version: '2.0.0', platform: 'ios' })
);
// Drop internal/debug events in production
analytics.addEventMiddleware(
createEventFilter((event) => !event.name.startsWith('debug_'))
);
// Normalize event names to snake_case
analytics.addEventMiddleware(
createEventTransformer((event) => ({
...event,
name: event.name.toLowerCase().replace(/ /g, '_'),
}))
);
// Add UTM attribution from a deep link
analytics.addEventMiddleware(
createAttributionEnricher({ utm_source: 'email', utm_medium: 'newsletter' })
);
// Filter specific screens from tracking
analytics.addScreenMiddleware(
createScreenFilter(['Loading', 'Splash', 'Transition'])
);Privacy & GDPR
const analytics = createAnalytics({
adapters: [...],
privacy: {
maskFields: ['email', 'phone', 'credit_card'], // masked to '***'
maskValue: '[REDACTED]', // custom mask value
defaultOptOut: false, // start opted in
},
});
// User opts out — all tracking stops immediately
analytics.optOut();
// User opts back in
analytics.optIn();
// Check status
if (analytics.isOptedIn()) {
analytics.track('settings_opened');
}Adapters
Segment
npm install @segment/analytics-react-nativeimport { createClient } from '@segment/analytics-react-native';
import { createSegmentAdapter } from 'react-native-analytics-bridge';
const client = createClient({ writeKey: 'YOUR_KEY' });
createAnalytics({ adapters: [createSegmentAdapter({ client })] });Mixpanel
npm install mixpanel-react-nativeimport { Mixpanel } from 'mixpanel-react-native';
import { createMixpanelAdapter } from 'react-native-analytics-bridge';
const mixpanel = new Mixpanel('YOUR_TOKEN', true);
await mixpanel.init();
createAnalytics({ adapters: [createMixpanelAdapter({ instance: mixpanel })] });Amplitude
npm install @amplitude/analytics-react-nativeimport * as amplitude from '@amplitude/analytics-react-native';
import { createAmplitudeAdapter } from 'react-native-analytics-bridge';
await amplitude.init('YOUR_API_KEY').promise;
createAnalytics({ adapters: [createAmplitudeAdapter({ instance: amplitude })] });Firebase
npm install @react-native-firebase/app @react-native-firebase/analyticsimport analytics from '@react-native-firebase/analytics';
import { createFirebaseAdapter } from 'react-native-analytics-bridge';
createAnalytics({ adapters: [createFirebaseAdapter({ instance: analytics() })] });PostHog
npm install posthog-react-nativeimport PostHog from 'posthog-react-native';
import { createPostHogAdapter } from 'react-native-analytics-bridge';
const posthog = await PostHog.initAsync('YOUR_API_KEY');
createAnalytics({ adapters: [createPostHogAdapter({ client: posthog })] });RudderStack
npm install @rudderstack/rudder-sdk-react-nativeimport rudderClient from '@rudderstack/rudder-sdk-react-native';
import { createRudderStackAdapter } from 'react-native-analytics-bridge';
await rudderClient.setup('YOUR_WRITE_KEY', { dataPlaneUrl: 'YOUR_URL' });
createAnalytics({ adapters: [createRudderStackAdapter({ client: rudderClient })] });Console (Debug)
Logs all events to the console — great for development.
import { createConsoleAdapter } from 'react-native-analytics-bridge';
createAnalytics({
adapters: [
createConsoleAdapter({ verbose: true }), // verbose: full JSON output
],
});Custom Adapter
Implement the AnalyticsAdapter interface to add any provider:
import type { AnalyticsAdapter } from 'react-native-analytics-bridge';
const myAdapter: AnalyticsAdapter = {
name: 'my-provider',
async initialize() {
await MySDK.init('API_KEY');
},
async track(event) {
await MySDK.logEvent(event.name, event.properties);
},
async screen(event) {
await MySDK.logScreen(event.name);
},
async identify(payload) {
await MySDK.setUser(payload.userId, payload.traits);
},
async reset() {
await MySDK.logout();
},
};TypeScript
Full types are exported:
import type {
AnalyticsConfig,
AnalyticsAdapter,
AnalyticsEvent,
ScreenEvent,
UserTraits,
SessionInfo,
EventMiddlewareFn,
ScreenMiddlewareFn,
PrivacyConfig,
QueueConfig,
SessionConfig,
} from 'react-native-analytics-bridge';License
MIT
Author
Oluwaseyi Roy (https://github.com/oluseyi-ged)
