---
title: "Capture App Start Errors"
description: "Learn how to capture app start errors and crashes that occur before JavaScript loads using native initialization."
url: https://docs.sentry.io/platforms/react-native/manual-setup/app-start-error-capture/
---

# Capture App Start Errors | Sentry for React Native

By default, the React Native SDK initializes the native SDK underneath the `init` method called on the JS layer. As a result, the SDK has a current limitation of not capturing native crashes that occur prior to the `init` method being called on the JS layer.

Starting with SDK version 8.0.0, you can initialize Sentry natively before JavaScript loads, enabling capture of app start errors and crashes that occur during:

* Native module initialization
* JavaScript bundle loading
* Early React Native bridge setup

This feature uses a `sentry.options.json` configuration file and native initialization APIs that read from this file.

##### SDK Version Requirement

This feature requires Sentry React Native SDK version 8.0.0 or higher.

## [Configuration File](https://docs.sentry.io/platforms/react-native/manual-setup/app-start-error-capture.md#configuration-file)

Create a `sentry.options.json` file in your React Native project root with the same options you currently have in `Sentry.init`:

`sentry.options.json`

```json
{
  "dsn": "https://key@example.io/value",
  "debug": true,
  "environment": "production",
  "tracesSampleRate": 1.0,
  "enableTracing": true
}
```

##### Options Merging

When `Sentry.init()` runs in JavaScript, the native SDK is re-initialized with the JS options merged on top of the file options. This means JavaScript options take precedence for events captured **after** JS loads.

However, crashes and errors that occur **before** JavaScript loads (which is the purpose of this feature) are captured using only the values from `sentry.options.json` and native auto-detection. If you set a custom `release` or `dist` in `Sentry.init()`, make sure the same values are also in `sentry.options.json`. Otherwise, pre-JS crashes will be attributed to a different release than post-JS events.

### [Setting the Environment](https://docs.sentry.io/platforms/react-native/manual-setup/app-start-error-capture.md#setting-the-environment)

If you need different `environment` values for build (e.g., production vs staging), set the `SENTRY_ENVIRONMENT` environment variable at build time. The SDK build scripts will use this to override the `environment` in your `sentry.options.json` without modifying the source file.

```bash
SENTRY_ENVIRONMENT=staging npx react-native run-android
```

This works in any CI/CD system by setting the environment variable in your build configuration.

### [Setting Release and Distribution](https://docs.sentry.io/platforms/react-native/manual-setup/app-start-error-capture.md#setting-release-and-distribution)

If you use a custom `release` or `dist` in `Sentry.init()`, you should set matching values in `sentry.options.json` so that pre-JavaScript crashes are attributed to the correct release:

`sentry.options.json`

```json
{
  "dsn": "https://key@example.io/value",
  "release": "my-app@1.0.0+42",
  "dist": "42"
}
```

For dynamic values that change per build, set the `SENTRY_RELEASE` and `SENTRY_DIST` environment variables at build time. The SDK build scripts will use these to override the values in your `sentry.options.json`, similar to how `SENTRY_ENVIRONMENT` works.

```bash
SENTRY_RELEASE="my-app@1.0.0+42" SENTRY_DIST="42" npx react-native run-ios
```

##### Release Alignment

If the `release` or `dist` in `sentry.options.json` doesn't match what you pass to `Sentry.init()`, you'll see two separate releases in Sentry — one for native crashes captured before JS loads and another for events captured after. Make sure both sources use the same values.

## [Android Setup](https://docs.sentry.io/platforms/react-native/manual-setup/app-start-error-capture.md#android-setup)

Initialize Sentry in your `MainApplication` class:

```kotlin
import io.sentry.react.RNSentrySDK

class MainApplication : Application(), ReactApplication {
    override fun onCreate() {
        super.onCreate()
        RNSentrySDK.init(this)
        // ... rest of your initialization code
    }
}
```

## [iOS Setup](https://docs.sentry.io/platforms/react-native/manual-setup/app-start-error-capture.md#ios-setup)

Initialize Sentry in your `AppDelegate` before starting React Native so app start crashes are captured.

```objective-c
#import <RNSentry/RNSentry.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [RNSentrySDK start];
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end
```

## [Expo Setup](https://docs.sentry.io/platforms/react-native/manual-setup/app-start-error-capture.md#expo-setup)

If you're using Expo, you can enable native initialization using the Expo plugin. Add the `useNativeInit` option and your SDK options to the plugin configuration:

`app.json`

```json
{
  "expo": {
    "plugins": [
      [
        "@sentry/react-native/expo",
        {
          "useNativeInit": true,
          "options": {
            "dsn": "https://key@example.io/value",
            "environment": "production",
            "tracesSampleRate": 1.0
          }
        }
      ]
    ]
  }
}
```

The plugin generates a `sentry.options.json` file from the `options` property during `expo prebuild`. If a `sentry.options.json` file already exists in your project root, the plugin options are merged into it (plugin options take precedence).

If you need to use environment variables or dynamic configuration, you can use `app.config.js` with the `withSentry()` wrapper instead of the array form in `app.json`:

`app.config.js`

```javascript
import { withSentry } from "@sentry/react-native/expo";

export default withSentry(config, {
  useNativeInit: true,
  options: {
    dsn: "https://key@example.io/value",
    environment: "production",
    tracesSampleRate: 1.0,
  },
});
```

When `useNativeInit` is set to `true`, the Expo plugin automatically:

* Adds `RNSentrySDK.init()` to your Android `MainApplication`
* Adds `RNSentrySDK.start()` to your iOS `AppDelegate`

### [Setting the Environment](https://docs.sentry.io/platforms/react-native/manual-setup/app-start-error-capture.md#setting-the-environment-1)

You can set the `environment` using the plugin `options` property as shown above, or using the `SENTRY_ENVIRONMENT` environment variable. The environment variable takes precedence over the plugin option.

For per-environment builds with EAS Build, set `SENTRY_ENVIRONMENT` in your build profiles. You can also set `SENTRY_RELEASE` and `SENTRY_DIST` if you use custom release names:

`eas.json`

```json
{
  "build": {
    "production": {
      "env": {
        "SENTRY_ENVIRONMENT": "production",
        "SENTRY_RELEASE": "my-app@1.0.0+42",
        "SENTRY_DIST": "42"
      }
    },
    "staging": {
      "env": {
        "SENTRY_ENVIRONMENT": "staging"
      }
    }
  }
}
```
