After working half a year with React and it’s ecosystem, I thought it was a good moment to analyze the things I’d like to take into account on future React projects.
These are mostly related with custom build configuration and improvements over the default configurations that we get while using popular tooling.
Create React App
On my first important project with React I decided to start off using the popular
create-react-app module, which let’s us create react apps with no build configuration.
At that moment, to integrate a library like PIXI.js we had to configure Webpack like the following gist:
Luckily, the PIXI community figured out how to import the library as a ES6 module in v4.1.1 so we don’t need to have a special configuration anymore.
Ejecting from a Create React App means that we won’t be able to upgrade
react-scripts (the module that contains the build configuration) whenever the community releases a new version.
And this is really important in order to stay up to date with the latest releases of each dependency and build configuration updates, which believe me, we want to have in our projects since each release includes important bug fixes and improvements.
So, what’s the alternative to ejecting?
create-react-app project itself, making the necessary changes to
react-scripts and publishing a new
npm package with these changes.
Sounds easy, right? :D
Well, before even starting to implement this approach, we need to understand that the
create-react-app Git repository is a monorepo.
That means it’s team decided to include most of the packages, built in favor of creating the
create-react-app module, in the same Git repository.
We’ll find a
packages/ directory in the repository which contains
npm packages such as
You can learn more about monorepos management at lerna.
So, in order to make changes to
react-scripts and publishing to a new
npm package, we first need to fork
My own fork, and specifically the custom
react-scripts module, can be found at
One of the most important things I wanted to change in the default Webpack configuration was to allow import of modules relative to the
Let’s say we are working in a component
Foo located deep in the
src/ directory structure and we want to use
Bar which is way up in the directory hierarchy.
By configuring Webpack to search for modules relative to
src/, we can get rid of the nasty
../../../../ in the import path.
You can find out how to do it in this commit.
There are other reasons for having to modify
react-scripts, like supporting SASS (implemented in this commit) or integrating a library like PIXI.js.
I’d love to hear more examples in the comments section.
Publish to npm
Now that we have the changes in place, we need to publish them in a new
In order to do that, we’ll have to rename the
packages/react-scripts/package.json package name, let’s say to
npm publish and that’s it, we have a brand new
For instance, my custom
aaccurso-react-scripts package can be found here.
The scope of this post doesn’t include topics such as release management of
npmpackages. However, you can find more information about this in the npm docs.
To get notified of changes in the base repository of our fork we can use backstroke.
This tool will create and maintain a PR on our fork whenever there are new changes in the base repository.
Then we can decide how and when to include those changes in our fork, and by doing that we’d be upgrading to the latest version of the base
My React App
Now that we have our own custom
my-react-scripts-fork, how do we use it in our project?
If it’s a project we already created, we just need to
npm uninstall --save-dev react-scripts and then
npm install --save-dev my-react-scripts-fork.
For new projects, we need to
create-react-app my-react-app --scripts-version my-react-scripts-fork.
You can take a look at
my-react-app which is using
Now we want to make a change to
my-react-scripts-fork and see the changes in
my-react-app without having to publish a new version.
To do that, we’ll have to
my-react-scripts-fork directory and
npm link the package.
npm link my-react-scripts-fork.
This is very useful when we are testing a new configuration, but you have to remember to release and publish when you get the job done so the rest of your team can pull the changes.
We’ve seen how to extend
react-scripts without ejecting and not “die” trying.
One thing I noticed while writing this post, is the fact that for most changes we need to duplicate the configuration in 2 webpack files:
I hope the
create-react-app team (or even Webpack) comes up with a better approach to this in the future.
Which will mean more effort while merging our custom
react-scripts to a new major version with breaking changes.
That’s why a complete Git commit history and changelog are important to help us in these matters.
I hope this helps you on your own projects.