> ## Documentation Index
> Fetch the complete documentation index at: https://docs.linkrunner.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Expo SDK

> Complete guide for integrating Linkrunner in Expo apps

<Note>
  **Prefer to let your AI coding agent do this?** Install the Linkrunner skill and Claude Code, Cursor, GitHub Copilot, or Windsurf will wire up the SDK and deep links for you:

  ```bash theme={null}
  npx @linkrunner/skills add expo
  ```

  Then ask your agent to "integrate Linkrunner". See [Linkrunner Agent Skills](https://github.com/linkrunner-labs/skills).
</Note>

This guide will help you install, configure, and use the Linkrunner SDK in your Expo application.

<Info>
  **Migrating from an older version?** For instructions on upgrading from 1.x.x/2.x.x to version 3.x.x, see the
  [Migration Guide](#migration-guide) below.
</Info>

## Requirements

* Expo SDK 52.0 or higher
* Node.js 18.0 or higher
* React Native 0.70 or higher

## Installation

### Step 1: Install Both Packages

Install both the React Native and Expo packages:

```bash theme={null}
npm install rn-linkrunner

npx expo install expo-linkrunner
```

### Step 2: Add Plugin to app.json

**Important**: You must add the expo-linkrunner plugin to your `app.json` plugins array:

```json theme={null}
{
    "expo": {
        "plugins": [
            [
                "expo-linkrunner",
                {
                    "userTrackingPermission": "This identifier will be used to deliver personalized ads.",
                    "debug": true
                }
            ]
        ]
    }
}
```

## What the `expo-linkrunner` Plugin Does

When you add `expo-linkrunner` to your `app.json` plugins and run the Expo prebuild step, the config plugin automatically makes the following changes to your iOS project:

* **Adds `NSUserTrackingUsageDescription`** in your iOS `Info.plist` if not already present (skipped when `disableIdfa` is set).
* **Adds the SKAdNetwork postback keys** `NSAdvertisingAttributionReportEndpoint` and `AttributionCopyEndpoint` (both set to `https://linkrunner-skan.com`) in your iOS `Info.plist` if not already present, so Apple sends SKAN postback copies to Linkrunner.

These changes are required for IDFA (Identifier for Advertisers) tracking, Apple's App Tracking Transparency (ATT) compliance, and SKAN attribution. For complete SKAdNetwork integration details, see the [SKAdNetwork Integration Guide](/features/skadnetwork-integration).

### Step 3: Prebuild Your Project

The `expo-linkrunner` package is a config plugin that automatically configures your Expo project for Linkrunner SDK integration. Once you've completed the installation and configuration steps above:

* **For EAS Build**: If your `android` and `ios` folders are in `.gitignore` (recommended), EAS Build will automatically run the prebuild step during the build process. No manual action required.

* **For local development or custom development clients**:
  ```bash theme={null}
  npx expo prebuild
  ```

### Step 4: Android Backup Configuration

For Android apps, the SDK provides backup rules to exclude Shared Preferences data from backup. This prevents the retention of the Linkrunner install ID during reinstallation, ensuring accurate detection of new installs and re-installs.

For detailed backup configuration instructions, please refer to the [Android SDK Backup Configuration](/sdk/android/installation#backup-configuration).

### Google Integrated Conversion Measurement (Optional)

Integrated Conversion Measurement (ICM) recovers Google App Campaign installs on iOS that Google cannot attribute because there is no click identifier and no IDFA to match on. Google's On-Device Measurement (ODM) SDK turns the click context into an encrypted signal that never leaves the device, and Linkrunner sends it with the install. See [Google ICM](/features/google-icm) for how it works.

Set this up if you run Google App Campaigns for your iOS app. Requires `rn-linkrunner` 3.1.0 or later.

<Note>
  Google keeps ODM inactive for users in the European Economic Area, the United Kingdom, and Switzerland, so ICM recovers nothing for that traffic. Elsewhere, Google reports improved coverage for iOS 14+ users.
</Note>

<Note>
  ICM also needs an **iOS link ID** configured in your Google Ads integration. Google has nowhere to send the conversion without one. See [Prerequisites](/features/google-icm#prerequisites).
</Note>

<Steps>
  <Step title="Add Google's On-Device Measurement SDK to the iOS build">
    <Note>
      Already using the Firebase iOS SDK 11.14.0 or later? The `FirebaseAnalytics` pod brings this SDK in for you. Skip this step.
    </Note>

    `rn-linkrunner` does not bundle this SDK, so apps that skip ICM carry none of its weight. Expo generates the `Podfile`, so add the pod through `expo-build-properties`:

    ```bash theme={null}
    npx expo install expo-build-properties
    ```

    ```json theme={null}
    {
        "expo": {
            "plugins": [
                [
                    "expo-build-properties",
                    {
                        "ios": {
                            "extraPods": [{ "name": "GoogleAdsOnDeviceConversion" }]
                        }
                    }
                ]
            ]
        }
    }
    ```

    CocoaPods adds the `-ObjC` and `-lc++` linker flags for you, so there are no Xcode Build Settings to change.

    <Note>
      If you manage `ios/` yourself instead of generating it, add `pod 'GoogleAdsOnDeviceConversion'` to `ios/Podfile` and run `pod install`.
    </Note>
  </Step>

  <Step title="Rebuild your development client">
    ```bash theme={null}
    npx expo prebuild --clean
    ```

    ICM needs native code, so it does not work in Expo Go. Build a development client or run an EAS build.
  </Step>

  <Step title="Report consent">
    Set the values with `setConsent` before you call `init`:

    ```javascript theme={null}
    import linkrunner from "rn-linkrunner";

    linkrunner.setConsent({
        isEEA: "granted",
        hasConsentForDataUsage: "granted",
        hasConsentForAdsPersonalization: "denied",
    });

    await linkrunner.init("YOUR_PROJECT_TOKEN");
    ```

    See [Google Integrated Conversion Measurement](/sdk/react-native#google-integrated-conversion-measurement-optional) in the React Native guide for what each signal means and how to verify the setup. **For users outside the EEA, the UK, and Switzerland, report `isEEA` as denied and leave the other two unset.** See [Send Consent](/features/send-consent).
  </Step>
</Steps>

## SDK Usage

<Note>
  The `expo-linkrunner` plugin handles the native configuration automatically. All SDK methods and APIs are provided
  by the `rn-linkrunner` package, which is why you'll use the React Native documentation for implementation details.
</Note>

Since `expo-linkrunner` is a config plugin that prepares your project, the actual SDK usage is identical to React Native. Please refer to the [React Native SDK Guide](/sdk/react-native) for:

* Initializing the SDK
* User registration
* Handling deep links with `handleDeeplink`
* Getting attribution data
* Setting user data
* Tracking custom events
* Revenue tracking
* Ecommerce Events
* Enhanced privacy controls

## Migration Guide

If you are using expo-linkrunner with v1.x.x or v2.x.x then moving forward you'll need to migrate to a v3.x.x.

### Architecture Changes

Starting with version 3.0.0, the Expo SDK has been redesigned to use a new architecture:

* **Config Plugin Architecture**: The SDK now uses an Expo config plugin for better integration with the Expo ecosystem
* **React Native SDK**: Business logic is now handled by the React Native SDK, ensuring consistency across platforms
* **Improved Developer Experience**: Simplified setup with automatic native configuration

### Breaking Changes

* The package installation process has changed to require both React Native and Expo SDKs
* Plugin configuration is now required in `app.json`
* All SDK methods and APIs are now provided by the `rn-linkrunner` package

### Migration Steps

1. **Uninstall the old package**:

   ```bash theme={null}
   npx expo uninstall expo-linkrunner
   ```

2. **Install the new version**:

   Follow the [Installation](#installation) steps above to install both `rn-linkrunner` and `expo-linkrunner`.

3. **Update your code to use `rn-linkrunner`**:

   The `expo-linkrunner` package is now just a config plugin. All SDK methods and APIs are now provided by the `rn-linkrunner` package. You'll need to update your imports and usage accordingly.

   For detailed implementation instructions, see the [SDK Usage](#sdk-usage) section above.

## Next Steps

<CardGroup cols={2}>
  <Card title="Test Your Integration" icon="flask" href="/testing/integration-testing">
    Validate your setup end-to-end
  </Card>

  <Card title="Set Up Deep Linking" icon="link" href="/features/deep-linking-setup">
    Configure deep links for your app
  </Card>
</CardGroup>

## Support

If you encounter issues during integration, contact us at [support@linkrunner.io](mailto:support@linkrunner.io).
