react-scripts serves as the configuration and build tooling layer for React applications created with Create React App. At its core, react-scripts abstract away the complex configuration required for modern JavaScript applications, particularly around webpack, Babel, ESLint, and testing setups. This abstraction allows developers to focus on writing application code rather than spending time on build configuration.
Specifically, react-scripts provides:
By handling these aspects, react-scripts enables developers to follow the “convention over configuration” principle, with sensible defaults that work for most React applications. This standardization also helped create consistency across React projects in the ecosystem during the peak popularity of Create React App.
However, as web development tooling has evolved, some limitations of react-scripts have become apparent, particularly around build performance and flexibility, leading to the rise of alternatives that we’ll explore later in this article.
Editor’s note: This article was last updated by Ikeh Akinyemi in March 2025 to update information around the current use of react-scripts, discuss the alternative Create React App, and address common challenges associated with using react-scripts.
The React ecosystem has evolved significantly since Create React App (CRA) was introduced as the go-to solution for bootstrapping React applications. In 2022, CRA and its underlying react-scripts package were the standard for quickly starting React projects without the configuration headaches. However, the landscape has shifted dramatically.
Over the years, many existing projects heavily relied on react-scripts — but that isn’t the case anymore. Newer React applications are increasingly porting to alternative tooling like Vite, which offers significant performance improvements and a more modern development experience.
Despite this shift, understanding react-scripts remains valuable for maintaining legacy projects, contributing to established codebases, or making informed decisions about migrating to newer toolchains.
In the past, creating a React app was a painful process. You had to slog through a lot of configuration, especially with webpack and Babel, before you could get your hands dirty and develop something meaningful.
Fortunately, Create React App was introduced as a solution, offering a handy module that comes with an outstanding configuration, and a scripts command called react-scripts that makes it much easier to build React applications.
The aim for this guide is to provide you with a comprehensive overview of react-scripts, its functionality, current status in the React ecosystem, and alternatives for modern React development. Whether you’re maintaining a CRA project or considering a migration to newer tools, this article will help you with the knowledge needed to navigate the changing React.
We’ll give an overview of react-scripts, compare a few different types of scripts, and describe how Create React App dramatically streamlines the React development process. Let’s dive in!
In programming, a script is a list of instructions that dictates what to do to another program; React is no exception. Create React App ships with four main scripts, each of which we’ll explore later. But for now, we’ll focus on where to find these scripts.
First, create a new React app with the following command to find predefined scripts:
npx create-react-app my-app
The above command creates a new React app with cra-template and all required configurations.
Every configuration required for the React app comes through the react-scripts package. Now, check the package.json
file of the newly created project.
In React apps, scripts are located in the package.json
file’s script
section, as shown below:
"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }
In the previous JSON snippet, the package.json
file has some default scripts, but it’s still possible to edit them. You can execute these scripts with your preferred Node package manager CLI.
As you can see, a fresh React app comes with four scripts that use the package react-scripts. Now that we know what a script is and where to find them, let’s dive into each one and explain what it does to a React app.
start
React uses Node.js on development to open the app on http://localhost:3000
. The start
script enables you to start the webpack development server.
You can run the start
script command on the terminal with either npm
or yarn
:
yarn start npm start
This command will not only start the development server, but it will also react and display the latest version each time a change occurs with the webpack’s Hot Module Replacement (HMR) feature. In addition, it will show lint errors on the terminal if it fails to start the server in the form of meaningful error messages.
test
Create React App uses Jest as a test runner. The test
script enables you to launch the test runner in interactive watch mode that lets you control Jest with your keyboard.
The test
script can be run on the terminal with the following commands:
yarn test npm test
The default React template comes with one predefined test case for the sample application interface. Open the src/App.test.js
file and find the following sample test case:
test('renders learn react link', () => { render(<App />); const linkElement = screen.getByText(/learn react/i); expect(linkElement).toBeInTheDocument(); });
The above test cases check whether the app rendered learn react
(case insensitive) or not. Enter the npm test
(or yarn test
) command and press the A key to run all test cases, as shown below:
I won’t dive too deep into testing React apps, but keep in mind that any file with .test.js
or .spec.js
extensions will be executed when the script is launched.
build
React is modular, which is why you can create several files or components if you wish. These separate files need to be merged or bundled into one to be precise. That’s one of the major benefits of the build
script.
The other is performance; as you know, development mode is not optimized for production environments. And React uses the build
script to ensure that the finished project is bundled, minified, and optimized with best practices for deployment.
The script can be run with the following commands:
yarn build npm run build
After running the build
script, you can find all deployable optimized static resources inside the build
directory.
There are some additional options that can be passed to the build
script. For example, you can use the --stats
option to generate a bundle stats file that you can visualize with the webpack-bundle-analyzer tool.
See the docs for a deeper dive on how to enhance your build
script.
eject
The Create React App documentation characterizes this script as a “one-way operation” and warns that “once you eject, you can’t go back!” Create React App comes with an excellent configuration that helps you build your React app with the best practices in mind to optimize it.
However, we may have to customize the pre-built react-scripts with additional configurations in some advanced scenarios. The eject
script gives you full control over the React app configuration. For example, you can customize the webpack or Babel configuration according to a specific need by ejecting the React app.
Running the eject
script will remove the single build dependency from your project. That means it will copy the configuration files and the transitive dependencies (e.g., webpack, Babel, etc.) as dependencies in the package.json
file. If you do that, you’ll have to ensure that the dependencies are installed before building your project.
After running the eject
command, it won’t be possible to run it again, because all scripts will be available except the eject
one. Use this command only if you need to. Otherwise, stick with the default configuration. It’s better, anyway.
To run the command on the terminal, type the following command:
yarn eject npm run eject
Ejecting helps you to customize anything in your React configuration, but ejecting may create different versions of react-scripts. Then, you have to maintain customized react-scripts yourself with every React project. Therefore, creating a react-scripts fork is a better idea to make a reusable custom React app configuration.
You can use a forked react-scripts module with the following command:
npx create-react-app my-app --scripts-version react-scripts-fork
The above command scaffolds a new React app by using the react-scripts-fork package as the react-scripts source.
Preconfigured react-scripts don’t typically accept many CLI options for customizing their default behaviors. But, react-scripts let developers do various advanced configurations via environment variables that you can set via the terminal.
For example, you can change the development server port with the PORT
environment variable, as shown below:
PORT=5000 yarn start PORT=5000 npm start
Also, you can change the default application build directory by setting BUILD_PATH
as follows:
BUILD_PATH=./dist yarn build BUILD_PATH=./dist npm run build
If you want, you can update your existing script definitions with environment variables, too. For example, if you use the following JSON snippet in package.json
, you can always use port 5000
with the start
script:
"scripts": { "start": "PORT=5000 react-scripts start", // port 5000 "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }
All supported environment variables are available in the official documentation.
As of 2025, react-scripts and Create React App have effectively become outdated tools in the React ecosystem. This isn’t just an opinion; it’s reflected in the project’s maintenance status and community adoption trends.
The last significant update to react-scripts was released in April 2022. This lack of updates is particularly concerning in the fast-moving JavaScript ecosystem, where dependencies, security patches, and best practices evolve rapidly.
The official Create React App repository shows minimal activity, with existing issues and pull requests largely unaddressed.
This stagnation has led to several problems for developers still using react-scripts:
npx create-react-app
today, you’ll receive multiple vulnerability warnings, most of which remain unfixed due to outdated dependenciesEven before maintenance stopped, react-scripts was already showing performance limitations compared to more modern tooling:
While the React team hasn’t officially deprecated Create React App, their documentation now prominently features alternative approaches. The official React documentation recommends using production-grade frameworks like Next.js, with Vite listed as an option for those wanting a simpler, client-side only solution.
If you’re considering moving away from react-scripts, the answer is yes, you can remove it—but this requires a migration to an alternative build system. The most popular direct replacement as of 2025 is Vite, which offers significant performance improvements and modern defaults. To learn more about migrating your CRA apps to Vite, visit this blog post.
The effort of migration comes with substantial benefits. Vite’s development server starts in milliseconds instead of seconds or minutes, and its Hot Module Replacement makes changes appear almost instantly in the browser. You’ll also enjoy smaller bundles through better production optimization, support for the latest JavaScript features through modern defaults, and the peace of mind that comes with regular updates and security patches through active maintenance.
Despite its new available options, many developers still work with react-scripts in existing projects. Here are solutions to some common issues you might encounter:
If you’ve cloned a React project from a repository and encounter errors when trying to run npm start
, the issue might be that react-scripts isn’t properly listed in the dependencies.
Problem — Error like below:
Error: Cannot find module 'react-scripts'
Solution — Ensure react-scripts is in your package.json:
"dependencies": { "react-scripts": "5.0.1", // other dependencies }
If it’s not there, add it:
npm install react-scripts --save
By including the --save
flag, npm will add react-scripts to your package.json, making the commands available in the future versions of the project.
Some projects may need to use a specific version of react-scripts for compatibility reasons.
Problem — You’re encountering errors like:
Invalid options object. Dev Server has been initialized using an options object that does not match the API schema
Solution — Downgrade to a specific version using:
# For npm npm uninstall react-scripts npm install --save [email protected] # For yarn yarn remove react-scripts yarn add [email protected]
Alternatively, you can directly edit your package.json:
"dependencies": { "react-scripts": "4.0.3", // other dependencies } >
Then run npm install
or yarn
to update your node_modules.
React-scripts may have issues with certain Node.js versions, especially newer ones.
Problem — You’re encountering cryptic errors after upgrading Node.js
Solution — Use a Node version manager like nvm (or nvm-windows) to switch to a compatible Node version:
# Install Node.js 16.x (LTS when react-scripts 5.0.1 was released) nvm install 16 nvm use 16
This allows you to use different Node versions for different projects without reinstallation.
When building larger applications, you might encounter memory issues.
Problem — Fatal error like below:
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed
Solution — Increase the memory limit for Node.js:
# For Windows (CMD) set NODE_OPTIONS=--max_old_space_size=4096 npm run build # For Windows (PowerShell) $env:NODE_OPTIONS="--max_old_space_size=4096" npm run build # For Mac/Linux NODE_OPTIONS=--max_old_space_size=4096 npm run build
You can add this to your package.json scripts for convenience:
"scripts": { "build": "react-scripts build", "build:high-memory": "cross-env NODE_OPTIONS=--max_old_space_size=4096 react-scripts build" }
As React evolves beyond version 18, compatibility issues with older react-scripts versions may increase.
Problem — Features from newer React versions don’t work with your CRA setup.
Solution — You have three options:
For temporary fixes with CRACO:
npm install @craco/craco --save-dev
Then update your package.json:
"scripts": { "start": "craco start", "build": "craco build", "test": "craco test" }
Create a craco.config.js
file in your project root with your customizations.
I hope this guide sheds enough light on the significant changes since Create React App and react-scripts simplified the React application bootstrapping process. Not only does the app come with useful scripts that can help make any developer’s life easier, but some commands come with flexible options that enable you to fit the scripts to the unique needs of your project.
While react-scripts served the community admirably for many years, its lack of updates since 2022 has left it increasingly out of step with modern development practices and the evolving React ecosystem. So for your next React project, check out the suite of Vite project setups that might serve your use case.
As React itself continues to evolve, the tooling around it will inevitably change as well. By staying informed about these changes and remaining open to new approaches, you’ll be well-positioned to build fast, maintainable, and future-proof React applications, regardless of the build tools you choose to employ.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowExplore the fundamental commands for deleting local and remote branches in Git, and discover more advanced branch management techniques.
AbortController
APICheck out a complete guide on how to use the AbortController and AbortSignal APIs in both your backend and frontend.
LLMs can do more than chat! Explore alternative integration models that improve efficiency, reduce complexity, and enhance user control.
Learn the basics of applying image overlays in CSS and explore more interactive techniques like hover effects and animations.
5 Replies to "How to handle react-scripts in a fast-changing React landscape"
`react-scripts` is great because you don’t have to manage tones of dependencies, but just a single one. It comes with most useful tools & dependencies, such as eslint, jest, babel, and webpack, which is powerful bundler but configuring it is a real nightmare. `react-scripts` saves all that.
Also, it is possible to integrate `react-scripts` to already existing app. I strongly recommend it.
Your example is wrong for ejecting with npm. You say it’s `npm run build` but it is `npm run eject`
Thanks for the catch
You’ve mentioned that these default scripts can be edited. That is exactly what I’m looking for, I need to edit “start” but I can’t find a way to do it.Â
Do You have an article on that?Â
Thank you for such a detailed article.