Last updated: 2026-05-06

JSX (JavaScript XML)

JSX lets you write HTML-like code in JavaScript. In normal JavaScript, writing HTML code inside JavaScript will throw a syntax error. In React, we can write HTML inside JavaScript code to be rendered.

Example:

This is a JavaScript function that returns an HTML h1 tag. Outside React, this is not allowed because JavaScript and HTML codes are meant to be separate.

function App() {
  return <h1>Hello, Wariz</h1>;
}

This is possible in React because JSX is a syntax extension, added by the React toolchain (like Babel), that transforms the above code into pure JavaScript. Historically, this compiled to:

React.createElement("h1", null, "Hello, Wariz");

Since React 17, a new JSX transform was introduced that no longer requires React.createElement or even a import React from 'react' statement at the top of every file. The compiled output now uses an internal function from react/jsx-runtime automatically. This is why you will see modern React files using JSX without an explicit React import at the top.


What JSX makes convenient is the simplification of writing HTML concisely without having to use multiple lines of code. For example, if JSX isn't used, this is how the HTML above would have been written:

const heading = document.createElement("h1");
heading.textContent = "Hello, Wariz";
document.body.appendChild(heading);

Instead of this verbose code, we get to write it like this instead all because of JSX:

function App() {
  return <h1>Hello, Wariz</h1>;
}

Aside from just writing plain HTML, JSX also enables us to use variables, run logic, and compose more powerful components.


JSX Rules That Must Be Obeyed

1. Only One Root Element

Every component must have just one root element encapsulating its contents. This root can either be an HTML tag like div or a React Fragment <>.

With div:

return (
  <div>
    <h1>Hello</h1>
    <p>Welcome</p>
  </div>
);

With React Fragments:

return (
  <>
    <h1>Hello</h1>
    <p>Welcome</p>
  </>
);

React Fragments are preferred when you don't want to add an extra div to the DOM purely for wrapping purposes.

2. Use className Instead of class

To assign a CSS class to an element, HTML uses the class attribute. In JSX, class is a reserved JavaScript keyword, so className is used instead.

<h1 className="header">Hello</h1>

3. All Tags Must Be Explicitly Closed

In HTML, void elements like <img>, <input>, and <br> do not need closing tags. In JSX, every tag must be explicitly closed — either with a closing tag or a self-closing slash.

<img src="photo.jpg" />   // ✅ Correct in JSX
<input type="text" />     // ✅ Correct in JSX
<br />                    // ✅ Correct in JSX

<img src="photo.jpg">     // ❌ Error in JSX

This is one of the most common errors when converting existing HTML into JSX.

4. JavaScript Expressions Must Be Inside Curly Braces {}

In JSX, variables, logic, and expressions are wrapped in curly braces {} so they can be evaluated and rendered.

When using variables:

const name = "Wariz";
<h1>Hello, {name}</h1>  // ✅

When writing logic:

{isLoggedIn ? <p>Welcome back</p> : <p>Please log in</p>}
{count > 0 && <span>You have messages</span>}

5. Inline Styles Use a JavaScript Object, Not a String

In HTML, the style attribute takes a string:

<h1 style="color: red; font-size: 16px;">Hello</h1>

In JSX, style takes a JavaScript object with camelCased property names. Notice the double curly braces — the outer {} is the JSX expression wrapper, and the inner {} is the JavaScript object:

<h1 style={{ color: "red", fontSize: "16px" }}>Hello</h1>

CSS property names with hyphens are written in camelCase in JSX: font-size becomes fontSize, background-color becomes backgroundColor, and so on.


Dynamic Rendering with JSX

JSX allows you to render variables, expressions, and function calls — meaning you can show different things on the screen depending on data or logic.