How to use Nutrient React Native SDK with Expo

Table of contents

    How to use Nutrient React Native SDK with Expo

    Expo(opens in a new tab) is a React Native(opens in a new tab) platform that significantly simplifies the process of developing, building, and testing React Native apps.

    But there’s one major downside with Expo(opens in a new tab), which is that it’s optimized to be used purely with JavaScript out of the box. Therefore, additional steps are needed for a developer to use any package that depends on native code. In fact, the native code isn’t even included in the project from the initial setup. To be able to run on the respective platform, the Expo Go(opens in a new tab) app is used to provide the necessary platform base.

    Nutrient React Native SDK is implemented on top of the existing native Nutrient Android and iOS SDKs. This means it won’t work in a project that runs in the Expo Go(opens in a new tab) app.

    In this blog post, you’ll learn how to install and configure Nutrient in an Expo(opens in a new tab) project.

    Prerequisites

    To get started, set up your environment by installing the following tools if you don’t have them installed already:

    Creating an Expo project

    You’ll start by creating a normal Expo(opens in a new tab) project. If you’re new to Expo(opens in a new tab), consider familiarizing yourself with the official Expo documentation(opens in a new tab).

    Use the command below to create a new project:

    Terminal window
    npx create-expo-app nutrient-expo

    In this example, the project is named nutrient-expo, but you can change it to one of your choice.

    Adding Nutrient React Native SDK

    Install Nutrient React Native SDK from npm:

    Terminal window
    npm install @nutrient-sdk/react-native

    Alternatively, you can use yarn:

    Terminal window
    yarn add @nutrient-sdk/react-native

    Configure app.json

    Nutrient doesn’t run in Expo Go(opens in a new tab) because it depends on native Android and iOS SDKs. With managed Expo, you declare those requirements in app.json using config plugins — the same settings apply for internal testing and App Store releases.

    Install Expo BuildProperties(opens in a new tab):

    Terminal window
    npx expo install expo-build-properties

    Add the following to app.json. Adjust SDK versions to match the getting started guides for your Nutrient React Native release.

    {
    "expo": {
    "plugins": [
    [
    "expo-build-properties",
    {
    "android": {
    "compileSdkVersion": 36,
    "targetSdkVersion": 36,
    "minSdkVersion": 24,
    "extraMavenRepos": [
    { "url": "https://my.nutrient.io/maven/" }
    ]
    },
    "ios": {
    "deploymentTarget": "17.0"
    }
    }
    ],
    "@nutrient-sdk/react-native"
    ],
    "ios": {
    "infoPlist": {
    "UIViewControllerBasedStatusBarAppearance": true
    }
    }
    }
    }

    List @nutrient-sdk/react-native after other plugins that touch Android styles (for example expo-splash-screen) so that the Nutrient config plugin patches AppTheme last.

    expo-build-properties configures Gradle and CocoaPods settings (Maven repository, SDK levels, deployment target). It does not set Info.plist keys. Nutrient requires view controller-based status bar appearance on iOS, so set UIViewControllerBasedStatusBarAppearance under expo.ios.infoPlist as shown above — not inside the expo-build-properties plugin block.

    Android theme (Expo SDK 55+): Expo’s default app theme on Android isn’t compatible with Nutrient and can cause an InvalidThemeException when opening a PDF. Include the @nutrient-sdk/react-native config plugin so the prebuild applies a compatible theme.

    After changing app.json, generate native projects and run on a device or simulator:

    Terminal window
    npx expo prebuild
    npx expo run:android
    Terminal window
    npx expo run:ios

    Use whichever command matches your platform. For building and distributing apps in CI or the cloud, follow Expo’s own guides — no extra Nutrient steps are required beyond this app.json configuration.

    For license keys and advanced setup, see the getting started guides and React Native guides.

    Opening a PDF

    To try Nutrient quickly, load a sample PDF from a remote URL. If you open a local file instead, it must be packaged with your app. On iOS, include it in the app bundle; on Android, place it under android/app/src/main/assets/. A remote URL skips that step for both platforms.

    Replace the contents of App.js with:

    import React, { Component } from 'react';
    import NutrientView from '@nutrient-sdk/react-native';
    import { NativeModules } from 'react-native';
    const Nutrient = NativeModules.Nutrient;
    Nutrient.setLicenseKey(null);
    const DOCUMENT =
    'https://www.nutrient.io/downloads/pspdfkit-react-native-quickstart-guide.pdf';
    export default class NutrientDemo extends Component {
    var pdfRef: React.RefObject<NutrientView | null> = React.createRef();
    render() {
    return (
    <NutrientView
    document={DOCUMENT}
    configuration={{
    showThumbnailBar: 'scrollable',
    pageTransition: 'scrollContinuous',
    scrollDirection: 'vertical',
    }}
    ref={this.pdfRef}
    fragmentTag="PDF1"
    style={{ flex: 1 }}
    />
    );
    }
    }

    Run the app again with npx expo run:android or npx expo run:ios. The PDF file will be downloaded and displayed in the Nutrient viewer. To customize remote file downloads, see open a document from a remote URL. To open documents from the local filesystem, see open a document from local storage.

    Nutrient won’t work when you run the project with expo start in Expo Go; the Nutrient native modules aren’t included in the Expo Go client.

    Conclusion

    This post showed how to integrate the Nutrient React Native SDK into an Expo project using app.json config plugins and a remote sample PDF. For full documentation, see the official guides.

    Julius Kato Mutumba

    Julius Kato Mutumba

    Hybrids Team Lead

    Julius joined PSPDFKit in 2021 as an Android engineer and is now the Cross-Platform Team Lead. He has a passion for exploring new technologies and solving everyday problems. His daily tools are Dart and Flutter, which he finds fascinating. Outside of work, he enjoys movies, running, and weightlifting.

    Explore related topics

    Try for free Ready to get started?