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)