What is JSX and how does it work?

React

The short answer

JSX is a syntax extension for JavaScript that lets you write HTML-like code inside your JavaScript files. It is not valid JavaScript on its own — a build tool (like Babel or SWC) transforms it into regular JavaScript function calls (React.createElement) before the browser sees it.

What JSX looks like

const element = <h1 className="title">Hello, world!</h1>;

This looks like HTML, but it is JavaScript. The build tool transforms it into:

const element = React.createElement(
'h1',
{ className: 'title' },
'Hello, world!'
);

React.createElement returns a plain JavaScript object that describes the element:

{
type: 'h1',
props: {
className: 'title',
children: 'Hello, world!'
}
}

This object is called a React element. React reads these objects and uses them to build and update the DOM.

JSX is just JavaScript

Since JSX is transformed into JavaScript, you can use any JavaScript expression inside it by wrapping it in curly braces:

const name = 'John';
const age = 30;
const element = (
<div>
<h1>{name}</h1>
<p>Age: {age}</p>
<p>Next year: {age + 1}</p>
<p>{age >= 18 ? 'Adult' : 'Minor'}</p>
</div>
);

You can use variables, function calls, ternary operators, and any other JavaScript expression inside {}. The only thing you cannot put inside {} is statements like if/else or for loops — only expressions that produce a value.

How JSX differs from HTML

There are a few differences you need to know:

1. className instead of class:

// JSX
<div className="container">...</div>
// HTML
<div class="container">...</div>

class is a reserved word in JavaScript, so JSX uses className.

2. htmlFor instead of for:

<label htmlFor="email">Email</label>

3. camelCase for attributes:

<div onClick={handleClick} tabIndex={0} />

HTML attributes like onclick, tabindex become onClick, tabIndex in JSX.

4. Self-closing tags are required:

// JSX — must self-close
<img src="photo.jpg" />
<input type="text" />
<br />
// HTML — self-closing is optional
<img src="photo.jpg">
<input type="text">
<br>

5. Style takes an object, not a string:

// JSX
<div style={{ backgroundColor: 'red', fontSize: '16px' }} />
// HTML
<div style="background-color: red; font-size: 16px;"></div>

Conditional rendering in JSX

Since you cannot use if/else inside JSX directly, there are common patterns:

// Ternary operator
{
isLoggedIn ? <Dashboard /> : <Login />;
}
// Logical AND (short-circuit)
{
showBanner && <Banner />;
}
// Early return
function Component({ isLoading }) {
if (isLoading) return <Spinner />;
return <Content />;
}

Rendering lists

You use map to render arrays:

const items = ['Apple', 'Banana', 'Cherry'];
<ul>
{items.map((item) => (
<li key={item}>{item}</li>
))}
</ul>;

Each item needs a unique key prop so React can track which items changed.

Common Pitfalls

A common mistake is forgetting that JSX expressions must return a single root element. If you have multiple elements, wrap them in a <div> or use a React Fragment (<>...</>). Another common mistake is using class instead of className — this will not throw an error in modern React, but it is not the correct JSX syntax.

Interview Tip

When explaining JSX, the key point is that it is not HTML — it is a syntax that compiles to React.createElement calls. Show the transformation from JSX to createElement to prove you understand what happens behind the scenes. Interviewers also like to hear about the differences between JSX and HTML (className, camelCase attributes, self-closing tags).

Why interviewers ask this

JSX is so fundamental to React that it is easy to take for granted. Interviewers ask about it to see if you understand that JSX is not magic — it is a compile step that produces JavaScript objects. A candidate who can explain the transformation shows they understand how React works at a deeper level than someone who just writes JSX without thinking about it.