Migrate React-Scripts v2.x to v3.0.0

Oleksandr Hutsulyak
Team Lead & Senior Front-End Engineer at TechMagic. Member of Solution Architecture Group. Passionate about JavaScript and AWS.
Migrate React-Scripts v2.x to v3.0.0

On April 22, 2019, Facebook react-scripts v3.0.0 was released. In this article I’ll try to describe a process of migration in general, with some issues and solutions to them, I’ve experienced while doing this migration.

On April 22, 2019, Facebook react-scripts v3.0.0 was released. In this article I’ll try to describe a process of migration in general, with some issues and solutions to them, I’ve experienced while doing react-scripts migration.

Most notable features of this release are:

  • React Hooks are now fully supported
  • TypeScript linting now integrated into ESLint
  • Absolute imports using jsconfig.json or tsconfig.json
  • Also, bug which made react-scripts test --coverage impossible to run in watch mode, is now fixed

Update react-scripts

To make update the react-scripts latest version, according to release notes, you should run the following command inside your project’s directory terminal:


Note: during an update, you may see that react-scripts package depends on a different version of some of your dependencies (ex. eslint , or any other dependency). In that case, you can remove explicitly provided dependencies it clashes with from your package.json file (all except typescript) and then — re-run installation command above. In case of a typescript, you’ll need to type and save its version inside package.json. This way, step-by-step you’ll trust react-scripts to install and maintain dependencies it relies on (and will clean your package.json file as a slight bonus).

Migrate rules from TSLint to ESLint

Next big thing might be moving all of your Typescript linting rules from tslint.json into .eslintrc :

  • if you’re starting from a scratch, create an empty .eslintrc file in the root of your project’s directory and add the following basic configuration there:
  • if you already have an existing .eslintrc config, make sure it already extends "react-app" . It is being made to properly show you all of react-script bundled rules during manual linting or inside of your code editor of choice (in my case that’s VSCode).
  • now copy-paste all of your tslint rules from tslint.json -> "rules" section into .eslintrc -> "rules" section.
  • the next step will be running eslint with command below and checking for possible rules syntax errors:

Note: errors will relate to true or false set for rules, which expect 0, 1, 2 or "off", "warn", "error" as a value correspondingly.

  • If you have multiple tslint configs for linting code on different stages (ex. separate dev and separate pre-commit configs), don’t forget doing the same operation for them, but naming files accordingly.

Note: as an alternative, you can skip everything related to rules copy-pasting above and just re-write your rules from scratch using http://ESlint.org/docs/rules documentation and then continue from the next step.

  • fix your npm scripts inside package.json to use eslint instead of tslint .

Note: if needed, you can specify needed config for each separate npm script with --config flag (ex. eslint --config .eslintrc --fix \”src/**/*.{ts,tsx,js}\”).

  • now lint your files and fix all possible errors
  • remove all tslint related files and configs from package.json and re-run your npm install or yarn to clean node_modules folder from stale dependencies.

Absolute imports

Now, react-scripts supports absolute imports based on jsconfig.json / tsconfig.json baseUrl setting. To configure it, create or update your jsconfig.json or tsconfig.json with following lines:

Note: currently the only supported options for baseUrl are node_modules which are set by default, and src .

Starting from this point, you can import your components specifying the relative path to your src folder, instead of writing a long chain of our beloved ../../../ :

A small note on Jest tests file naming

If your tests file names don’t have a .spec or .test suffix, and for instance are called simply as test.tsx (like it was in my case) — they won’t be discovered by a react-scripts test runner. As a result, you’ll need to rename them not to be called as test.tsx but to include this suffix in their name (ex. Button.test.tsx).

Another note on react-scripts test

If in your development process you relied on the react-scripts test --coverage running only once (ex. — CI run, or some pre-commit hook), it’s now running in watch mode by default. So to fix that, you’ll need to add --watchAll=false flag, to make sure it will not run in a watch mode.

Good luck!

Was this helpful?
Subscribe to our blog

Get the inside scoop on industry news, product updates, and emerging trends, empowering you to make more informed decisions and stay ahead of the curve.