Skip to content

JSX in React

JSX lets you write HTML-like markup inside JavaScript. It is the most readable way to describe UI in React function components. This lesson covers JSX rules, expressions, attributes, and what happens when JSX is compiled.

What Is JSX?

JSX is a syntax extension for JavaScript that looks like HTML but lives inside your .jsx or .tsx files. React does not require JSX, but almost every modern React codebase uses it because it keeps UI structure close to the logic that drives it.

Under the hood, a build tool like Vite transforms JSX into React.createElement() calls (or the automatic JSX runtime in React 17+). You write <Button label="Save" />; the compiler outputs function calls that React's reconciler understands.

const element = (
  <div className="card">
    <h2>{title}</h2>
    <button onClick={handleSave}>Save</button>
  </div>
);

Curly braces embed JavaScript expressions. className replaces HTML's class because class is a reserved word in JavaScript.

JSX Rules You Must Know

// Single root (or use Fragment)
return (
  <>
    <Header />
    <Main />
  </>
);

// Self-closing tags required
<img src={logo} alt="Logo" />

// camelCase for DOM properties
<label htmlFor="email">Email</label>
  • Return one parent element, or wrap siblings in a Fragment (<>...</>).
  • All tags must be closed: <input />, not <input>.
  • Use className, htmlFor, and onClick instead of HTML attribute names.
  • JavaScript reserved words (class, for) cannot be used as JSX attribute names.

JSX Quick Reference

Common JSX patterns you will write daily.

Pattern Example Notes
Expression {user.name} Any valid JS expression
Conditional {isLoggedIn ? <Dashboard /> : <Login />} Ternary in JSX
List {items.map(i => <li key={i.id}>{i.name}</li>)} Always add keys
Fragment <><A /><B /></> No extra DOM node
Spread props <Input {...field} /> Pass object as props
Style object style={{ color: 'red' }} CamelCase CSS properties

How JSX Compiles

With the automatic JSX runtime (default in Vite + React 17+), you do not need to import React in every file just to use JSX. The compiler injects the correct import from react/jsx-runtime.

// JSX you write:
const el = <h1 className="title">Hello</h1>;

// Roughly compiles to:
import { jsx as _jsx } from 'react/jsx-runtime';
const el = _jsx('h1', { className: 'title', children: 'Hello' });

Understanding compilation helps when debugging transform errors or library integration.

JSX and Security

React escapes values embedded in JSX by default, which helps prevent XSS when rendering user-provided strings as text content.

Never use dangerouslySetInnerHTML with untrusted input. If you must render HTML from a CMS, sanitize it first with a library like DOMPurify.

Common Mistakes

  • Using class instead of className in JSX.
  • Forgetting curly braces around JavaScript expressions.
  • Returning multiple sibling elements without a Fragment wrapper.
  • Putting objects directly as children without converting to strings.

Key Takeaways

  • JSX is syntactic sugar for React.createElement / the JSX runtime.
  • Use className, camelCase attributes, and curly braces for expressions.
  • Fragments let you group elements without adding DOM nodes.
  • React escapes JSX text content by default for safer rendering.

Pro Tip

If JSX looks wrong in the browser, inspect the compiled output mentally: every tag becomes a function call with a props object.