JSX Fundamentals
The HTML-like syntax React components return, the rules it enforces, and what it actually compiles into.
2 min read
JSX lets you write markup directly inside JavaScript:
const element = <h1 className="title">Hello, world!</h1>;This isn't a template language and it isn't valid JavaScript on its own — it's syntax that a build tool (Vite, using esbuild/Babel under the hood) compiles into plain function calls before your code ever runs in the browser. The line above compiles to roughly:
const element = jsx("h1", { className: "title", children: "Hello, world!" });That's the whole trick: JSX is sugar over regular function calls that create JavaScript objects describing UI. Knowing this explains most of JSX's rules, which otherwise look arbitrary.
Embedding JavaScript expressions
Curly braces drop back into JavaScript from inside JSX:
const name = "Ada";
const element = <h1>Hello, {name}!</h1>;
const sum = <p>2 + 2 = {2 + 2}</p>;Anything that's a valid expression works — variables, function calls, ternaries, arithmetic. Statements (if, for, variable declarations) don't, because this compiles to a function argument, and a function argument has to be a single expression.
className, not class
class is a reserved word in JavaScript, so JSX uses className for the HTML class attribute (and htmlFor instead of for on labels). Most other HTML attributes carry over as-is, but multi-word ones become camelCase: onclick becomes onClick, tabindex becomes tabIndex.
A single root element
A component must return one root element, because JSX compiles to one function call, which can only return one value:
// Error: Adjacent JSX elements must be wrapped in an enclosing tag
function Bad() {
return (
<h1>Title</h1>
<p>Body</p>
);
}Wrap siblings in a parent element, or in a Fragment (<>...</>) when you don't want an extra <div> in the actual DOM:
function Good() {
return (
<>
<h1>Title</h1>
<p>Body</p>
</>
);
}Capitalization matters
JSX uses capitalization to decide whether a tag is a built-in HTML element or one of your components: <div> renders a DOM element, <Profile> renders your Profile component. This is why component names must always start with an uppercase letter — <profile> would be treated as an unknown HTML tag, not your component.
With the syntax down, the next lesson covers components themselves — how to define one, accept input through props, and compose them together.