Expo integration guide

Add Bugsnag to your Expo apps to report JavaScript errors.

New to Bugsnag? Create an account

Note for bare Expo apps

If you’re using the bare workflow or you’ve ejected your Expo app, you should follow the React Native guide.

You should continue with this guide if you’re using Expo’s managed workflow on supported platforms.

This documentation is for version 7 of the Bugsnag JavaScript notifier. If you are using older versions, we recommend upgrading to the latest release using our Upgrade guide. Documentation for the previous release can be found on our legacy pages.

Installation and configuration

The easiest way to add Bugsnag to your Expo project is to use our CLI (macOS and Linux only). Alternatively you can follow the manual setup guide.

# using npx (recommended)
npx bugsnag-expo-cli init

# using npm (if npx isn't available)
npm install --global bugsnag-expo-cli
bugsnag-expo-cli init

Note: npx (included with npm 5.2+) is a tool that lets you invoke command line tools from npm without installing them first.

This will install the @bugsnag/expo notifier, add some configuration to app.json and initialize Bugsnag in your application.

Capturing React render errors

An error boundary component is included which you can use to wrap your application. When render errors happen, they will be reported to Bugsnag along with any React-specific info that was available at the time.

To catch all render errors in your application and show a custom error screen to your users, follow this example:

const ErrorBoundary = Bugsnag.getPlugin('react').createErrorBoundary(React)

export default () =>
  <ErrorBoundary FallbackComponent={ErrorView}>
    <App />
  </ErrorBoundary>

class App extends React.Component {
  // Your main app component
}

class ErrorView extends React.Component {
  // This component will be displayed when an error boundary catches an error
}

When render errors happen, they will be reported to Bugsnag along with any React-specific info that was available at the time.

See React’s documentation on Error Boundaries to find out more.

In the dashboard, you’ll see errors reported with extra debugging info in a “React” tab. For example:

React error information in the the dashboard

Customizing the error boundary

The <ErrorBoundary /> component accepts some additional props:

  • onError() – this allows you to pass in an onError callback which runs only for errors caught by the error boundary.
  • FallbackComponent – by default the error boundary will attempt to re-render the child tree which may result in nothing being rendered at all. If you specify a <FallbackComponent/>, when an error happens Bugsnag will render this instead. This means you can display a user-friendly error state.
  • clearError() – resets the state of the error boundary which will cause a re-render the child tree instead of the <FallbackComponent/>.

TypeScript support

Type definitions are provided and will be picked up automatically by the TypeScript compiler when you import @bugsnag/expo.

Showing full stacktraces

Bugsnag supports showing full stacktraces for Expo release builds.

Using the provided postPublish hook, every time you publish a JS bundle with expo publish or build a standalone app with expo build:ios|android, your release will be reported to Bugsnag, along with its source maps.

If you used the CLI but didn’t choose to install the postPublish hook, you can add it with the following command:

npx bugsnag-expo-cli add-hook

Alternatively you can follow the manual setup guide.

Note: full stacktraces are not shown for errors that happen in development.

Reporting unhandled errors

After completing installation and basic configuration, unhandled exceptions and unhandled promise rejections will be reported and automatically appear on your Bugsnag dashboard.

In Expo SDK 39-40, unhandled promise rejections are not reported. This is due to multiple versions of the promise library in Expo’s dependencies, meaning that Bugsnag can’t pick up the correct one to track promise rejections. If you’re using yarn, you can add the following to your package.json to ensure only one version gets installed, meaning unhandled promise rejections can be reported:

  "resolutions": {
    "promise": "^8.0.3"
  }

Unhandled render errors will only be reported if you have wrapped your application in an error boundary.

Reporting handled errors

Sometimes it is useful to manually notify Bugsnag of a problem. To do this, call Bugsnag.notify(). For example:

try {
  something.risky()
} catch (e) {
  Bugsnag.notify(e)
}

When reporting handled errors, it’s often helpful to send custom diagnostic data or to adjust the severity of particular errors. For more information, see reporting handled errors.

Sending diagnostic data

Automatically captured diagnostics

As well as a full stacktrace for every exception, Bugsnag will automatically capture the following diagnostic data:

  • Full stack trace.
  • App state including running time and time in foreground.
  • Build information including name, version/build, release stage and whether the app is bundled as standalone.
  • Device specification including model, OS version and total memory.

For more information see Automatically captured data.

Attaching custom diagnostics

It can often be helpful to attach application-specific diagnostic data to error reports. This can be accomplished by setting a callback which will be invoked before any reports are sent to Bugsnag.

The following adds a map of data to the “company” tab on the Bugsnag dashboard for all captured events:

Bugsnag.start({
  onError: function (event) {
    event.addMetadata('company', {
      name: "Acme Co.",
      country: "uk"
    })
  }
})

For more information, see Customizing error reports.

Identifying users

In order to correlate errors with customer reports, or to see a list of users who experienced each error, it is helpful to capture and display user information on your Bugsnag dashboard.

You can set the user information of an error report using the user configuration property when Bugsnag starts or via an onError callback.

Bugsnag.start({
  onError: function (event) {
    event.setUser('3', 'bugs.nag@bugsnag.com', 'Bugs Nag')
  }
})

For information on doing so, see Adding user data.

Logging breadcrumbs

In order to understand what happened in your application before each crash, it can be helpful to leave short log statements that we call breadcrumbs. A configurable number of breadcrumbs are attached to each error report to help diagnose what events led to the error.

Automatically captured breadcrumbs

By default, Bugsnag captures the following events as breadcrumbs.

  • Errors
  • HTTP requests
  • Console logs, warnings, and errors
  • Orientation changes
  • App entering or exiting the foreground
  • Network state changes

For more information or to disable particular classes of automatic breadcrumb generation see configuration options.

Attaching custom breadcrumbs

You can use the leaveBreadcrumb method to log potentially useful events in your own applications:

Bugsnag.leaveBreadcrumb('Button clicked')

Bugsnag will keep track of the time and order of the breadcrumbs and show them on your dashboard. Additional data can also be attached to breadcrumbs by providing the optional metadata parameter.

For more information and examples for how custom breadcrumbs can be integrated, see Customizing breadcrumbs.

Tracking releases

Bugsnag will automatically associate your errors with the version of your application.

Using the provided postPublish hook, releases will be reported with build time metadata (source control revision, build time, JS bundle revision id).

Session tracking

Bugsnag tracks the number of “sessions” that happen within your application. This allows you to compare stability scores between releases and helps you to understand the quality of your releases.

Sessions are captured and reported by default. This behavior can be disabled using the autoTrackSessions configuration option.

In Expo a new session is recorded each time the app starts.

For more information about manually controlling session tracking, see Capturing sessions.

Next steps