← Back to React Course | Chapter 2: JSX & Rendering Fundamentals | Lesson 1 of 10

Introduction to JSX

JSX lets you write what a webpage should look like right inside your JavaScript, like drawing a picture directly inside your to-do list.

What JSX Looks Like

JSX is a syntax extension that lets you write HTML-like tags directly inside JavaScript. Under the hood, each JSX tag compiles down to a React.createElement() call -- JSX is just a friendlier way to write that.

Note: JSX isn't valid plain JavaScript by itself -- it has to be compiled (by Babel or a bundler) before it runs in a browser.

Warning: Forgetting to wrap multi-line JSX in parentheses after return can cause JavaScript's automatic semicolon insertion to cut your return short.

Example: What JSX Looks Like

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
function Hello() {
  return <p>This is JSX -- it looks like HTML but is JavaScript.</p>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<Hello />);
  </script>
</body>
</html>

A Single Root Element

A component's JSX must return exactly one top-level element -- you can't return two sibling tags side by side without wrapping them in a parent.

Note: Wrap sibling elements in a single <div> (or a Fragment, covered later) to satisfy this rule.

Warning: Returning <p>One</p><p>Two</p> directly (two siblings, no wrapper) is a syntax error in JSX.

Example: A Single Root Element

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
function TwoLines() {
  return (
    <div>
      <p>First line</p>
      <p>Second line</p>
    </div>
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(<TwoLines />);
  </script>
</body>
</html>

JSX Attributes Use camelCase

HTML attributes like onclick and tabindex become onClick and tabIndex in JSX, following JavaScript's camelCase convention instead of HTML's lowercase convention.

Note: When something looks right but does nothing, double-check the attribute is camelCased correctly.

Warning: Using onclick (lowercase) instead of onClick in JSX doesn't error -- it just silently does nothing, since React doesn't recognize it as an event handler prop.

Example: JSX Attributes Use camelCase

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
function ClickNote() {
  return <button onClick={() => alert('Clicked!')}>Click me</button>;
}
ReactDOM.createRoot(document.getElementById('root')).render(<ClickNote />);
  </script>
</body>
</html>
Common Mistakes
  1. Writing JSX outside of a function that returns it, expecting it to display automatically.
  2. Forgetting JSX must have exactly one root element wrapping everything returned.
  3. Using class instead of className for CSS classes, since class is a reserved word in JavaScript.
Chapter Summary
  • JSX is a syntax extension that lets you write HTML-like markup inside JavaScript.
  • It gets compiled (via Babel) into regular JavaScript function calls.
  • JSX expressions must return a single root element.
  • JSX uses camelCase attribute names like className and onClick.
Browser Support

JSX itself never runs directly in a browser -- it must be compiled first, either at build time (Babel/Webpack/Vite) or via the Babel standalone CDN for quick demos.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.