Don’t eject your Create React App
If you found yourself on this page because you want to eject your Create React App project, the details you’re looking for are at the bottom of this article.
But before you jump down, I hope you consider reviewing this article because ejecting can introduce much more complexity to your project than you might anticipate. Before you commit to your irreversible decision to eject, let me propose a few alternatives.
Why are you ejecting?
There are 3 primary reasons why someone might choose to eject and each reason has either drawbacks or alternatives that should first be investigated.
- “I can manage the build on my own” or “I want full control over my project.”
- “Create-React-App is missing a feature that I need, so I’m going to add it myself.”
- “I’m curious about the build process and want to learn how it works.”
“I can manage the build on my own” or “I want full control over my project”
I’ll admit that the first CRA project I created, I immediately ejected. My naïve assumption was that managing my own build process is something experts did and I assumed I was experienced enough to handle it.
“I’m a good programmer, I can manage my own build tools, I just need a headstart from Create-React-App.”
In reality, experts do everything they can to avoid additional configuration, tools, and code. Before you eject, ask yourself, “Do I want to build something using React or do I want to fight with picky build tools when things stop working?”
Don’t eject until you have a specific reason to do so. If you feel that you have a good reason to eject at a later date, circle back to this article and reevaluate your position. Ejecting is a one-way process and makes your configuration more complex; why burn that bridge before you’ve even used it?
If you’re being thoughtful enough to learn more about ejecting before jumping in, also be thoughtful enough to consider that CRA’s “sane defaults” might work for you, at least for now.
“Create-React-App is missing a feature that I need, so I’m going to add it myself”
This is a great reason to eject. It’s the reason most people do so. However, before you eject, take the time to ensure you aren’t making extra work for yourself or repeating the work someone else has done previously.
Is this something the Create-React-App team has already discussed?
There are thousands of issues filed in the Create-React-App repo, and chances are someone has already addressed your concern. Explore the existing discussions around the topic; you might find a solution or alternative already exists. If it hasn’t been discussed yet, consider filing an issue or making a PR. Thoughtful input is always appreciated.
Has someone built this already?
A nice feature of the CRA sub-package react-scripts is that it can easily be forked and modified. The resulting forked configuration can then be used by your project. Try exploring some existing forks of react-scripts to see if they include the features you want, but without having the maintenance burden of managing your own configuration files. React-super-scripts is an example of one alternative that includes decorators, babel stage-0 features, CSS, SASS, and LESS modules:
adds super powers to create-react-app and allows custom configs without ejecting. - shrynx/react-super-scriptsgithub.com
Do you really need this feature?
Before you dive into editing configuration files, you should ask yourself two important questions:
- How much value will be added by making this change?
- Does the value outweigh the introduced cognitive burden of managing the build process?
You’ll be adding thousands of lines of complex code for building and testing, which you will then need to learn in order to properly update, test, and debug your build. By ejecting, you’re taking on the responsibility of updating code that you might not fully understand. If your build breaks, the CRA team will be unable to support your custom configuration. If you have a development team, do you trust they will also adequately understand the changes they’re making to the build process to ensure its stability?
If you or your team do not have a strong understanding of the existing build tools already, “just adding one feature” is likely more difficult than it sounds.
Are you just adding a couple small tweaks to the CRA configuration?
There are a couple of ways to edit your configuration without ejecting. Unlike ejecting, these options are easy to back out of if necessary. React-app-rewired is one of the most popular approaches. Additionally, customize-cra is a package built on top of react-app-rewired with support for version 2 of CRA.
Version 2 of CRA introduced babel-macros, which are an advanced feature that allows for the inclusion of simple code transformations that run during the build process. It makes configuration files unnecessary, just import your macro into the file you want to transform. Babel-macros have a steeper learning curve than the above tools but are a handy escape-hatch from managing the entire build process yourself.
Are you making significant changes to the CRA configuration?
Okay, I get it, your workflow is a special case and needs specific tooling to reflect it. But before you eject, consider that your use case might be more reusable than you think. Rather than ejecting and maintaining the build process yourself, forking react-scripts allows you to make changes while also reusing it on other similar projects.
Allowing others to use and contribute to your build process is good for your code’s stability and maturity. Forking is encouraged by the CRA team, and easy to set up. Auth0 wrote a great instruction guide for how to fork react-scripts.
“I’m curious about the build process and want to learn how it works”
Great reason! After you’ve set up a new CRA project to your liking, use the command at the bottom of this article to eject it. When ejecting, you will gain access to the code from the react-scripts package. The same code can also be found on the CRA Github repo if you want to do some exploration before ejecting. The CRA repo also contains several other packages which you might also find interesting to investigate.
Don’t be discouraged if you wind up confused or lost. Understanding how CRA works is a daunting task given its size, maturity, and complexity. If you need help, Stack Overflow is a good place to ask questions if you need help with specific blocks of code. Many of the project’s contributors are active on Twitter and could also provide some insights into higher-level details.
There’s nothing wrong with ejecting — there’s a reason it was built into CRA. There are workarounds and escape-hatches that are worth exploring, but for some cases, they’re just not enough.
Before you eject, heed this warning from the docs:
This is a one-way operation. Once you
eject, you can’t go back!
If you’ve informed yourself of the alternatives and you still feel that ejecting is the right choice, the process is simple, just a single command. After running the command, you’ll be greeted with two new directories,
scripts, that you can explore and edit.
If you disagree with my opinions on ejecting in this article, I’d love to hear why. Leave a response below and I’d be happy to discuss my viewpoints. Additionally, If you also have other reasons for or against ejecting, I’d love to hear from you.