DEV Community

Cover image for How JSX works?
M. Bagher Abiat
M. Bagher Abiat

Posted on • Updated on


How JSX works?

I put a post on my Twitter account and had a brief talk on how JSX works, So I want to explain more about it here.

Every ReactJS developer knows about the jsx magic, it let us write some HTML in javascript, and that's how the magic happens. We can do this kind of stuff in tools like babel.

For example, we have a babel plugin named @babel/plugin-transform-react-jsx that gives us the ability to work with JSX syntax.


We just need @babel/plugin-transform-react-jsx to start, you can install it with npm or yarn:

npm install --save-dev @babel/plugin-transform-react-jsx
# or
yarn add -D @babel/plugin-transform-react-jsx
Enter fullscreen mode Exit fullscreen mode


It's the time to dig into the magic and see what happens inside. In React 17, React core team replaced the classic React.createElement with the jsx and jsx functions, so you don't need to import React anymore to write jsx. Now, the @babel/plugin-transform-react-jsx uses the jsx function by default now, check out this:

const profile = (
    <img src="avatar.png" className="profile" />
    <h3>{[user.firstName, user.lastName].join(" ")}</h3>
Enter fullscreen mode Exit fullscreen mode

By default, babel is going to compile that jsx to this plain javascript:

import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";

const profile = _jsxs("div", {
  children: [
    _jsx("img", {
      src: "avatar.png",
      className: "profile",
    _jsx("h3", {
      children: [user.firstName, user.lastName].join(" "),
Enter fullscreen mode Exit fullscreen mode

That's how the magic works, easy as that!

Let's be a magician

We all love to do magical things, why we don't do it now, so let's do it! We need that babel plugin to do some magic.

Now we can tell the plugin to use our own function instead of react's functions. For that, we need to write a small comment to tell it.

/** @jsx logJsx */
Enter fullscreen mode Exit fullscreen mode

Here we tell it, we want to use logJsx for jsx syntax. For the logJsx function, we turn the jsx into a logged statement like "It's a div, Hello Mohammad". Now let's define the logJsx function:

// the babel plugin is going to pass this function the type and props/attributes 
function logJsx(type, props) {
  console.log(`It's a ${type}, Hello ${}`);
Enter fullscreen mode Exit fullscreen mode

We did it, check this:

<title name="Mohammad"></title> // type: "title" props: { name: "Mohammad" }
// console: It's a title, Hello Mohammad
Enter fullscreen mode Exit fullscreen mode

That's how jsx works, but in React, instead of logging, it gives us an object like this:

    type: "title",
    key: null,
    ref: null,
    props: {
        name: "Mohammad"
    _owner: null,
    _store: {}
Enter fullscreen mode Exit fullscreen mode

Now we saw what's going on underneath in React. If you know any other magic, comment it or mention me on Twitter and tell me about it.

I hope you enjoyed this article and learned something new. Don't forget to share and send reactions to my article. If you wanted to tell me something, tell me on Twitter or mention me anywhere else, You can even subscribe to my newsletter and follow me on Github. πŸ‘‹πŸ»

Top comments (4)

ironcladdev profile image
Conner Ow

This is like the post I've been looking for. I was always wondering why babel's syntax is so different than JS. I did not know that it would compile JS for you.

Thank you so much.

aslemammad profile image
M. Bagher Abiat

I'm really happy that you learned something new!

adnanaslam profile image
Adnan Aslam

good explanation

aslemammad profile image
M. Bagher Abiat

Thanks, Adnan.

11 Tips That Make You a Better Typescript Programmer


1 Think in {Set}

Type is an everyday concept to programmers, but it’s surprisingly difficult to define it succinctly. I find it helpful to use Set as a conceptual model instead.

#2 Understand declared type and narrowed type

One extremely powerful typescript feature is automatic type narrowing based on control flow. This means a variable has two types associated with it at any specific point of code location: a declaration type and a narrowed type.

#3 Use discriminated union instead of optional fields


Read the whole post now!