Why Did And Don’t You Need To Import React

March 13, 2022 - 3 minutes

For a very long time in React development, it was necessary to import React in your JavaScript or TypeScript files that used React components. It wasn’t until React v17.0, which was released in August of 2020, that React introduced a new transform feature that allowed its developers to not have to do this anymore.

But why did we have to import it in the first place? What was the reason that we had to add this seemingly unused import every time we created React components? And why do we ‘suddenly’ not need it anymore?

The Reason We Needed It

If you’re unfamiliar with React development, it’s composed of a ton of so-called React components. The main philosophy behind React development is creating small components that can be reused and composable in different scenarios. To create React components, the standard is to use JSX which is a syntax extension to JavaScript.

An example of how such a component and JSX look is as follows:

import React from "react";

function Card({ content }) {
  return (
    <div>
      <CardBody size="medium">{content}</CardBody>
    </div>
  );
}

For most React developers, this will feel very familiar. It’s a straightforward Card component that accepts one prop. The component itself renders some HTML, a singular div, and another random React component called CardBody. To that latter component, we pass 2 props: the content prop that Card received as its children and a static value for its size prop.

Nothing fancy going on here. But in its current form, the browsers can’t do anything with it. As mentioned, JSX is a syntax extension created on top of JavaScript. The browser doesn’t understand JSX so when it tries to evaluate this code, it will just throw an error.

What does this have to do with having to import React? Well, ultimately your React code still has to be received and rendered by a browser. But rather than its current form, it will first be transformed into a form that the browser can understand: regular JavaScript. That would look as follows:

import React from "react";

function Card({ content }) {
  return React.createElement('div', null, React.createElement(CardBody, { size: 'medium' }, content));
}

All the syntactic sugar was removed and transformed to their respective JavaScript equivalents. Based on this, we can see that creating a React component using JSX is nothing more than a function call using 3 function arguments: the type of the component, its props in an object form, and its children.

But the most important thing to note is the function itself. Under the hood, React components are createElement calls and that function comes from React. Based on that, we can go back to the original question of this article and understand the necessity to import React whenever we created a React component. Without it, the transformed JSX code would fail in the browser as React needs to be in scope to create components through its createElement function.

The Reason We Don’t Need It Anymore

So now that we know why we needed it before, the next interesting question becomes why we suddenly don’t need it anymore. What changed in React v17.0 that set us free from having to perform this annoying and seemingly unused import of React in every file that uses JSX?

In short, React moved the functions for creating elements towards new entry points. Instead of relying on the createElement function that is exposed in the main entry point of the package, it was split off into entry points that are intended to be only used by compilers, like Babel and TypeScript.

So now while transforming JSX, compilers can, and will, automatically import the appropriate functions from those new entry points. This means that developers don’t have to manually add the React import as compilers don’t have to rely on the main entry point anymore. The example code, before and after transformation, will now look as follows:

function Card({ content }) {
  return (
    <div>
      <CardBody size="medium">{content}</CardBody>
    </div>
  );
}
// Inserted by a compiler
import { jsx as _jsx } from 'react/jsx-runtime';

function Card({ content }) {
  return _jsx("div", {
    children: _jsx(CardBody, { size: "medium", children: content })
  });
}

This feature was also backported to most of the older React versions for backwards compatibility. If you want to learn more about how you can also upgrade to this new JSX transform, it’s recommended to take a look at the upgrade guide.


After graduation, my career is entirely centered around learning and improving as a developer. I’ve began working full time as a React developer and I’ll be blogging about everything that I encounter and learn during this journey. This will range from improving communicational skills in a technical environment, becoming a better developer, improving technical skills in React and JavaScript, and discussing career related topics. In all of my posts, the focus will be on my personal experiences, learnings, difficulties, solutions (if present), and also flaws.

If you’re either interested in these topics, more personalised technical stories, or the perspective of a learning developer, you can follow me either on Twitter or at Dev to stay up to date with my blogposts. I’m always learning, so stay tuned for more stories! 🎉