"JSX is just JavaScript" – No.
#39 · 2021-07-06 (updated 2021-07-16) · JSX, JavaScript, template, HTML, CSSWhen discussing differences between JSX and markup-based template engines like the ones used with Angular/Vue.js/Svelte/others, one argument almost always comes up: "JSX is just JavaScript". People claim that you have to learn markup-based template systems while JSX is just JavaScript. Well, not quite. Both JSX and markup-based templates have to be learned first. JSX is not "just JavaScript". Is has several rules that are different from JavaScript, or HTML, or CSS. This is an incomplete list of these differences.
-
JSX is not valid JavaScript. A vanilla JavaScript parser does not recognize JSX. Code editors that support JavaScript have to add explicit support for JSX. The usual file extension for JSX is
*.jsx
, not*.js
. Browsers can neither parse nor execute JSX. Trying to do so will fail with syntax errors. Node.js cannot execute JSX code by default either. -
JSX uses curly braces for different things. They contain expressions and can evaluate to attribute values, node content or whole HTML elements including nested children.
-
Within the curly braces of JSX, you can only use expressions but not statements. That means you can't use any of the following JavaScript features (taken from MDN): Blocks,
break
,continue
,if...else
,switch
,throw
,try...catch
,var
,let
,const
,function
,function*
,async function
,class
,do..while
,for
,for...in
,for...of
,for await...of
,while
,debugger
,export
,import
,import.meta
, labels,with
, and likely other things. -
Unlike HTML, attributes in JSX are usually in camelCase. For example, you must use
tabIndex
instead oftabindex
. Unless, it is an ARIA attribute, then you have to use the hyphenated form likearia-x
. -
for
andclass
are reserved keywords in JavaScript. But they are also HTML attributes. In HTML, you can use them anyway. But in JSX, you have to use thehtmlFor
andclassName
attributes instead. -
JSX also adds some custom attributes like
defaultChecked
,defaultValue
,suppressContentEditableWarning
, andsuppressHydrationWarning
. Unfortunately, you can't tell from their names whether these are HTML or JSX attributes. -
JSX automatically escapes embedded values in order to avoid XSS attacks. If you want to overcome that, you have to use the custom
dangerouslySetInnerHTML
attribute and pass an object with a__html
property. -
The
style
attribute in JSX must be an object containing camelCased CSS rules like{fontSize: '16px'}
. -
The names of custom components must be Capitalized when used with JSX.
-
Empty HTML elements must be closed with a slash
/
. So<br>
is invalid syntax as you have to use<br/>
in JSX. In contrast, "just JavaScript" does not care about that difference. -
JavaScript has
// line comments
and/* block comments */
. JSX only supports block comments. -
JSX removes whitespace before and after each line. That is different from the usual representation of HTML, and it is the reason why JSX code often includes
{' '}
to enforce whitespace. -
Booleans,
null
, andundefined
don't render. For example,<div>{true}</div>
just renders an empty element. Note that falsy values do render, though. It is a common mistake to use something like{anArray.length && ...}
which would render as "0" for an empty array.
Sure, these rules can be learned quickly. But the same applies to most markup-based template engines. JSX is not "just JavaScript".