JSX vs HTML: Every Important Difference

JSX looks like HTML but follows stricter rules. See every important difference between the two syntaxes and avoid the most common conversion mistakes.

5 min read

The difference between JSX and HTML comes down to one rule: JSX is JavaScript, and HTML is a markup language the browser parses directly. JSX looks like HTML but compiles into JavaScript objects, so it is stricter about tags, attribute names, and how values are written.

A quick example shows the shift. HTML writes a class attribute; JSX writes the same idea with a camelCase prop:

App.jsxApp.jsx
function Button() {
  return <button className="primary">Save</button>;
}

React renders a button with the CSS class "primary." The rename exists because class is a reserved word in JavaScript, and JSX turns attributes into object properties.

JSX vs HTML at a glance

The table below lists the differences you will hit most often when moving an HTML mockup into a React component.

HTMLJSXWhy it changes
class attributeclassNameclass is reserved in JavaScript
for attributehtmlForfor is reserved in JavaScript
tabindextabIndexcamelCase naming
readonlyreadOnlycamelCase naming
style="color: red"style with an objectstyles are objects
unclosed img tagself-closing imgevery tag closes

Two groups of attributes keep their hyphens in JSX: aria attributes and data attributes. Everything else follows camelCase.

Attributes use camelCase

HTML attribute names are lowercase. JSX converts most of them to camelCase because they become JavaScript object properties, and JavaScript prefers camelCase.

The event attribute onload becomes onLoad, and the input attribute maxlength becomes maxLength. React prints a warning with the correct spelling when you get one wrong, so the mistake is easy to spot in the browser console. Think of the attribute as a JavaScript property: the name has to be a valid property name, which is why the hyphens disappear.

App.jsxApp.jsx
<input maxLength={40} onLoad={handleLoad} />

This input enforces a 40 character limit and runs the load handler when it finishes loading. The visible result matches the HTML version, but the names follow JavaScript rules.

Every tag must close

HTML forgives unclosed tags. A list item or image often works even when the closing tag is left out. JSX does not allow that.

App.jsxApp.jsx
<img src="avatar.png" alt="Profile" />
<br />

The image and line break are self-closing here. If you paste them as plain HTML, React shows a build error until the slash is added. JSX needs a closing slash so the compiler always knows where an element ends, with no ambiguity to resolve from context.

Inline styles are objects

HTML styles are strings. JSX styles are JavaScript objects with camelCase property names, so background-color becomes backgroundColor.

App.jsxApp.jsx
<p style={{ color: "crimson", fontSize: 18 }}>
  Keep moving.
</p>

The paragraph renders in crimson text at 18 pixels. The double braces are not a new syntax: the outer pair opens a JavaScript expression, and the inner pair is the style object itself. Margin and padding work the same way, so margin-top becomes marginTop and padding-left becomes paddingLeft.

Expressions replace static text

The biggest behavioral difference is that JSX can read JavaScript values. Where HTML needs a script to swap text, JSX embeds an expression directly.

App.jsxApp.jsx
const name = "Maya";
 
function Welcome() {
  return <h1>Hello, {name}</h1>;
}

The heading shows "Hello, Maya." The guide on rendering variables and expressions in JSX walks through what you can put between those braces.

Which should you use?

You never choose between JSX and HTML at the same level. HTML is what the browser renders in the end, and JSX is the syntax you write in source files.

A common false equivalence is treating JSX as a string of HTML. It is not. It compiles to objects, which is why the rules above exist.

For a full walk through those rules, the guide on what JSX is covers the syntax itself, and the guide on JSX attributes and inline styles goes deeper into styles and comments.

Rune AI

Rune AI

Key Insights

  • JSX compiles to JavaScript; HTML is parsed directly by the browser.
  • Most attributes switch to camelCase, such as className and htmlFor.
  • Every JSX tag must be closed, including img and br.
  • Inline styles are objects with camelCase property names.
  • aria-* and data-* attributes keep their hyphens.
RunePowered by Rune AI

Frequently Asked Questions

Why does JSX use className instead of class?

class is a reserved word in JavaScript, and JSX compiles to JavaScript. React uses className, which maps to the same DOM class attribute.

Can I write regular HTML inside a React component?

No. JSX looks like HTML but has stricter rules. Most valid HTML needs small edits, such as closing every tag and renaming a few attributes, before it becomes valid JSX.

Why do inline styles use two sets of curly braces?

The outer braces open a JavaScript expression, and the inner braces define a JavaScript object. Inline styles are objects with camelCase property names.

Conclusion

JSX and HTML share a visual shape, but JSX is JavaScript. It closes every tag, renames reserved attributes with camelCase, and replaces static style strings with objects. Learning those differences turns any HTML mockup into working React markup.