How to enable new JSX transform in React?
Tags: javascript, react, babel, tutorial
Published: 2020-08-11 15:07:32

---
title: How to enable new JSX transform in React?
published: true
description: 
tags: javascript, react, reactjs, babel, tutorial
//cover_image: https://direct_url_to_image.jpg
---

The biggest feature of React 17, as React team claims, is that there are no new features. This isn't however entirely true.

In Babel 7.9.0, a [new JSX transform](https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154-https-githubcom-babel-babel-pull-11154) was announced. It could only be used in experimental React releases. Until now!

Before we dive into how to enable this feature, let's see the advantages:

### No more `import React from 'react'`

Yes! You'll no longer need to import React to each. and. every. component. you write. Instead, it will be imported automatically!

Well, not _quite_. If you use hooks, `lazy`, `Suspense` or any other import, you will still need to import them all manually. But no more importing `React` if you're not using `React` explicitly in your code, e.g. by calling `React.useState`. 

### Smaller bundle

A side effect of this change is also a slightly smaller bundle. In my case, on a moderately sized commercial application with ~1500 components, the savings were around 10.5 KiB. It ain't much, but arguably a welcome improvement.

Where do the savings come from? Take a look at transpiled code, before & after the change we're about to make:

```js
import React from "react";

function Foo() {
  return React.createElement("div");
}
```

```js
import { jsx as _jsx } from "react/jsx-runtime";

function Foo() {
  return _jsx("div");
}
```

Turns out, this can add up!

## Enough talking, let's do it!

### Make sure you're all up to date

To continue, you're going to need:

* Babel & `@babel/preset-react` `7.9.0` or later
* React:
  * 17: `17.0.0` or later, 
  * 16: `16.14.0` or later,
  * 15: `15.7.0` or later,
  * 0.14: `0.14.10` or later

For example, you can use

```sh
npm install @babel/core@^7.9.0 @babel/preset-react@^7.9.0 --dev
npm install react@^16.14.0 react-dom@^16.14.0
```

or 

```sh
yarn add @babel/core@^7.9.0 @babel/preset-react@^7.9.0 --dev
yarn add react@^16.14.0 react-dom@^16.14.0
```

to update your React 16 app. 

You can also jump straight to React 17. _Note that React 17 contains some breaking changes when compared to React 16. Upgrade carefully!_

### Babel configuration

Your Babel configuration (`.babelrc`, `.babelrc.json`, or similar) needs a small change: In `presets` section, to

```json
  "@babel/preset-react"
```

preset you'll now need to pass `"runtime": "automatic"` option. Change the above line to:

```json
  ["@babel/preset-react", {
    "runtime": "automatic"
  }]
```

That's it! You're done! 🥳

### Cleaning up

Alright, not quite. You're now left with redundant React imports. Cleaning them up is optional, because modern bundlers will ignore unused imports. If you still want to do the cleaning, continue reading.

If you used e.g. `React.useState` or `<React.Fragment>` (as opposed to `useState` or `<>`), the easiest approach would be to get rid of all `React.*` occurrences first.

Then, you'll be free to remove "pure" React imports by replacing (using RegEx):

```
import React from ['"]react['"];?\n
```

with an empty string, and replacing

```
import React,\s?(\{.*\})\s?from (['"]react['"])
```

with

```
import $1 from $2
```

which should leave only named imports in a vast majority of cases.

### ESLint configuration

Changes are ESLint will complain about you no longer importing `React` in files where you're using JSX. If that's the case, all you need to do is simply turn off these rules:

```
  "react/jsx-uses-react": "off",
  "react/react-in-jsx-scope": "off",
```

## Happy coding!