Fix Web3 Package Dependency Issues in React Using Polyfills

If you're on this page, you're probably in the middle of your create-react-app
project hacking away, so let's skip the intro and get right to it!
The Overview
- Install
react-app-rewired
- Identify the polyfill needed (e.g.
stream
). - Check this list for what polyfill package to use (e.g.
stream-browserify
forstream
) and install it. - Configure
config-overrides.js
. - Modify
package.json
to usereact-app-rewired
. - Restart the server and enjoy!
The Error

I know. Is it frustrating? Luckily we have you covered.
Before Webpack 5 shipped, Webpack 4 automatically polyfilled a lot of core modules for Node in the browser. This system, despite its convenience, tucks large amounts of code into your build as well as prevents you from having control over the polyfills you will use.
This means that for Webpack 5, you have to choose which polyfill you'll use and configure Webpack with the polyfills you'll need.

The Poly– what? The Polyfills.
As we are on the edge of Web3 innovation, some older browsers can't keep up with modern browser functionalities. With this, we have pieces of code called polyfills that can be used to give older browsers some modern functionalities.
You can think of it as browser boosters to give older browsers a chance to keep up with today's innovations. (BLAST OFF! 🚀)

The Tutorial
The thirdweb Way
Use our create-react-app
starter template to get you started with polyfills included. Â I repeat, with polyfills included so you don't have to do anything else to set it up!
You can get started with these templates by running:
npx thirdweb create --app
The react-app-rewired
Way
If you're too far into your project, and can't start with thirdweb's starter template, this one's for you.
1. Install react-app-rewired
as dev dependency
yarn add --dev react-app-rewired # yarn
npm install --save-dev react-app-rewired # npm
2. Identify polyfills needed
The easiest and fastest way to identify what polyfills you need is to run your build and read the error logs.
yarn run start # yarn
npm run start # npm
Identify errors that contain:
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it.

It's your indicator that you are currently experiencing a polyfill error. Now notice how stream
is highlighted below together with a suggested solution for the polyfill?
It states that you can use resolve.fallback: { "stream": require.resolve(""stream-browserify)}
to enable a polyfill for stream
.

This is the same for other polyfills with the complete list in this Webpack repo on Github.
You can also solve this error by disabling the polyfill as suggested below:
Importate Note: Disabling the polyfill means some functions in your build may not work in older browsers.

3. Install missing dependencies
Now that you have identified that the missing polyfill is stream
and its dependency isstream-browserify
install it using your package manager.
yarn add --dev stream-browserify # yarn
npm install --save-dev stream-browserify # npm
4. Configure polyfills with config-overrides.js
We have identified that the polyfill that can't be found is stream
and you can choose to either disable or enable it.
First create a file called: config-overrides.js
in your root directory.
In order to enable the stream
polyfill use stream: require.resolve("stream-browserify")
in your config-overrides.js
like below.
Tip: If you're wondering where "stream-browserify" came from, check this list over here.
const webpack = require("webpack");
module.exports = function override(config) {
const fallback = config.resolve.fallback || {};
Object.assign(fallback, {
// ENABLE OR DISABLE YOUR POLYFILLS HERE
stream: require.resolve("stream-browserify"),
});
config.resolve.fallback = fallback;
config.plugins = (config.plugins || []).concat([
new webpack.ProvidePlugin({
process: "process/browser",
Buffer: ["buffer", "Buffer"],
}),
]);
config.resolve.extensions.push(".mjs");
config.module.rules.push({
test: /\.m?js/,
resolve: {
fullySpecified: false,
},
});
return config;
};
If you want to disable the stream
polyfill use stream: false
like below.
Importate Note: Disabling the polyfill means some functions in your build may not work in older browsers.
const webpack = require("webpack");
module.exports = function override(config) {
const fallback = config.resolve.fallback || {};
Object.assign(fallback, {
// ENABLE OR DISABLE YOUR POLYFILLS HERE
stream: false
});
config.resolve.fallback = fallback;
config.plugins = (config.plugins || []).concat([
new webpack.ProvidePlugin({
process: "process/browser",
Buffer: ["buffer", "Buffer"],
}),
]);
config.resolve.extensions.push(".mjs");
config.module.rules.push({
test: /\.m?js/,
resolve: {
fullySpecified: false,
},
});
return config;
};
5. Modify package.json
scripts to use react-app-rewired
Now that you're done installing react-app-rewired
and you're done configuring your config-overrides.js
it's time to change your package.json
to use react-app-rewired like below:
Note:eject
is intentionally left withreact-scripts eject
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
},
Restart your server and that's it! You're done! (SHEESH!)
The Conclusion
Giving the code you need straight on is quick and easy, but understanding polyfills will not only allow you to solve the bug but also give you perspective on why they matter.
But once again, you can always skip these, by using our create-react-app
starter template with thirdweb.