4 min read
React.Fragment: What It Is and Why We Need It

Understanding React.Fragment: What It Is and Why We Need It

React developers are used to wrapping multiple JSX elements using <Fragment>, <React.Fragment>, or the shorthand syntax <>...</>. But why is Fragment needed in the first place?

Why Do We Need Fragments?

If you try to return multiple sibling elements from a component without wrapping them, like this:

return (
  <span>First element</span>
  <span>Second element</span>
)

You’ll get a syntax error like:

JSX expressions must have one parent element.

or

Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?

This is because JSX must return a single parent element. Under the hood, JSX is just syntactic sugar that gets transformed into plain JavaScript objects using React.createElement.

So the example above would compile to something like this:

{
  type: 'span',
  props: {
    children: "First element"
  }
}

{
  type: 'span',
  props: {
    children: "Second element"
  }
}

React expects to receive a single React element, not two separate ones. And when rendering a component, React internally iterates over the children, expecting a structure that is iterable — like an array or a single object with nested children.

That’s why we need a wrapper like Fragment.

What Does React Do with a Fragment?

When using React.Fragment, the compiled output looks more like this:

{
  type: React.Fragment,
  props: {
    children: [
      {
        type: 'span',
        props: { children: 'First element' }
      },
      {
        type: 'span',
        props: { children: 'Second element' }
      }
    ]
  }
}

Fragment allows us to group multiple elements without adding an extra DOM node — like a div or a span.

But… What Is Fragment?

React.Fragment is a special kind of component — it’s a React exotic component that accepts children (and optionally a key).

Here’s the type definition:

(alias) const Fragment: ExoticComponent<{ children?: ReactNode }>

An ExoticComponent is a type of component that React treats in a special way:

interface ExoticComponent<P = {}> {
  (props: P): ReactNode;
  readonly $$typeof: symbol;
}

Notice the $$typeof property — this is an internal marker React uses to identify React elements. It’s essentially what tells React, “Hey, I’m a valid React element,” especially useful when multiple versions of React are present or in debugging scenarios.

The Anatomy of a React Element

When you create a React element, say:

const element = React.createElement("span", null, "Hello World");

You get an object like this:

{
  $$typeof: Symbol(react.element),
  type: "span",
  key: null,
  ref: null,
  props: {
    children: "Hello World"
  }
}

Here:

  • type determines what kind of node it is (e.g., "div", "span", or a custom component).
  • $$typeof helps React recognize this as an element it should process.

For a Fragment, you can do something like:

const fragment = React.createElement(React.Fragment, null, [element, element]);

And the output will look like:

{
  $$typeof: Symbol(react.element),
  type: Symbol(react.fragment),
  key: null,
  ref: null,
  props: {
    children: [
      {
        $$typeof: Symbol(react.element),
        type: "span",
        props: { children: "Hello World" },
        key: null,
        ref: null,
      },
      {
        $$typeof: Symbol(react.element),
        type: "span",
        props: { children: "Hello World" },
        key: null,
        ref: null,
      }
    ]
  }
}

So even though Fragment is not rendered in the DOM, React still treats it as a full-fledged React element with the $$typeof: Symbol(react.element), and its own type: Symbol(react.fragment).


Fragments are a simple but powerful feature in React. They solve the fundamental limitation of JSX requiring a single parent element, without bloating your DOM with unnecessary wrapper nodes.

Use them when:

  • You need to return multiple elements from a component.
  • You want to avoid unnecessary <div> wrappers (hello, clean DOM).
  • You care about minimal DOM structure for styling, accessibility, or performance.

Next time you see <>...</>, remember - there’s some elegant React machinery under the hood making that possible.