React 17 introduces new JSX transform


What is a JSX Transform?

JSX, as we know, is an HTML-like syntax that is used by React components to render in the browser.

Example JSX -

import React from 'react';

function Greet() {
  return <h1>Hello, world!</h1>;
}

But, browsers do not understand this as JSX is not valid JavaScript code.

This is where a transpiler like Babel comes into the picture. A Babel plugin called @babel/plugin-transform-react-jsx transforms JSX into standard JavaScript objects that a JavaScript engine can parse.

Before

The result of transpiling the above example with Babel is:

import React from 'react';

function Greet() {
  return React.createElement('h1', null, 'Hello, world!');
}

However, notice that we are using import React from 'react';, which is what makes the above code work.

Although there is no reference to React before transpilation, we must import React in any file that contains JSX. This is because there is a reference to React post transpilation as we can see here -

React.createElement('h1', null, 'Hello, world!');

In the older version of React (versions < 17), the JSX transform relied on the name React being in the scope of JSX i.e., we had to import ‘React’ to use JSX.

After

Now, with React adding support for a new version of JSX transform, React and, React-like libraries can optimize the creation of JSX elements.

In React 17 and starting with Babel version v7.9.0, @babel/plugin-transform-react-jsx plugin automatically imports “special functions” from the new React package when needed so that we don’t have to manually include them.

Do note that the new React packages - react/jsx-runtime and react/jsx-dev-runtime, are intended to only be used by transpilers like Babel.

Now we can write JSX like below:

function Greet() {
  return <h1>Hello, world!</h1>;
}

This gets transpiled to:

// Inserted by a transpiler (don't import it manually)
import {jsx as _jsx} from 'react/jsx-runtime';

function Greet() {
  return _jsx('h1', { children: 'Hello, world!' });
}

To add support for the new JSX transform in Babel manually, we can pass { "runtime": "automatic" } as against { "runtime": "classic" } (which is the default) to @babel/preset-react or @babel/plugin-transform-react-jsx):

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

Benefits of the new JSX transform

  • We no longer have to import “React” to write JSX.
  • Slight reduction in the application’s bundle size.

For more details, head over to React’s official blog on the introduction of the new JSX transform.