Skip to Content
DevelopersSDKsReact Native SDKQuickstart

React Native SDK

The Active Reach React Native SDK provides a TypeScript API that bridges to native iOS and Android SDKs for tracking, identity, and push notifications.

Current version: @active-reach/[email protected].

Brand canon. The npm package is @active-reach/react-native-sdk, but the TypeScript class you import is still Aegis. The bridge delegates to the underlying iOS (ActiveReachSDK) and Android (ai.active-reach:android-sdk) SDKs — “Aegis” is the internal source-tree name; “Active Reach” is the customer-facing identifier across npm, CocoaPods, and Maven.

Installation

npm install @active-reach/react-native-sdk

Initialization

Initialize once in your app entry point:

import { Aegis } from '@active-reach/react-native-sdk'; export default function App() { useEffect(() => { Aegis.init('YOUR_WRITE_KEY', { workspace_id: 'YOUR_WORKSPACE_ID', }); }, []); return <Navigation />; }

Core tracking

// Track a custom event Aegis.track('order_completed', { order_id: 'ORD-123', amount: 4999, currency: 'INR', }); // Identify a user Aegis.identify('user_456', { name: 'Priya Sharma', email: '[email protected]', plan: 'pro', }); // Track a screen view Aegis.screen('Product Detail', { product_id: 'SKU-A' }); // Group, alias, reset, flush — same API as Web SDK Aegis.group('company_789', { name: 'Acme Corp' }); Aegis.alias('user_456'); Aegis.reset(); Aegis.flush();

The React Native SDK shares the same method signatures as the Web SDK. If you’ve used the Web SDK, the API is identical. Native bridges for push token registration and deep linking are in progress.

Event governance

The React Native bridge exposes the same ingestGovernanceHint API as the other SDKs — the actual Bloom filter and hash math run on the native side (iOS uses ActiveReachSDK.NameGovernor, Android uses ai.aegis.sdk.governance.NameGovernor), so drops happen without round-tripping through JS.

Integration

import Aegis, { EventGovernanceHint } from '@active-reach/react-native-sdk'; // 1. Bootstrap against control-plane (JS fetch is fine — no native call needed here). const resp = await fetch('https://api.active-reach.ai/v1/sdk/bootstrap', { method: 'POST', body: JSON.stringify({ writeKey: WRITE_KEY, currentOrigin: 'mobile-app' }), }); const bootstrap = await resp.json(); // 2. Initialize the SDK. await Aegis.initialize(WRITE_KEY, { apiHost: 'https://api.active-reach.ai' }); // 3. Forward the hint to the native governor. Aegis.ingestGovernanceHint(bootstrap.eventGovernance);

Pass null or undefined to disable (fail-open):

Aegis.ingestGovernanceHint(null);

The hint type (exported)

export interface EventGovernanceHint { bloom_algo: string; // always "mmh3_x86_32_km" seed_a: number; // always 0 seed_b: number; // always 1 k: number; m: number; bloom_b64: string; remaining_new_names: number | null; grace_active?: boolean; ttl_seconds: number; }

Snake_case on the wire — the native bridge hand-decodes into the typed Swift / Kotlin structs so numeric fields stay Int rather than RN’s default Double.

What you get

Full parity with the standalone iOS + Android SDKs — novel event names past the cap are dropped on-device in native code before they hit the JS bridge, the gateway, or the network. Drops emit a coalesced aegis.client.name_governor_dropped meta event on the next flush.

See Event governance concept for the full story.

E-commerce + governance + cell selection (Phase 1, SDK ≥1.1.0)

import aegis from '@active-reach/react-native-sdk'; await aegis.initialize('YOUR_WRITE_KEY', { cellEndpoints: [ { region: 'ap-south', url: 'https://ap-south.api.aegis.ai' }, ], preferredRegion: 'ap-south', workspaceId: 'ws_abc123', }); // Bootstrap auto-arms NameGovernor with the returned EventGovernanceHint. const result = await aegis.bootstrap(); const product = { product_id: 'sku-42', name: 'Cotton Tee', price: 1299 }; aegis.ecommerce.productViewed(product); aegis.ecommerce.addToCart(product); aegis.ecommerce.productWaitlisted({ product, channels: ['whatsapp'] });

identify() + group() run a TS-side TraitGovernor that mirrors the cell-plane backend’s ingestion guards — console.warn lines surface in your dev tools before the bad data crosses the bridge.

Preload-first renderers (1.6.0)

Version 1.6.0 ships five preload-first in-app renderers so every render_type the cell-plane can dispatch has a matching React Native component. “Preload-first” means each renderer fetches and caches its assets before display — the campaign appears with images / copy already resolved, not as a flash-of-empty-modal followed by content.

The renderers are exported as standalone React Native components plus a PreloadFirstRenderer dispatch entrypoint that picks the right one for an incoming campaign:

Renderercampaign.type
CarouselCardsRenderercarousel_cards
StickyBarRenderersticky_bar
ProgressBarRendererprogress_bar
CoachmarkTourRenderercoachmark_tour
ProductRecommendationRendererproduct_recommendation
import { PreloadFirstRenderer } from '@active-reach/react-native-sdk'; function CampaignOverlay({ campaign }) { return ( <PreloadFirstRenderer campaign={campaign} listener={(campaignId, event, properties) => { // event is 'in_app.displayed' | 'in_app.clicked' | 'in_app.dismissed' Aegis.acknowledgeCampaign(campaignId, event, properties); }} /> ); }

Each renderer emits the standard lifecycle triplet — in_app.displayed when it mounts, in_app.clicked on the primary action, in_app.dismissed when the customer closes it (or auto-hide expires for sticky bars). Wire those into Aegis.acknowledgeCampaign so the cell-plane’s campaign analytics + frequency-cap evaluation see the engagement.

The same five renderers ship on iOS (AegisInApp.PreloadFirstRenderers), Android (ai.aegis.sdk.inapp.preload.PreloadFirstRenderers), and Flutter — all four SDKs reach feature parity on the render-type matrix this release. The cross-SDK contract is pinned by libs/mobile-sdk/tests/drift/preload-first-renderers.json + the per-renderer rows in campaign-render-types.json (status: supported_phase_3_5).

Visual polish is tracked under Phase 3.6 — the current MVPs use native dialog primitives. The web equivalents are bespoke; mobile parity ships first to close the dispatch-coverage gap.

Push engagement reporting (SDK ≥1.4.0)

Aegis.push posts push lifecycle events to the canonical ingestion endpoint by delegating to the native SDK on each platform — there is nothing extra to call from JS once the SDK is initialised and you have wired the native push integrations (FCM on Android, APNs on iOS).

import { Aegis } from '@active-reach/react-native-sdk'; // Register the device token returned by your push library // (e.g. @react-native-firebase/messaging or react-native-push-notification). Aegis.push.registerDeviceToken(token, 'android'); // Native side automatically fires push.delivered / .clicked / .dismissed // on the canonical /v1/push/engagement endpoint. No JS bridge involved // for the lifecycle signals themselves.

Wire shape: POST /v1/push/engagement — see Event ingestion.

What’s next