DEV Community

Wojciech Maj
Wojciech Maj

Posted on • Edited on

How to enable new JSX transform in React?

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 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:

import React from "react";

function Foo() {
  return React.createElement("div");
}
Enter fullscreen mode Exit fullscreen mode
import { jsx as _jsx } from "react/jsx-runtime";

function Foo() {
  return _jsx("div");
}
Enter fullscreen mode Exit fullscreen mode

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

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
Enter fullscreen mode Exit fullscreen mode

or

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
Enter fullscreen mode Exit fullscreen mode

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

  "@babel/preset-react"
Enter fullscreen mode Exit fullscreen mode

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

  ["@babel/preset-react", {
    "runtime": "automatic"
  }]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

with an empty string, and replacing

import React,\s?(\{.*\})\s?from (['"]react['"])
Enter fullscreen mode Exit fullscreen mode

with

import $1 from $2
Enter fullscreen mode Exit fullscreen mode

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",
Enter fullscreen mode Exit fullscreen mode

Happy coding!

Top comments (2)

Collapse
 
daavidaviid profile image
David Guerin

Thanks 🙌

Collapse
 
igortas profile image
Igor Tashevski

Module '"react/jsx-runtime"' has no exported member 'jsxs'