SyntaxError: JSX expressions must have one parent element
This error means you’re returning multiple adjacent JSX elements from a component without wrapping them in a single parent. React requires every component to return exactly one root element — it’s a fundamental rule of how JSX compiles to JavaScript.
What causes this
Under the hood, JSX compiles to React.createElement() calls. A function can only return one value, so returning two sibling elements is like trying to return two values from a function — it doesn’t work.
// ❌ This compiles to two separate createElement calls — invalid
return (
<h1>Title</h1>
<p>Content</p>
);
You’ll hit this in a few common scenarios:
- Returning multiple elements from a component
- Returning siblings inside a
.map()callback - Conditionally rendering multiple elements side by side
Fix 1: Use a Fragment
Fragments let you group elements without adding an extra DOM node. This is the preferred approach.
// ✅ Short syntax
return (
<>
<h1>Title</h1>
<p>Content</p>
</>
);
// ✅ Explicit syntax (needed when you pass a key)
import { Fragment } from 'react';
return items.map((item) => (
<Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.definition}</dd>
</Fragment>
));
The short syntax <>...</> works in most cases. Use the explicit Fragment import when you need to pass a key prop, like inside .map().
Fix 2: Wrap in a div
If you don’t mind an extra DOM node, a <div> works fine:
return (
<div>
<h1>Title</h1>
<p>Content</p>
</div>
);
This is fine for layout wrappers, but avoid it when the extra node breaks your CSS (e.g., inside a flex or grid container) or when rendering table rows, list items, or definition lists.
Fix 3: Fix conditional returns
A common variant is returning siblings from a ternary or logical expression:
// ❌ Two elements in the ternary branch
return (
{isLoggedIn ? <Nav /> <Profile /> : <Login />}
);
// ✅ Wrap the branch in a Fragment
return (
{isLoggedIn ? (
<>
<Nav />
<Profile />
</>
) : (
<Login />
)}
);
Related resources
How to prevent it
- Use a linter. ESLint with
eslint-plugin-reactcatches this at save time, before you even see the browser error. - Default to Fragments when returning multiple elements. It’s a zero-cost abstraction — Fragments produce no DOM output.
- If you’re using TypeScript, the compiler will also flag this as a syntax error before build time.