# SDK — React Native (/docs/sdk/react-native)



<Callout type="warn">
  **Status: alpha.** `@layers/react-native` is published to npm (current
  version at the time of writing: `2.2.0`). The API is still evolving and
  is pre-1.0 stable.
</Callout>

## Install [#install]

```bash
npm i @layers/react-native
cd ios && pod install
```

Peer dependencies (declared by the package):

* `react >= 18`
* `react-native >= 0.70`
* `@react-native-async-storage/async-storage >= 1.21`
* `@react-native-community/netinfo >= 11`

Autolinking handles the native binding for iOS (CocoaPods) and Android
(Gradle). For Expo managed projects, install `@layers/expo` instead.

## Initialize [#initialize]

```ts
// App.tsx
import { useEffect } from 'react';
import Layers from '@layers/react-native';

export default function App() {
  useEffect(() => {
    Layers.init({
      apiKey: 'unused-but-required-by-type',
      appId: 'app_xxx',
      environment: __DEV__ ? 'development' : 'production',
      enableDebug: __DEV__,
    });
  }, []);

  return <RootNavigator />;
}
```

Notes:

* The call is `Layers.init(...)`, not `Layers.configure(...)`.
* `apiKey` is required by the TypeScript type but the server currently
  only validates `appId` (the `X-Api-Key` header is accepted and
  ignored). Pass any non-empty string.
* The ingest endpoint is always `https://in.layers.com` by default;
  override with `baseUrl` if you're on a
  [custom domain](/docs/sdk/custom-domain).

## Track events [#track-events]

```ts
await Layers.track('purchase_success', {
  revenue: 9.99,
  currency: 'USD',
  product_id: 'premium_yearly',
  store: 'app_store',
});
```

Use canonical event names from [Standard events](/docs/sdk/standard-events)
where possible — names outside that set are stored in `sdk_events` but
dropped at the CAPI relay.

## Screen tracking [#screen-tracking]

```ts
await Layers.screen('Checkout', { cart_size: 3 });
```

For Expo Router apps, the package ships a helper:

```tsx
import { useLayersExpoRouterTracking, LayersExpoRouter } from '@layers/react-native';
import { usePathname, useGlobalSearchParams } from 'expo-router';

// In _layout.tsx
<LayersExpoRouter usePathname={usePathname} useGlobalSearchParams={useGlobalSearchParams} />
```

## Identify [#identify]

```ts
Layers.setAppUserId('user_42');
await Layers.setUserProperties({ plan: 'premium' });

// On logout
Layers.clearAppUserId();
```

Note: `setAppUserId` is synchronous. There is no `Layers.identify(id,
traits)` / `Layers.reset()` — use `setAppUserId` + `setUserProperties`
and `clearAppUserId` instead.

## Consent [#consent]

```ts
await Layers.setConsent({ advertising: true, analytics: true });
```

`setConsent` takes a `{ advertising?, analytics? }` object, not a
boolean. The remote-config endpoint can also gate advertising / analytics
globally via killswitches.

## ATT (iOS) [#att-ios]

```ts
await Layers.requestTracking(); // shows the system prompt
```

`Info.plist` entry is still required:

```xml
<key>NSUserTrackingUsageDescription</key>
<string>We use this to personalize your experience.</string>
```

## Connector & debug surface [#connector--debug-surface]

The SDK exposes several advanced surfaces that are **not guaranteed
stable** in the current alpha:

* `Layers.connectors.*` — per-network connector config/metrics
  (`meta`, `tiktok`, `snap`, `google`). Native pixel SDKs are NOT
  bundled; the server-side CAPI relay is what actually forwards events.
* `Layers.skan.*` — SKAdNetwork preset + rule management.
* `Layers.deepLinks.*` — deep-link configuration + listeners.
* `Layers.att.*` — ATT-specific helpers.
* `Layers.debug.*` — overlay, metric dumps. Use during development only.

Treat these as experimental — signatures may change before 1.0.

## Expo [#expo]

For Expo managed projects, use `@layers/expo` (which wraps this package
with a config plugin). See the [Expo guide](/docs/sdk/expo).
