Editor’s Note: This blog post was reviewed and updated with relevant information in June 2021.
Create React App is one of the most popular tools for creating a React app. Why?
Because with just three dependencies, you get support for React, JSX, ES6, polyfills, a development server, auto prefixed CSS, tests, service workers, and much more.
This post presents a quick guide to set up a React app with this tool and configure some of its more important features.
The only prerequisite for using this tool is having Node.js version 6 or superior installed.
Use one of the following commands to create a new app:
#Using npx npx create-react-app app-name #Using npm init <initializer> npm init react-app app-name #Using yarn 0.25+ yarn create react-app app-name
These commands create a directory with the given app name of the app and an initial project structure (see the template here), as well as install hundreds of packages as the dependencies.
Now, if you look at the generated package.json
file, you’ll only see three dependencies: react, react-dom, and react-scripts.
react-scripts is the library that handles all the configuration and brings most of the dependencies of the project, like babel, ESlint, and webpack (if you’re curious, see the complete list in its package.json file).
Understanding react-scripts is the key to understanding the inner workings of Create React App.
One of the advantages of having so few dependencies is that they are easy to both upgrade or downgrade.
You only have to execute npm install
with the flags — — save — -save-exact
to specify the exact version. The package.json
will be updated and the new versions of the dependencies downloaded.
For example, to change to version 1.1.4 of react-scripts, execute:
npm install --save --save-exact [email protected] # or yarn add --exact [email protected]
Also, don’t forget to consult the changelog of react-scripts and React to look for breaking changes.
ESLint is configured by default (you can see the configuration here), and its output is shown in the terminal as well as the browser console.
Officially, you cannot override this configuration. If you want to enforce a coding style, you can install and use Prettier (it’s not integrated right now).
The only thing you can do is configure your code editor to report linting warnings by installing an ESLint plugin for your editor and adding a .eslintrc
file to the project root:
{ "extends": "react-app" }
Or, you can add your custom rules to this file, but they will only work in your editor.
Unofficially, you can use something like react-app-rewired to override the default configuration.
To run the application, execute npm start
, which is a shortcut to:
react-scripts start
This script executes a Webpack development server:
3000
by default (or another one if the chosen port is occupied)In Mac, the app is opened in Chrome if it’s installed. Otherwise, like in other OS, the default browser is used.
In addition, errors are shown in the console terminal as well as the browser.
You can see the whole start script here.
You have two options when adding images, styles or by using other files (like fonts):
src
folder, using the module systempublic
folder, as static assetsEverything you place inside the src
folder will be handled by Webpack, which means the files will be minified and included in the bundle generated at build time.
This also means that the assets can be imported in JavaScript:
Importing images that are less than 10,000 bytes returns a data URI instead of a path to the actual image as long as they have the following extensions:
Another advantage of using this folder is that if you don’t reference the file correctly, or if you accidentally delete it, a compilation error is generated.
On the other hand, you can also add files to the public
folder. However, you’ll miss the advantages described above because they will not be processed by webpack, they will only be copied into the build
folder.
Something else to keep in mind is that you cannot reference files inside the src
folder in the public
folder.
However, to reference the files in the public
folder, you can use the variable PUBLIC_URL
like this:
Or with the variable process.env.PUBLIC_URL
in JavaScript:
In addition to the variable PUBLIC_URL
, there’s a special built-in environment variable called NODE_ENV
that cannot be overridden:
npm start
takes the value development
npm run build
takes the value production
npm test
takes the value test
You can also define custom environment variables that will be injected at build time. They must start with REACT_APP_
, otherwise, they will be ignored.
You can define them using the terminal:
#Windows set "REACT_APP_TITLE=App" && npm start #Powershell ($env:REACT_APP_TITLE = "App") -and (npm start) #Linux and mac REACT_APP_TITLE=App npm start
Or one of the following files in the root of your project (files on the left have more priority than files on the right):
npm start
: .env.development.local
, .env.development
, .env.local
, .env
npm run build
: .env.production.local
, .env.production
, .env.local
, .env
npm test
: .env.test.local
, .env.test
, .env
As explained before, all these variables can be used with process.env
inside a component:
Or in public/index.html
:
In addition to NODE_ENV
, there are other predefined environment variables that you can set for development settings, like BROWSER
, HOST
, and PORT
, as well as some production settings like PUBLIC_URL
and GENERATE_SOURCEMAP
.
See the complete list here.
It’s common to serve the frontend and backend of your app in the same server and port. However, you cannot do this because Create React App runs the app in its own development server.
So you have three options.
The first one is to run the back-end server on another port and make requests like this:
With this approach, you need to set the CORS headers on your server.
The second one is to tell the development server to proxy any request to your back-end server by adding a proxy field to your package.json
file. For example, using:
Instead of making a request like this:
After restarting the server, you should make them like this:
If this is not enough for you, a third option is to configure the proxy of each endpoint individually, like this:
The configuration properties are the same as the ones supported by http-proxy-middleware or http-proxy.
A service worker is registered in src/index.js
. If you don’t want to enable it just remove the call to registerServiceWorker()
.
The service worker is only enabled in the production version of the application. However, if the app has already been executed, the service worker will already be installed in the browser and should be removed using unregister()
:
Service workers require HTTPS (otherwise registration will fail, although the app will remain functional). However, to facilitate local testing, this doesn’t apply to localhost.
A web app manifest where you can configure the app name, icons and other metadata about your application is located at public/manifest.json
.
Create React App uses Jest as its test runner and jsdom to provide browser global variables like window
or document
.
Test files should follow any of these naming conventions:
.js/.jsx/.mjs
, the files should be located in a directory named __tests__
(matching the expression <rootDir>/src/**/__tests__/**/*.{js,jsx,mjs}
).test.js
or .specs.js
(matching the expression <rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}
)Executing npm test will run the tests by executing the script:
react-scripts test --env=jsdom
You can see the complete script here.
The tests will be run in watch mode. Every time you save a file, the tests are re-run. However, this mode also includes an interactive command-line interface with an option to enter a test name pattern to avoid running all tests.
If you just need to execute or configure something before running your tests, add it to the file src/setupTests.js
, which will be executed automatically before any test.
If you need a coverage report, you can execute the command npm test --coverage
, optionally configuring in the package.json
file the options:
For example:
You can create a production version of your app in the build directory with npm run build, which is a shortcut to:
react-scripts build
You can see the complete script here.
After this, you may copy the content of this build directory to a web server or you use packages like http-server or serve to test your application from that directory.
One thing to take into account is that Create React App assumes that you will host your app at the server root. If this is not the case, you need to specify the homepage field in your package.json
file so the correct root path can be inferred:
However, if you are not using a router with HTML5 pushState history API or not using routing at all, you can use a dot to make sure that all the asset paths are relative to index.html:
In the user manual of Create React App, you can find instructions to deploy your app using:
Ejecting will copy all the configuration files, scripts, and dependencies to your project while removing the dependency to react-scripts
.
Execute npm run eject
to perform this operation.
Here’s an extract of the output:
And here you can see the whole script it executes.
This operation cannot be reverted. Use it when the configuration options the tool offers are not enough for you anymore.
This post covered the most important features you may configure when using Create React App. Now you might want to take a closer look at react-scripts, the core of Create React App, to get a deep knowledge of how it works.
Although Create React App is a popular tool, it is not for everyone. There might be better alternatives depending on the type of application you’re developing. For example, Gatsby for static sites or Next.js for server-side rendering. Consult more alternatives here.
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>
Hey there, want to help make our blog better?
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 use cases for using npm vs. npx such as long-term dependency management or temporary tasks and running packages on the fly.
Validating and auditing AI-generated code reduces code errors and ensures that code is compliant.
Build a real-time image background remover in Vue using Transformers.js and WebGPU for client-side processing with privacy and efficiency.
Optimize search parameter handling in React and Next.js with nuqs for SEO-friendly, shareable URLs and a better user experience.