JSX is the syntax you will spend most of your time writing in React. It looks like HTML sitting right inside your JavaScript, and that is intentional — it keeps the markup and the logic that drives it next to each other instead of split across separate template files.
A first component
function ProfileCard() {
return (
<div className="card">
<h2>Ada Lovelace</h2>
<p>Mathematician and writer.</p>
</div>
);
}Notice className instead of class — since class is a reserved word in JavaScript, React renames the HTML attribute. This trips up almost everyone the first time they copy-paste HTML into a component.
Embedding real JavaScript values
Curly braces let you drop any JavaScript expression straight into your markup:
function ProfileCard() {
const name = "Ada Lovelace";
const yearsActive = 2024 - 1815;
return (
<div className="card">
<h2>{name}</h2>
<p>Active for roughly {yearsActive} years.</p>
</div>
);
}Anything that is a valid JavaScript expression works inside those braces: variables, function calls, ternaries, arithmetic. Statements like if do not work directly inside JSX, which is why you will see a lot of ternary operators and short-circuit && expressions in React code once you start handling conditional rendering.
Composing components together
The real power shows up once components render other components:
function App() {
return (
<div>
<ProfileCard />
<ProfileCard />
</div>
);
}Each <ProfileCard /> is a self-closing tag, the same way <img /> is in HTML. A React app is really just one big tree of components like this, starting from a root App component at the top.
A couple of JSX rules worth knowing early
- A component must return a single root element — wrap sibling elements in a
<div>or an empty<>...</>fragment. - Every element needs to be properly closed, including ones like
<input />that you might leave open in plain HTML. - Component names must start with a capital letter —
profileCardwould be treated as a plain HTML tag, not your component.
Next up: passing data into components with props, and giving them memory with the useState hook — that is where components actually start reacting to things.