DEV Community

Brian Neville-O'Neill
Brian Neville-O'Neill

Posted on • Originally published at on

What’s new in Create React App 3

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.

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:

import React, { useState } from 'react';
// ...

function App() {
  if(1 !== 0) {
    const [count, setCount] = useState(0);

  return (
    /* ... */

// ...

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!

Plug: LogRocket, a DVR for web apps

LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

Try it for free.

The post What's new in Create React App 3 appeared first on LogRocket Blog.

Top comments (0)