JSX is syntax sugar, not something React runs. Babel or TypeScript compiles each JSX tag into a call to createElement, or to jsx and jsxs from react/jsx-runtime with the automatic runtime. React only needs the resulting element objects, so you can skip JSX and call those functions yourself. The production trade-off is tooling: the JSX setting must match across packages, and lint rules must not still expect React in scope.
Frontend interview practice question
How does JSX get transformed, and why doesn’t React require it?
Interview quick answer
Interview focus
This React interview question tests whether you can explain JSX transformed in React and do you need it, connect it to production trade-offs, and handle common follow-up questions.
- JSX transformed in React and do you need it explanation without falling back to memorized definitions
- Jsx and Tooling reasoning, edge cases, and production failure modes
- How you would answer the most likely React interview follow-up
Use this React interview question to rehearse a quick answer, common mistake, follow-up, and production pitfall.
Full interview answer
Core idea
JSX is not something React executes. JSX is syntax that your build tool (Babel or TypeScript) compiles into plain JavaScript function calls that create React elements. React doesn’t require JSX because React only needs the result: a React element tree (plain JS objects) — and you can create those objects without JSX.
Step | What happens | Who does it |
|---|---|---|
1) Parse JSX | JSX is parsed into an AST (like any JS syntax). | Babel / TypeScript compiler |
2) Transform | JSX nodes become function calls (classic or automatic runtime). | Babel plugin / TS JSX transform |
3) Run | Those function calls return React elements (JS objects). | React runtime |
4) Render | React reconciles elements and updates the DOM. | React + ReactDOM |
Two JSX runtimes you’ll see
There are two common outputs for JSX transforms: classic (calls React.createElement) and automatic (calls jsx/jsxs from react/jsx-runtime). Both produce the same kind of React elements.
// Input (JSX)
function App({ user }) {
return (
<main className="page">
<h1>Hello, {user.name}</h1>
<button onClick={() => alert('hi')}>Click</button>
</main>
);
}
// Output (classic runtime - conceptual)
function App({ user }) {
return React.createElement(
'main',
{ className: 'page' },
React.createElement('h1', null, 'Hello, ', user.name),
React.createElement('button', { onClick: () => alert('hi') }, 'Click')
);
}
// Output (automatic runtime - conceptual)
import { jsx, jsxs } from 'react/jsx-runtime';
function App({ user }) {
return jsxs('main', {
className: 'page',
children: [
jsxs('h1', { children: ['Hello, ', user.name] }),
jsx('button', { onClick: () => alert('hi'), children: 'Click' })
]
});
}
What are jsx and jsxs?
jsx and jsxs are the two element factory functions exported by react/jsx-runtime (development builds use jsxDEV from react/jsx-dev-runtime). The compiler emits jsx(type, props, key) when an element has zero or one child and jsxs(type, props, key) when it has several static children, so React can skip the missing-key warning for arrays it knows were written inline. Both return the same React element object as React.createElement; only the call signature differs: key is a separate argument and children live inside props. You never import them yourself; the automatic runtime inserts the import during the build.
Detail | What it means in practice |
|---|---|
Automatic runtime often removes the need to import React just for JSX | You might not see |
JSX becomes props + children | Attributes become a props object; nested content becomes |
JSX is JavaScript expressions | {...} is an expression slot, not “template interpolation” like HTML. |
Lowercase vs Uppercase matters |
|
Why React doesn’t require JSX
React only needs you to produce React elements. JSX is just a nicer way to write those element factory calls. You can skip JSX entirely and write createElement (or jsx) calls yourself — it’s just more verbose.
// React without JSX
import React from 'react';
export function App() {
return React.createElement('h1', null, 'No JSX here');
}
Interview framing
Say: “JSX is syntax sugar compiled by Babel/TS into element-creation calls (classic createElement or automatic jsx/jsxs). React doesn’t require JSX because it only consumes React elements — JSX never reaches React as JSX.”
Practical scenario
You upgrade to React 17+ and remove import React from files using JSX.
Common pitfalls
- Tooling not configured for the new JSX transform.
- Babel/TS settings inconsistent across packages.
- Lint rules still expecting React in scope.
New transform reduces boilerplate but needs config. Test build output and update linters.
Use this as one explanation rep, then continue with the React interview questions cluster or a guided prep path.