Skip to main content
A special component that allows grouping multiple children without adding extra DOM nodes.

Signature

const Fragment: FunctionComponent<{}>

Type Definition

interface FunctionComponent<P = {}> {
  (props: RenderableProps<P>, context?: any): ComponentChildren;
  displayName?: string;
}

Description

Fragment is a built-in component that renders its children directly without creating a wrapper DOM element. It’s useful when you need to return multiple elements from a component but don’t want to add an extra <div> or other container to the DOM.

Implementation

The Fragment is implemented in src/create-element.js:77 as a simple pass-through function:
export function Fragment(props) {
  return props.children;
}

Usage Examples

Basic Fragment

import { Fragment } from 'preact';

function List() {
  return (
    <Fragment>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </Fragment>
  );
}

// Renders:
// <li>Item 1</li>
// <li>Item 2</li>
// <li>Item 3</li>
// (No wrapper element)

Short Syntax

import { h, Fragment } from 'preact';

function Columns() {
  return (
    <>
      <td>Column 1</td>
      <td>Column 2</td>
      <td>Column 3</td>
    </>
  );
}

// Equivalent to using <Fragment>

Conditional Rendering

import { Fragment } from 'preact';

function UserInfo({ user, showDetails }) {
  return (
    <div>
      <h2>{user.name}</h2>
      {showDetails && (
        <Fragment>
          <p>Email: {user.email}</p>
          <p>Phone: {user.phone}</p>
          <p>Address: {user.address}</p>
        </Fragment>
      )}
    </div>
  );
}

Lists and Keys

import { Fragment } from 'preact';

function Glossary({ items }) {
  return (
    <dl>
      {items.map(item => (
        <Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </Fragment>
      ))}
    </dl>
  );
}

Multiple Return Elements

import { Fragment } from 'preact';

function Layout() {
  return (
    <Fragment>
      <header>
        <h1>My App</h1>
      </header>
      <main>
        <p>Content goes here</p>
      </main>
      <footer>
        <p>Footer content</p>
      </footer>
    </Fragment>
  );
}

With Map

import { Fragment } from 'preact';

function Table({ rows }) {
  return (
    <table>
      <tbody>
        {rows.map((row, i) => (
          <Fragment key={i}>
            <tr>
              <td>{row.label}</td>
              <td>{row.value}</td>
            </tr>
            {row.hasDetail && (
              <tr>
                <td colSpan={2}>{row.detail}</td>
              </tr>
            )}
          </Fragment>
        ))}
      </tbody>
    </table>
  );
}

Nested Fragments

import { Fragment } from 'preact';

function ComplexLayout({ showSidebar, showHeader }) {
  return (
    <Fragment>
      {showHeader && (
        <Fragment>
          <nav>Navigation</nav>
          <header>Header</header>
        </Fragment>
      )}
      <main>Content</main>
      {showSidebar && <aside>Sidebar</aside>}
    </Fragment>
  );
}

JSX Configuration

To use the <> short syntax, configure your JSX transform: TypeScript (tsconfig.json)
{
  "compilerOptions": {
    "jsx": "react",
    "jsxFactory": "h",
    "jsxFragmentFactory": "Fragment"
  }
}
Babel (.babelrc)
{
  "plugins": [
    ["@babel/plugin-transform-react-jsx", {
      "pragma": "h",
      "pragmaFrag": "Fragment"
    }]
  ]
}
Import Configuration
/** @jsx h */
/** @jsxFrag Fragment */
import { h, Fragment } from 'preact';

When to Use Fragments

Good Use Cases

// ✅ Returning multiple elements
function Header() {
  return (
    <>
      <title>Page Title</title>
      <meta name="description" content="Description" />
    </>
  );
}

// ✅ Valid table structures
function Columns() {
  return (
    <>
      <td>A</td>
      <td>B</td>
    </>
  );
}

// ✅ Conditional groups
function Content({ showExtra }) {
  return (
    <div>
      <p>Always visible</p>
      {showExtra && (
        <>
          <p>Extra 1</p>
          <p>Extra 2</p>
        </>
      )}
    </div>
  );
}

When Not Needed

// ❌ Unnecessary wrapper
function App() {
  return (
    <Fragment>
      <div>Only one child</div>
    </Fragment>
  );
}

// ✅ Better - no Fragment needed
function App() {
  return <div>Only one child</div>;
}

Key Prop Support

Fragments support the key prop for lists:
function Items({ items }) {
  return items.map(item => (
    <Fragment key={item.id}>
      <dt>{item.term}</dt>
      <dd>{item.definition}</dd>
    </Fragment>
  ));
}
Note: Fragments do not support other props besides key and children.

Differences from Wrapper Elements

// With Fragment
function WithFragment() {
  return (
    <>
      <span>A</span>
      <span>B</span>
    </>
  );
}
// Renders: <span>A</span><span>B</span>

// With div wrapper
function WithDiv() {
  return (
    <div>
      <span>A</span>
      <span>B</span>
    </div>
  );
}
// Renders: <div><span>A</span><span>B</span></div>

Performance Considerations

  • Fragments have zero overhead - they don’t create DOM nodes
  • No CSS/layout impact from wrapper elements
  • Slightly faster than rendering a wrapper element
  • Ideal for keeping DOM structure clean and semantic
  • h - Create virtual nodes
  • createElement - React-compatible node creation
  • render - Render components to DOM

Build docs developers (and LLMs) love