Starting a new React project isn’t that simple. Instead of diving straight into code and bringing your application to life, you have to spend time configuring the right build tools to set up a local development environment, unit testing, and a production build. Luckily, help is at hand in the form of Create React App.
Create-React-App is a command-line tool from Facebook that allows you to generate a new React project and use a pre-configured webpack build for development. It has long since become an integral part of the React ecosystem that removes the need to maintain complex build pipelines in your project, letting you focus on the application itself.
How Does Create React App Work?
Create React App is a standalone tool that can be run using either npm or Yarn.
You can generate and run a new project using npm just with a couple of commands:
npx create-react-app new-app
cd new-app
npm start
If you prefer Yarn, you can do it like this:
yarn create react-app new-app
cd new app
yarn start
Create React App will set up the following project structure:
new-app
├── .gitignore
├── node_modules
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── README.md
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reportWebVitals.js
│ └── setupTests.js
└── yarn.lock
It will also add a react-scripts
package to your project that will contain all of the configuration and build scripts. In other words, your project depends on react-scripts
, not on create-react-app
itself. Once the installation is complete, you can fire up the dev server and start working on your project.
Basic Features
Local Development Server
The first thing you’ll need is a local development environment. Running npm start
will fire up a webpack development server with a watcher that will automatically reload the application once you change something. Starting from v4, Create React App supports React’s fast refresh as an alternative to Hot Module Replacement. Like its predecessor, this allows us to quickly refresh parts of the application after making changes in the codebase, but has some new features as well. Fast Reload will try to reload only the modified part of the application, preserve the state of functional components and hooks, and automatically reload the application after correcting a syntax error.
You can also serve your application over HTTPS, by setting the HTTPS
variable to true
before running the server.
The application will be generated with many features built in.
ES6 and ES7
The application comes with its own Babel preset — babel-preset-react-app — to support a set of ES6 and ES7 features. Some of the supported features are:
- Async/await
- Object Rest/Spread Properties
- Dynamic import()
- Class Fields and Static Properties
Note that Create React App does not provide any polyfills for runtime features, so if you need any of these, you need to include them yourself.
Asset Import
You can import CSS files, images, or fonts from your JavaScript modules that allow you to bundle files used in your application. Once the application is built, Create React App will copy these files into the build folder. Here’s an example of importing an image:
import image from './image.png';
console.log(image); // image will contain the public URL of the image
You can also use this feature in CSS:
.image {
background-image: url(./image.png);
}
Styling
As mentioned in the previous section, Create React App allows you to add styles by just importing the required CSS files. When building the application, all of the CSS files will be concatenated into a single bundle and added to the build folder.
Create React App also supports CSS modules. By convention, files named as *.module.css
are treated as CSS modules. This technique allows us to avoid conflicts of CSS selectors, since Create React App will create unique class selectors in the resulting CSS files.
Alternatively, if you prefer to use CSS preprocessors, you can import Sass .scss
files. However, you’ll need to install the node-sass
package separately.
Additionally, Create React App provides a way to add CSS Resets by adding @import-normalize;
anywhere in your CSS files. Styles also undergo post-processing, which minifies them, adds vendor prefixes using Autoprefixer, and polyfills unsupported features, such as the all
property, custom properties, and media query ranges.
Running Unit Tests
Executing npm test
will run tests using Jest and start a watcher to re-run them whenever you change something:
PASS src/App.test.js
✓ renders learn react link (19 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.995 s
Ran all test suites.
Watch Usage
› Press f to run only failed tests.
› Press o to only run tests related to changed files.
› Press q to quit watch mode.
› Press p to filter by a filename regex pattern.
› Press t to filter by a test name regex pattern.
› Press Enter to trigger a test run.
Jest is a test runner also developed by Facebook as an alternative to Mocha or Karma. It runs the tests in a Node environment instead of a real browser, but provides some of the browser-specific globals using jsdom.
Jest also comes integrated with your version control system and by default will only run tests on files changed since your last commit. For more on this, refer to “How to Test React Components Using Jest”.
ESLint
During development, your code will also be run through ESLint, a static code analyzer that will help you spot errors during development.
Creating a Production Bundle
When you finally have something to deploy, you can create a production bundle using npm run build
. This will generate an optimized build of your application, ready to be deployed to your environment. The generated artifacts will be placed in the build folder:
build
├── asset-manifest.json
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
├── robots.txt
└── static
├── css
│ ├── main.ab7136cd.chunk.css
│ └── main.ab7136cd.chunk.css.map
├── js
│ ├── 2.8daf1b57.chunk.js
│ ├── 2.8daf1b57.chunk.js.LICENSE.txt
│ ├── 2.8daf1b57.chunk.js.map
│ ├── 3.d75458f9.chunk.js
│ ├── 3.d75458f9.chunk.js.map
│ ├── main.1239da4e.chunk.js
│ ├── main.1239da4e.chunk.js.map
│ ├── runtime-main.fb72bfda.js
│ └── runtime-main.fb72bfda.js.map
└── media
└── logo.103b5fa1.svg
Deployment
Since the build of your Create React App application consists of just static files, there are different ways you can deploy them to your remote environment. You can use a Node.js server if you’re running in a Node.js environment, or serve the application using a different web server, such as NGINX.
The deployment section in the official documentation provides an overview of how to deploy the application to Azure, AWS, Heroku, Netlify, and other popular hosting environments.
Development Features
Environment variables
You can use Node environment variables to inject values into your code at build time. Create React App will automatically look for any environment variables starting with REACT_APP_
and make them available under the global process.env
. These variables can be in a .env
file for convenience:
REACT_APP_BACKEND=http://my-api.com
REACT_APP_BACKEND_USER=root
You can then reference them in your code:
fetch({process.env.REACT_APP_SECRET_CODE}/endpoint)
Proxying to a Back End
If your application will be working with a remote back end, you might need to be able to proxy requests during local development to bypass CORS. This can be set up by adding a proxy field to your package.json
file:
"proxy": "http://localhost:4000",
This way, the server will forward any request that doesn’t point to a static file to the given address.
Code Splitting
Create React App supports code splitting using the dynamic import() directive. Instead of returning the values exported by the module, it will instead return a Promise that resolves into these values. As a result, modules imported this way won’t be included in the final bundle, but built into separate files. This allows you to reduce the size of the final bundle and load content on demand.
TypeScript Support
You can enable TypeScript to get the benefits of static type analysis when generating a new project. This can be done by using a different non-default template for generating the project:
npx create-react-app my-app --template typescript
You can also add TypeScript support to an existing project, as described in the documentation.
Progressive Web Apps
Similarly, you can add progressive web app support. You can use service workers by adding a src/service-worker.js
file. Starting from v4, this will be injected into the application using the Workbox library.
To enable service workers in a new project, they need to be generated from a custom template:
npx create-react-app my-app --template cra-template-pwa
# or with TypeScript support
npx create-react-app my-app --template cra-template-pwa-typescript
Web Vitals
Create React App allows you to measure the performance and responsiveness of your application. This is done by tracking the metrics defined by web vitals and measured using the web-vitals library. The metrics include Largest Contentful Paint, which measures loading performance, First Input Delay, and Cumulative Layout Shift for responsiveness.
Create React App provides a convenient function to track all of the available metrics:
// index.js
reportWebVitals(console.log);
Opting Out
If at some point you feel that the features provided are no longer enough for your project, you can always opt out of using react-scripts
by running npm run eject
. This will copy the webpack configuration and build scripts from react-scripts
into your project and remove the dependency. After that, you’re free to modify the configuration however you see fit.
As an alternative, you can also fork react-scripts
and maintain your branch with the features you need. This can be easier, in case you have many projects to maintain.
In Conclusion
If you’re looking to start a new React project, look no further. Create React App will allow you to quickly start working on your application instead of writing yet another webpack config. It also makes it easy to update your build tooling with a single command (npm install react-scripts@latest
) — something that’s typically a daunting and time-consuming task.
Create React App has become an integral part of the React ecosystem. Whether you use it to throw together a quick prototype, or to scaffold out your next major project, it will save you many hours of dev time.