> For the complete documentation index, see [llms.txt](/llms.txt).

# Bundler polyfill issues - React Native Metro

While setting up a new Web3 project from scratch, you might face bundler issues. This can occur because the core packages like `eccrypto` have dependencies which are not present within the build environment.

To rectify this, the go-to method is to add the missing modules directly into the package, and edit the bundler configuration to use those. Although this approach works, it can significantly increase bundle size, leading to slower load times and a degraded user experience.

Some libraries rely on environment-specific modules that may be available at runtime in the browser even if they are not bundled. Libraries such as Embedded Wallets' Web3Auth take advantage of this behavior and can function correctly without bundling all modules. However, if you are using a library that does not take advantage of this, you might face issues.

To avoid unnecessary overhead, include only the required polyfills, test functionality with care, and configure your bundler to ignore unresolved modules rather than including them in the final build.

tip

We recommend that you require certain Node polyfills to be added to your project, while testing each of its functionalities. At the same time, instruct the bundler to ignore the missing modules, and not include them in the build.

In this guide, we provide instructions for adding polyfills in React Native Metro. The steps install the missing libraries required for module resolution and then configures Metro so they are not bundled unless needed at runtime.

## Step 1: Install the missing modules[​](#step-1-install-the-missing-modules "Direct link to Step 1: Install the missing modules")

Check for the missing libraries in your build and included packages, and polyfill these. For Web3Auth, you need to polyfill the `buffer`, `process`, `crypto` and `stream` libraries. For the rest of the libraries, we are installing a dummy module called `empty-module` which helps us get rid of the warnings while building the project.

- npm
- Yarn
- pnpm
- Bun

```
npm install --save empty-module readable-stream crypto-browserify react-native-get-random-values buffer process

```

```
yarn add empty-module readable-stream crypto-browserify react-native-get-random-values buffer process

```

```
pnpm add empty-module readable-stream crypto-browserify react-native-get-random-values buffer process

```

```
bun add empty-module readable-stream crypto-browserify react-native-get-random-values buffer process

```

warning

If you're using any other blockchain library alongside Web3Auth, it's possible that you might need to polyfill more libraries. Typically, the libraries like `browserify-zlib`, `assert`, `stream-http`, `https-browserify`, `os-browserify`, `url` are commonly required.

## Step 2: Update your `metro.config.js`[​](#step-2-update-your-metroconfigjs "Direct link to step-2-update-your-metroconfigjs")

To make use of the polyfilled modules while building the application, you need to reconfigure your metro bundler config.

Expo-managed workflow

Create a `metro.config.js` for an expo-managed workflow, as it is not present by default.

Learn more about [customizing a metro bundler](https://docs.expo.dev/guides/customizing-metro/).

Note that polyfilling is not supported with "Expo Go" app. It's compatible only with Custom Dev Client and Expo Application Services (EAS) builds. Please [prebuild your expo app](https://docs.expo.dev/workflow/continuous-native-generation/#usage)to generate native code based on the version of expo a project has installed, before progressing.

You can copy the following code in your `metro.config.js` file. This will tell the bundler to ignore the missing modules and include those that are needed.

#### `metro.config.js`[​](#metroconfigjs "Direct link to metroconfigjs")

- Bare React Native
- Expo

metro.config.js

```
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config')

const defaultConfig = getDefaultConfig(__dirname)

const 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'),
    },
    sourceExts: [...defaultConfig.resolver.sourceExts, 'svg'],
  },
}

module.exports = mergeConfig(defaultConfig, config)

```

metro.config.js

```
// Learn more https://docs.expo.io/guides/customizing-metro
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

```

## Step 3: Fix additional dependency issues[​](#step-3-fix-additional-dependency-issues "Direct link to Step 3: Fix additional dependency issues")

1. Create a `globals.js` at your project root directory and add the following code to it:

globals.js

```
global.Buffer = require('buffer').Buffer

// Needed so that 'stream-http' chooses the right default protocol.
global.location = {
  protocol: 'file:',
}

global.process.version = 'v16.0.0'
if (!global.process.version) {
  global.process = require('process')
  console.log({ process: global.process })
}

process.browser = true

```

1. Import the dependencies to `index.js` of your project.

info

For Expo apps, you need to create an entry point, that is, the index.js file. This can be done by following the [naming guide](https://docs.expo.dev/versions/latest/sdk/expo/#what-if-i-want-to-name-my-main-app-file-something-other-than-appjs-or-app%5Flayouttsx)

- Bare React Native
- Expo

index.js

```
import { AppRegistry } from 'react-native'
import './globals'
import 'react-native-get-random-values'
import App from './App'
import { name as appName } from './app.json'
AppRegistry.registerComponent(appName, () => App)

```

index.js

```
import '@ethersproject/shims'
import '@expo/metro-runtime'
import 'react-native-get-random-values'
import './globals'

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)

```
