Skip to main content
Fragments let you group a list of children without adding extra nodes to the DOM. They’re useful when you need to return multiple elements from a component but don’t want to wrap them in a container element.

Why Use Fragments?

Without fragments, you’d need to wrap multiple elements in a container:
// Without fragments - adds unnecessary div
function Component() {
  return (
    <div>
      <h1>Title</h1>
      <p>Paragraph</p>
    </div>
  );
}
This extra <div> can cause issues with:
  • CSS layouts (flexbox, grid)
  • Table structures
  • List semantics
  • Extra DOM nodes affecting performance

Using Fragments

How Fragments Work

The Fragment component is implemented simply in src/create-element.js:
// From src/create-element.js:77-79
export function Fragment(props) {
  return props.children;
}
It just returns its children directly, without wrapping them. During diffing, Preact handles fragments specially to avoid creating wrapper DOM nodes. Reference: src/create-element.js:77-79

Common Use Cases

function TableRows({ items }) {
  return (
    <>
      {items.map(item => (
        <tr key={item.id}>
          <td>{item.name}</td>
          <td>{item.value}</td>
        </tr>
      ))}
    </>
  );
}

function Table({ items }) {
  return (
    <table>
      <tbody>
        <TableRows items={items} />
      </tbody>
    </table>
  );
}

Keyed Fragments

When rendering a list of fragments, you need to provide a key prop. The short syntax <> doesn’t support keys, so use the explicit Fragment component:
1
Basic Keyed Fragment
2
import { Fragment } from 'preact';

function Blog({ posts }) {
  return (
    <div>
      {posts.map(post => (
        <Fragment key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.excerpt}</p>
          <hr />
        </Fragment>
      ))}
    </div>
  );
}
3
Two-Column Layout
4
import { Fragment } from 'preact';

function TwoColumnList({ items }) {
  return (
    <div className="two-columns">
      {items.map(item => (
        <Fragment key={item.id}>
          <div className="column-a">{item.title}</div>
          <div className="column-b">{item.content}</div>
        </Fragment>
      ))}
    </div>
  );
}
5
Complex Table Structure
6
import { Fragment } from 'preact';

function ExpandableRow({ row, isExpanded }) {
  return (
    <Fragment key={row.id}>
      <tr>
        <td>{row.name}</td>
        <td>{row.value}</td>
      </tr>
      {isExpanded && (
        <tr>
          <td colSpan={2}>
            <div className="details">{row.details}</div>
          </td>
        </tr>
      )}
    </Fragment>
  );
}
When mapping over fragments, always use <Fragment key={...}> instead of <>.

Fragments vs. Arrays

You might wonder: why use fragments when you can return an array?

Practical Examples

function FormField({ label, name, type = 'text', error }) {
  return (
    <>
      <label htmlFor={name}>{label}</label>
      <input id={name} name={name} type={type} />
      {error && <span className="error">{error}</span>}
    </>
  );
}

function Form() {
  return (
    <form>
      <FormField label="Username" name="username" />
      <FormField label="Password" name="password" type="password" />
      <button type="submit">Login</button>
    </form>
  );
}

Best Practices

1
Use the short syntax when possible
2
// Good: Short syntax for simple cases
function Component() {
  return (
    <>
      <Header />
      <Main />
    </>
  );
}

// Only use explicit Fragment when you need keys
import { Fragment } from 'preact';

function Component({ items }) {
  return items.map(item => (
    <Fragment key={item.id}>
      <div>{item.title}</div>
      <div>{item.content}</div>
    </Fragment>
  ));
}
3
Don’t wrap unnecessarily
4
// Bad: Unnecessary wrapper
function Component() {
  return (
    <div>
      <Header />
    </div>
  );
}

// Good: Return directly if single element
function Component() {
  return <Header />;
}

// Good: Use fragment for multiple elements
function Component() {
  return (
    <>
      <Header />
      <Main />
    </>
  );
}
5
Consider semantic HTML
6
Sometimes a wrapper element is better for semantics or styling:
7
// Not always best: Fragment in navigation
function Nav({ items }) {
  return (
    <nav>
      {items.map(item => (
        <>
          <a href={item.href}>{item.label}</a>
          <span> | </span>
        </>
      ))}
    </nav>
  );
}

// Better: Use a list for semantics
function Nav({ items }) {
  return (
    <nav>
      <ul>
        {items.map(item => (
          <li key={item.href}>
            <a href={item.href}>{item.label}</a>
          </li>
        ))}
      </ul>
    </nav>
  );
}
8
Always add keys to mapped fragments
9
import { Fragment } from 'preact';

// Bad: Missing keys
function Component({ items }) {
  return items.map(item => (
    <>
      <h3>{item.title}</h3>
      <p>{item.text}</p>
    </>
  ));
}

// Good: Keyed fragments
function Component({ items }) {
  return items.map(item => (
    <Fragment key={item.id}>
      <h3>{item.title}</h3>
      <p>{item.text}</p>
    </Fragment>
  ));
}

Performance Considerations

Fragments have no performance overhead - they don’t create extra DOM nodes or components. They’re just a syntax feature that tells Preact to render children directly.
// These are functionally equivalent in the DOM:

// With wrapper (creates <div> in DOM)
<div>
  <h1>Title</h1>
  <p>Text</p>
</div>

// With fragment (no wrapper in DOM)
<>
  <h1>Title</h1>
  <p>Text</p>
</>

// Resulting DOM for both:
<h1>Title</h1>
<p>Text</p>

Next Steps

Server-Side Rendering

Render Preact components on the server

TypeScript

Use Preact with TypeScript for type safety

Build docs developers (and LLMs) love