Skip to main content
5

JSX Tutorial: Complete Guide to React's JavaScript Syntax Extension

React Fundamentals 7 min read Updated June 19, 2025 Free

Master JSX, the syntax extension for JavaScript that makes writing React components more intuitive and efficient.

A React component is a Javascript function starting with a capitalized letter and returning an Html-like Markup known as JSX.

A diagram representing what a react component is composed of

Introduction

JSX is considered a syntax extension for Javascript. Yes you heard it right, it’s a syntax extension for Javascript and not for Html as many people think.

Meaning that, the JSX is converted to valide Javascript Code 😮.

Under the hood, the conversion is done by compilers like Babel or SWC. Consequently the whole component tree representing our App get converted into Javascript objects that can be understood by the browser and used by the React runtime to render the final Html code.

For example the code bellow.


function Image() {
  return <img alt="Blog post image" src="https://picsum.photos/500/400" />;
}

function App(){
    return (
        <Image/>
    )
}

will get converted to:

import { jsx as _jsx } from "react/jsx-runtime";
function Image() {
  return /*#__PURE__*/_jsx("img", {
    alt: "Blog post image",
    src: "https://picsum.photos/500/400"
  });
}
function App() {
  return /*#__PURE__*/_jsx(Image, {});
}

the role of the _jsx function is to build and return the object representing the JSX node.

So instead of writing all of that, we use JSX for its conciseness. It’s easier to write and looks mostly like the final Html code that will get shipped into the user’s browser.

In this article, we will see why it’s even a good idea to co-locate the markup with its corresponding Javascript logic in a single placeReact component.

Then we will question What makes JSX different from ordinary Html code? And finally we are going to understand how to use JSX code correctly and connect it with the component’s javascript logic using the magical curly bracket syntax {}.

So if that sounds interesting let’s dive in.

Why Co-locate Markup and Logic?

In traditional or Vanilla Javascript, the Markup and the Javascript logic live in separate files. That was totally fine when most of the applications were mostly relying on server side logic with minimal interactivity.

As the years have rolled by, the world understood the psychological and business benefits of User experience or UX; hence, the need for more interactive and engaging websites.

An example For that is a welcome component which only gets displayed when the user is logged in

function Welcome() {
  const isLoggedIn = true;
  
  if (!isLoggedIn) {
    return null;
  }
  
  return <h1>Welcome back!</h1>;
}

If the user is not logged in we just return null if it’s logged in we display this welcome message.

The fact that a component is its own block of Markup plus Logic ensures that changes to either of the two are always synced together.

In traditional web pages the whole Html is stored in a single file. Consequently changing one line may break the whole page.

But that’s not the case for React, because every component has its own Markup. So modifying a component’s Markup may only break the component itself with only the other components that depend on it but not the whole page.

JSX vs HTML: Key Differences

Okay, Next let’s compare between Html and JSX.

The syntax is almost the same but JSX is more strict.

First Rule

So the first rule consist of always closing the tags in JSX including self closing tags like <img/> or wrapping tags like <div>s.

function App(){
 return (
   <div> // ✅

   <img> // ❌ 
   <img/> // ✅

   </div> // ✅
 )
}

Second Rule

The second rule states that attributes expect these two special ones (data-, and aria-) and component names should be always written in camel case.

function my_component(){/*...*/} // Snake case ❌
function MyComponent(){/*...*/} // Camel case ✅
<button tab-index={0}> </button>  // Kabab case ❌
<button tabIndex={0}> </button>  // Camel case ✅

It’s also worth mentioning that Attribute names like class that comes to be reserved keywords in the Javascript language are not allowed. So instead of class you write className.


 <div class="..."> </div>  // ❌
 <div className="..."> </div> // ✅

Third Rule

The third important rule is that you can’t return a bunch of children tags without wrapping them in a parent root element.

Remember that JSX get transpiled or converted into a plain Javascript object. So as you can’t return multiple objects from a single function without wrapping them in an array or a parent object, you also can’t just return a bunch of children tags without wrapping them in a root element like a div or any other JSX tag.

function invalidFunction(){
  return {key:"sidali"}, {key:"I don't know"}; // ❌
}

function validFunction(){
  return [{key:"Neovim"},{key:"Btw"}]; // ✅
}

