Esteban Herrera Family man, Java and JavaScript developer. Swift and VR/AR hobbyist. Like books, movies, and still trying many things.

What’s new in Create React App 3

3 min read 1086

Released at the end of April 2019, Create React App (CRA) 3 adds linting rules to hooks and TypeScript projects, along with other improvements and version upgrades to ease the development of React apps.

In this article, I’m going to cover the following new features of CRA 3:

  • Jest 24
  • Support of hook rules
  • Linting of TypeScript files
  • browserslist configuration for production and development environments
  • baseUrl in jsconfig.json/tsconfig.json

For a complete list of all the features (and some breaking changes), check out the changelog for this release.

Jest 24

CRA now bundles the latest major version of Jest (specifically, version 24.7.1, at the time of this writing).

In comparison to the previous version, Jest 24 includes changes like:

  • Built-in support for transpiling TypeScript files
  • Improved error reporting
  • A test.todo function to print todos separately in the test summary
  • Renamed setupTestFrameworkScriptFile to setupFilesAfterEnv, turning it into an array

For more information, you can check out this blog post or the changelog.

If you haven’t use Jest, it is a unit testing framework that runs in a Node.js environment instead of a browser.

When executing npm test, CRA will use Jest to run tests with the following naming conventions:

  • Files with a .js suffix in __tests__ folders
  • Files with a .test.js suffix
  • Files with a .spec.js suffix

By default, Jest will only run the tests related to files changed since the last commit and it will launch in watch mode (every time you save a file, it will re-run the tests).

To avoid running tests in watch mode, CRA 3 removed the --no-watch flag in favor of Jest’s flag --watchAll=false. However, this flag is not necessary if you, or your CI server, set the CI environment variable.

You can know more about running tests on this page.

We made a custom demo for .
No really. Click here to check it out.

Hooks rules

Hooks were introduced in React 16.8. They are functions that allow you to use React features only available for classes (like state handling) in functional components.

There are two rules for using hooks:

  1. Use hooks at the top level of your functional component, never inside loops, conditions, or nested functions
  2. Only call hooks from functional components, don’t call hooks from regular JavaScript functions

CRA 3 integrates an ESLint plugin, eslint-plugin-react-hooks, that enforces these two rules and other conventions (for example, that hooks must begin with use followed by an uppercase character).

The build will fail if you break one of the rules.

For example, if you modify the file src/App.js in the following way:

Since the hook useState is being used inside a conditional block, the build will fail with the following message:

Failed to compile.

Line 7:  React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render react-hooks/rules-of-hooks

In this README file (and in particular, the index.js file), you can know more about the ESLint configuration used by CRA.

And on this page, you can learn how to set up your editor to display the lint output.

TypeScript linting

CRA 3 also added linting rules for TypeScript projects via typescript-eslint.

Remember that you can create a TypeScript project with either:

npx create-react-app my-typescript-app --typescript


yarn create react-app my-typescript-app --typescript

Here you can see the ESLint configuration for TypeScript in CRA 3.0, and in this page, you can find instructions to enable TypeScript support in the ESLint extension of Visual Studio Code.

Browserslist configuration

Browserslist allows you to configure a set of browser versions to change the build output in order to produce compatible code and support the specified browser versions.

You can specify separate lists for production and development. For example, if you add the following configuration to the package.json file:

"browserslist": {

  "production": [

    "cover 99.5%"


  "development": [

    "last 2 chrome versions"



The production build will target browsers that cover 99.5% of global usage, while the development build will target only the last two versions of Chrome.

Browserslist uses Can I Use for these queries, but you can use to see the results of these queries (here and here) and test your own.

This way, you can install @babel/polyfill as a dependency of your project and import it at the top of the src/index.js or src/index.tsx files and Browserslist will include polyfills when necessary (polyfills are not automatically added). In this page, you can find more information about the supported language features.

Also, if you want CRA 3 to handle a reset CSS, it will use PostCSS Normalize by default, which in turn, will use the Browserslist configuration to adapt its output. You just need to add @import-normalize; anywhere in your CSS file(s). See this page for more information.

Browserslist’s default configuration targets a broad range of browsers in production, but following the instructions in this README file, you’ll be able to define your own custom queries.

Setting a base URL

Setting the NODE_PATH environment variable to a colon-delimited (semicolons on Windows) list of absolute paths, allows Node.js to search for modules in those paths to avoid things like:

const myModule = require('../../../../../../myModule');

CRA 3 removes the need for setting NODE_PATH in a .env file (this variable is still considered, but is deprecated and will be removed in a future release).

So now you have to use baseUrl in either a jsconfig.json or tsconfig.json file (the latter for TypeScript projects) at the root of your project:


  "compilerOptions": {

    "baseUrl": "src"



This way, instead of having something like:

import Menu from 'src/components/Menu';

You can just have:

import Menu from 'components/Menu';

Not a big improvement, but in CRA 3.0, the only acceptable values for baseUrl are src and node_modules (the default value).

In this page, you can find more information about this feature.


There’s no doubt CRA keeps improving with every new release. Thanks to the work of almost 50 committers, this time, it has brought a set of useful additions, improvements, and updates to internal and underlying tools.

If you have created a React application with CRA 2 and you have not ejected it, upgrading to CRA 3 is as easy as running one the following commands:

npm install --save --save-exact react-scripts@3.0.0

# Or

yarn add --exact react-scripts@3.0.0

If you have ejected your application, there’s no easy process to upgrade, so consider if it’s worth revert the project up to the point before ejection, upgrade, and optionally, eject again.

Happy coding!

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

    Which of these topics are you most interested in?
    ReactVueAngularNew frameworks
    Do you spend a lot of time reproducing errors in your apps?
    Which, if any, do you think would help you reproduce errors more effectively?
    A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
    Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

    Full visibility into production React apps

    Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

    LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

    The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

    Modernize how you debug your React apps — .

    Esteban Herrera Family man, Java and JavaScript developer. Swift and VR/AR hobbyist. Like books, movies, and still trying many things.

    Leave a Reply