Skip to main content

PnP React Native - v5 to v6

Overview

This guide provides a detailed step-by-step process to help you migrate your PnP React Native project from version 5 to version 6 of the SDK. This includes necessary changes to your metro.config.js and globals.ts files and updates for both bare React Native and Expo workflows.

Metro Configurations

Expo Workflow

Before:

const { getDefaultConfig } = require("expo/metro-config");

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

config.resolver.extraNodeModules = {
assert: require.resolve("empty-module"), // assert can be polyfilled here if needed
http: require.resolve("empty-module"), // stream-http can be polyfilled here if needed
https: require.resolve("empty-module"), // https-browserify can be polyfilled here if needed
os: require.resolve("empty-module"), // os-browserify can be polyfilled here if needed
url: require.resolve("empty-module"), // url can be polyfilled here if needed
zlib: require.resolve("empty-module"), // browserify-zlib can be polyfilled here if needed
path: require.resolve("empty-module"),
crypto: require.resolve("crypto-browserify"),
stream: require.resolve("readable-stream"),
buffer: require.resolve("buffer"),
};

config.transformer.getTransformOptions = () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
});

module.exports = config;

After:

const { getDefaultConfig } = require("expo/metro-config");

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

config.resolver.extraNodeModules = {
assert: require.resolve("empty-module"), // assert can be polyfilled here if needed
http: require.resolve("empty-module"), // stream-http can be polyfilled here if needed
https: require.resolve("empty-module"), // https-browserify can be polyfilled here if needed
os: require.resolve("empty-module"), // os-browserify can be polyfilled here if needed
url: require.resolve("empty-module"), // url can be polyfilled here if needed
zlib: require.resolve("empty-module"), // browserify-zlib can be polyfilled here if needed
path: require.resolve("empty-module"),
stream: require.resolve("readable-stream"),
buffer: require.resolve("buffer"),
};

config.resolver.resolveRequest = (context, moduleName, platform) => {
if (moduleName === "crypto") {
// when importing crypto, resolve to react-native-quick-crypto
return context.resolveRequest(context, "react-native-quick-crypto", platform);
}
// otherwise chain to the standard Metro resolver.
return context.resolveRequest(context, moduleName, platform);
};

config.transformer.getTransformOptions = () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
});

module.exports = config;

Updating globals.ts

Bare React Native Workflow

import { install } from "react-native-quick-crypto";

install();

// Needed so that 'stream-http' chooses the right default protocol.
// @ts-ignore
global.location = {
protocol: "file:",
};
// @ts-ignore
global.process.version = "v16.0.0";
if (!global.process.version) {
global.process = require("process");
console.log({ process: global.process });
}
// @ts-ignore
process.browser = true;

Expo Workflow

import "./globals";
import "@ethersproject/shims";
import "@expo/metro-runtime";

import { App } from "expo-router/build/qualified-entry";
import { renderRootComponent } from "expo-router/build/renderRootComponent";

// This file should only import and register the root. No components or exports
// should be added here.
renderRootComponent(App);
note

Make sure to install the react-native-quick-crypto module:

npm install react-native-quick-crypto

Updating index.ts

Bare React Native Workflow

import { AppRegistry } from "react-native";
import "./globals";
import App from "./App";
import { name as appName } from "./app.json";
AppRegistry.registerComponent(appName, () => App);

Expo Workflow

import "./globals";
import "@ethersproject/shims";
import "@expo/metro-runtime";

import { App } from "expo-router/build/qualified-entry";
import { renderRootComponent } from "expo-router/build/renderRootComponent";

// This file should only import and register the root. No components or exports
// should be added here.
renderRootComponent(App);