Using a div as a wrapper can be annoying sometimes, especially when styling elements. Instead there is a built-in React alternative which you can use.

It’s the fragment component: so you can either wrap your component in a Fragment component imported from react, or just use the concise syntax which consist of an empty tag element <>wrapped content here...</>.

function IncorrectComponent(){ // ❌
  return (
    <h1>Title</h1>
    <div>Description </div>
  )
}
import React from 'react'
function CorrectComponent1(){ // ✅
  return (
    <React.Fragment>
      <h1>Title</h1>
      <div>Description </div>
    </React.Fragment>
  )

// Or more concisely

function CorrectComponent2(){ // ✅
  return (
    <>
      <h1>Title</h1>
      <div>Description </div>
    </>
  )

Using JavaScript in JSX

Sure we can perform any kind of Javascript logic in the function’s body before returning the JSX including if statements, for loops and so on.

But is there a built-in way to use Javascript or reference a Javascript value or object from within the JSX code itself?

Yes, and it’s pretty simple just use the curly bracket syntax {} and then reference any variable, value, function or expression from the Javascript world 🌎.

So instead of hard coding the title value in the Markup here, we can store the h1 tag inner content in a Javascript variable as a string.

And then reference it in the Markup, using the curly bracket syntax like this.

function App(){
  const title = "This is my first react component";

  return (
    <div>
      <h1>{title}</h1>
      <ol>
        <li>Wake up</li>
        <li>Code</li>
        <li>Eat</li>
        <li>Sleep</li>
        <li>Repeat</li>
      </ol>
    </div>
  );
}

You can think of the curly brackets {} as a Javascript return statement, so any Javascript expression which outputs something is valid to use within the curly brackets {}.

So instead of hardcoding the h1 tags, we could have created a createTitle arrow function which takes a title and then returns it wrapped within h1 tags.

Subsequently, we can use it inside the Markup by employing the curly brackets syntax {}, then calling the function that returns the JSX.

function App(){
  const title = "This is my first react component";
  const createTitle = (title) => <h1>{title}</h1>;

  return (
    <div>
      {createTitle(title)}
      <ol>
        <li>Wake up</li>
        <li>Code</li>
        <li>Eat</li>
        <li>Sleep</li>
        <li>Repeat</li>
      </ol>
    </div>
  );
}

As you can see, JSX can be stored normally in a Javascript variable, and then rendered in the Markup later.

Keep in mind that, You can store any JSX code in a Javascript variable following the same rules which you normally follow within the Return () statement.

Remember that The brackets are optional unless your JSX code spans more than one line.

const var1 = <h1>This is my first react component</h1>;
const var2 = (
  <div>
    {var1}
    <ol>
      <li>Wake up</li>
      <li>Code</li>
      <li>Eat</li>
      <li>Sleep</li>
      <li>Repeat</li>
    </ol>
  </div>
);

You can use the curly bracket syntax to set any attribute into a string, let’s say the className attribute.

Other attributes like style require passing an object, including your inline css code in camel case instead of kebab case as you used to do in normal Html or CSS code.

/* CSS kebab-case */
background-color: black;
color: pink;
function App(){
  const title = "This is my first react component";
  const createTitle = (title) => <h1>{title}</h1>;
  const classNameValue = "class1 class2";
  const style = {
    backgroundColor: 'black',
    color: "pink"
  };
  
  return (
    <div className={classNameValue} style={style}>
      {createTitle(title)}
      <ol>
        <li>Wake up</li>
        <li>Code</li>
        <li>Eat</li>
        <li>Sleep</li>
        <li>Repeat</li>
      </ol>
    </div>
  );
}

Many get confused with the double curly brackets {{}}, when passing the style object directly like this.

<img style={{backgroundColor:'red'}}/>

Thinking that it’s a special JSX syntax, but in fact it’s not we are just passing a normal Javascript object within the curly bracket syntax.

function App(){
  const styleObj =  {backgroundColor:'red'}

  return(
  <img style={styleObj}/> // Instead of style={{backgroundColor:'red'}}
  )
}

Conclusion

So that was it for JSX, in the next article we will learn about a new way that allows us to make React components more generic and reusable while allowing bidirectional data flow from parents component to their direct or indirect children.

Let me know in the comment sections below if you have any questions or thoughts about the article. Thanks for your attentive reading and happy coding.