introduccion-jsx-react

What is JSX and how is it used in React

  • 5 min

JSX (JavaScript XML) is a syntax extension for JavaScript created by the React team to make writing components easier.

JSX allows you to write component structure similar to HTML within JavaScript code, combining both languages in a more intuitive way.

  1. It’s very readable: JSX looks like HTML, which makes the code easier to understand.
  2. It’s more expressive: It allows you to describe the user interface structure in a declarative way.
  3. It’s safer: JSX prevents certain types of errors and even security issues.

It’s a mix between HTML and JavaScript that might seem confusing at first, but it’s one of the most distinctive features of React (and one of the reasons why it’s so popular).

Let’s see an example of JSX and this “mix of JavaScript and HTML languages”

const element = <h1>Hello, world!</h1>;
Copied!

In this example,

  • element is a variable containing a piece of JSX.
  • As you can see, I didn’t need to use ", or anything like that (because it’s not a string, it’s a piece of JSX)

It’s not mandatory to use it in React, but it’s highly recommended due to its clarity and safety.

Basic JSX Syntax Rules

As we said, JSX looks a lot like HTML, but it’s not exactly HTML (it has its own syntax).

Therefore, it has its own rules and some (few) important differences. Here are the main ones:

JSX allows the use of standard HTML tags, such as <div>, <h1>, <p>, etc. However, there are some key differences:

  • JSX requires all tags to be closed, even those that don’t need it in HTML (like <br>, <img>, <input>).
// ❌ Incorrect
<img src="photo.jpg">

// ✅ Correct
<img src="photo.jpg" />
Copied!
  • Custom tags: JSX allows the use of custom component names, which must start with a capital letter.
<MyComponent />
Copied!

In JSX each component or fragment must return a single parent node. For example, this is incorrect:

// ❌ This will throw an error
return (
  <h1>Title</h1>
  <p>Description</p>
);
Copied!

To fix it, you can wrap everything in a <div>:

// ✅ Correct
return (
  <div>
    <h1>Title</h1>
    <p>Description</p>
  </div>
);
Copied!

Or use a Fragment (<>...</>), which doesn’t add extra nodes to the DOM:

return (
  <>
    <h1>Title</h1>
    <p>Description</p>
  </>
);
Copied!

Instead of using classic HTML attributes (class, for, etc.), JSX uses camelCase names following JavaScript conventions.

HTMLJSX
classclassName
forhtmlFor
onclickonClick
// ❌ Incorrect
<div class="container"></div>

// ✅ Correct
<div className="container"></div>
Copied!

Comments in JSX are written inside curly braces {} and use JavaScript comment syntax (/* ... */).

<div>
  {/* This is a comment in JSX */}
  <p>Hello, world!</p>
</div>
Copied!

JSX and Expressiveness with JavaScript

JSX is not a static template: it’s embedded JavaScript code with HTML-like syntax… but it’s still JavaScript.

Therefore, you can use variables and expressions inside the “HTML” fragments (that’s most of the point of JSX).

To do this, you can pass strings, variables, or even objects. For example,

const user = {
  name: "Luis",
  age: 22
};

return (
  <div>
    <h2>Profile</h2>
    <p>Name: {user.name}</p>     // this prints "Luis"
    <p>Age: {user.age}</p>             // this prints "22"
  </div>
);
Copied!

In the end, it’s just string interpolation under the hood, with a bit of syntactic sugar (well, with a lot of syntactic sugar).

Similarly, you can use variables and expressions in HTML attributes. For example, for the class (or any other),

const title = "Hello";
const className = "red";

return (
  <h1 className={className}>{title} world</h1>
);
Copied!

Even inside {} you can put operations, functions, or almost any JavaScript expression. For example:

const name = "Ana";
return <p>Hello, {name.toUpperCase()}!</p>;
Copied!

Although it’s advisable not to go crazy putting very long things inside the {}. If you need to, create an independent variable.

Component Composition

We mentioned that JSX allows adding new tags (which are precisely the components we’re going to create in React).

By extension, we can also compose components as if they were HTML tags. That is, if you have a Button component, you can use it like this:

function Button() {
  return <button>Click here</button>;
}

function App() {
  return (
    <div>
      <h1>Welcome</h1>
      <Button />
    </div>
  );
}
Copied!

Notice that custom component names must always start with a capital letter (<Button />, not <button />), so React can distinguish them from HTML tags.

Internal Operation Advanced

Although we don’t see it, under the hood, all our JSX is transformed into standard JavaScript code, fully compatible with the browser.

Specifically, it’s converted into calls to React.createElement. For example, the following JSX code:

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

Will be transformed into:

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

Which, we can agree, is much less readable, and we wouldn’t want to write it by hand (right? 🤭)

This transformation is performed by tools like Babel or ESBuild or similar, which handle these operations transparently for us.

We are using Vite, which internally uses ESBuild for the conversion.