LearnContact
Lesson 921 min read

JSX (JavaScript XML)

Learn what JSX is, how to embed JavaScript expressions inside it, the rules it enforces, and how it compiles down to plain JavaScript.

Introduction

Every React component you have seen so far has returned something that looks a lot like HTML, sitting right inside JavaScript code. That syntax is JSX, and it is one of the first things that feels unusual about React — and one of the fastest things to feel completely natural.

This lesson explains exactly what JSX is, how to mix in dynamic JavaScript values using curly braces, the handful of rules JSX enforces, and what actually happens to your JSX by the time it reaches the browser.

What You Will Learn
  • What JSX is and why React uses it.
  • How to embed JavaScript expressions inside JSX with curly braces.
  • The core rules JSX enforces: single root element, className, closing tags, and camelCase events.
  • How JSX compiles down to React.createElement() calls via a build tool like Vite.

What Is JSX?

JSX (JavaScript XML) is a syntax extension for JavaScript that lets you write HTML-like markup directly inside your JavaScript code. It is not a separate templating language and it is not valid JavaScript on its own — it needs to be compiled by a build tool (like Vite, via Babel) before it can run in a browser.

A Simple JSX Example
function Greeting() {
  return <h1>Hello, React!</h1>;
}
Rendered on the Page
Hello, React!

JSX exists because describing UI is usually easier with markup than with a long chain of function calls. Instead of writing React.createElement("h1", null, "Hello, React!") by hand, you write something that looks like the HTML you already know — while still having the full power of JavaScript available around it.

Embedding Expressions with Curly Braces

The real power of JSX is that it is not static markup — you can drop any valid JavaScript expression into it by wrapping it in curly braces {}. This includes variables, function calls, arithmetic, ternaries, and more.

App.jsx
function App() {
  const name = "Amol";
  const items = ["React", "JSX", "Vite"];

  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>You have {items.length} topics to learn.</p>
      <p>{items.length > 2 ? "That is a lot!" : "Just getting started."}</p>
    </div>
  );
}
Rendered on the Page
Hello, Amol!
You have 3 topics to learn.
That is a lot!
Tip

Only expressions are allowed inside curly braces — things that produce a value, like name, items.length, or a ternary. Statements like if or for cannot go directly inside {}; you handle that logic in JavaScript above the return statement instead.

The Rules of JSX

Because JSX ultimately compiles to JavaScript function calls, it enforces a few rules that plain HTML does not.

① One Root Element

A component must return a single root element (or a Fragment) — you cannot return two sibling tags side by side.

② className, not class

Since "class" is a reserved JavaScript word, JSX uses className to set an element's CSS class.

③ Every Tag Must Close

Tags like <img> or <input> that have no children must be self-closed: <img /> not <img>.

④ camelCase Event Names

DOM events are written in camelCase, like onClick and onChange, instead of onclick.

Following the Rules
function Profile() {
  return (
    <div className="profile">
      <img src="/avatar.png" alt="User avatar" />
      <h2>Amol</h2>
      <button onClick={() => alert("Clicked!")}>Say Hi</button>
    </div>
  );
}

If you need multiple top-level elements without adding an extra <div> to the DOM, wrap them in a Fragment, written as <>...</> or explicitly as <React.Fragment>...</React.Fragment>.

Using a Fragment
function List() {
  return (
    <>
      <h2>Fruits</h2>
      <p>Apple, Banana, Mango</p>
    </>
  );
}

How JSX Compiles to JavaScript

Browsers do not understand JSX directly. When you run npm run dev or npm run build, Vite uses a compiler (Babel, under the hood) to transform every JSX tag into a plain JavaScript function call — React.createElement() — before the code ever reaches the browser.

What You Write (JSX)
function Greeting() {
  return <h1 className="title">Hello, React!</h1>;
}
What It Compiles To
function Greeting() {
  return React.createElement(
    "h1",
    { className: "title" },
    "Hello, React!"
  );
}
Both Produce
<h1 class="title">Hello, React!</h1>

This is exactly why a build tool like Vite is required for React projects — without it, the browser would encounter JSX syntax it simply cannot parse. Knowing this transformation happens under the hood also explains rules like "one root element": React.createElement() can only return one value, so a component can only return one element tree.

Common Mistakes

Avoid These Mistakes
  • Returning two sibling elements without wrapping them in a single parent or Fragment.
  • Using class instead of className, which React silently ignores rather than applying as a CSS class.
  • Forgetting to close self-closing tags, like writing <img> instead of <img />.
  • Writing lowercase event names like onclick instead of the camelCase onClick that JSX expects.
  • Putting a JavaScript statement (like an if block) directly inside curly braces instead of an expression.

Best Practices

  • Wrap multi-line JSX returned from a component in parentheses for readability.
  • Prefer Fragments (<>...</>) over an extra wrapping <div> when you do not need the extra DOM node.
  • Keep expressions inside curly braces short — move complex logic into a variable above the return statement.
  • Always close every tag, even ones that look like they might not need it.
  • Remember JSX is JavaScript — you can use any expression, but never a statement, inside {}.

Frequently Asked Questions

Is JSX required to use React?

No, technically you can write React.createElement() calls directly without JSX. In practice, virtually every React codebase uses JSX because it is far more readable.

Can I put an if statement inside curly braces in JSX?

Not directly — curly braces only accept expressions. Instead, compute the value with an if statement above the return, or use a ternary or logical && operator inline.

Why does React use className instead of just fixing "class"?

JSX compiles to JavaScript, and "class" is a reserved keyword in JavaScript (used for defining classes), so React had to pick a different attribute name.

What is a Fragment and when should I use one?

A Fragment (<>...</>) groups multiple elements without adding an extra node to the real DOM. Use it whenever a component needs to return multiple top-level elements but an extra wrapping <div> is not desired.

Does every project need Babel for JSX?

Not by name — Vite handles the JSX transformation for you automatically, using Babel or esbuild under the hood, so you rarely configure it directly.

Key Takeaways

  • JSX is a syntax extension that lets you write HTML-like markup inside JavaScript.
  • Curly braces {} embed any JavaScript expression directly inside JSX.
  • JSX requires a single root element (or Fragment), className instead of class, closed tags, and camelCase event names.
  • A build tool compiles JSX into React.createElement() calls before it reaches the browser.
  • Because a component can only return one value, it can only return one root element.

Summary

JSX is what makes React components feel readable — markup and logic living together in one place, backed by the full power of JavaScript. Once you understand that it is simply sugar for React.createElement() calls, its rules stop feeling arbitrary and start feeling like natural consequences of being JavaScript underneath.

In this lesson, you learned what JSX is, how to embed expressions with curly braces, the core rules JSX enforces, and how it compiles down to plain JavaScript. Next, you will look closely at what a React element actually is — the object JSX creates under the hood.

Lesson 9 Completed
  • You can read and write basic JSX confidently.
  • You can embed dynamic JavaScript values using curly braces.
  • You know the core rules JSX enforces and why they exist.
  • You understand that JSX compiles down to React.createElement() calls.
Next Lesson →

React Elements