Upgrading react-scripts to v5 without Craco - for idiots.
Tags: react, webpack
Published: 2023-03-14 15:45:39


_tl;dr - If you're using Create-React-App and trying to upgrade react-scripts to v5, you need to remove/replace any packages that have dependencies which are intended for use in the node runtime, rather than in the browser. There is no way in create-react-app to adjust the config without use of craco/react-app-rewired/ejecting, so you can't provide browser-compatible fallbacks, as the error messaging suggests. Your only option is to stop using any packages which are themselves intended for a Node environment or, trickier, any packages which depend on such packages._

If you maintain an app created with Create-React-App (CRA), and are reading this article, you're probably aware that react-scripts (the main package in CRA, besides the CLI portion) v5, webpack is also upgraded to v5, and that the webpack v5 upgrade drops supports for browser polyfills for node packages. ("Browser polyfills for node packages" is a fancy way of saying that Webpack would automatically load a web-based alternative if it encountered a package intended for a Node environment.)
This is the part that gets confusing. What does that mean for you?
Well, first of all, if you try to upgrade react-scripts , you may get lots of error messages like
```
Error: Can't resolve 'fs' in '../node_modules/dotenv/lib'
```
Basically, Webpack is refusing to use packages meant to run in node (i.e., backend packages) in your browser code.
The thread discussing this on the CRA Github repo has hundreds of angry responses, as well as a bunch of proposed solutions - most of them based on craco or react-app-rewired , packages that allow you to modify CRA's config without ejecting. There's also a PR against CRA to add back in an escape hatch, but it's a year old, and the creator of the PR said in August of 2022 that they didn't have time for it anymore. So it's not clear that waiting for a fix is a great option. [Update: This PR was closed in April 2023, so it's definitely not happening.]
If you want to use craco or react-app-rewired , you're probably all set. But what if you don't (as many larger-scale apps do not)? In that case, the solution is less clear.
The key point here is that, unlike if you're using Webpack directly, with CRA you can't directly edit the Webpack setup, so you can't follow the advice in the error messages to add browser fallbacks for your node packages. This is why people are frustrated - this means that, if a package you're using depends on a node package, you can't use that package. And there's not really a lot you can do about it.
That was the key point that took me awhile to understand - that the console errors I was getting about adding browser-compatible fallback modules did not apply to me, because I was using CRA. Instead, the only solution was to remove the packages that were dependent on node packages.
This may not be an easy pill to swallow. But for our repo, it happened to be pretty easy, so it's at least worth checking and seeing how much you really need those packages that have node-based dependencies.
I will mention one other solution I saw in the ginormous thread on this topic, which seemed promising, but I didn't try - user fernandocamargo just added aliases in their package.json , like so:
```json
"buffer": "^6.0.3",
"crypto": "npm:crypto-browserify",
"stream": "npm:stream-browserify",
```
I haven't tried this, but it was the one non- craco / react-app-rewired solution I saw, and had some positive emoji reactions.
Whatever path you choose, good luck.