Skip to main content
GoodFirstPicks
DashboardIssuesReposLeaderboard

GoodFirstPicks by Leaveitblank © 2026

CreatorRequest a RepoPrivacy PolicyTerms of Service
Bug: renderToPipeableStream doesn't initiate streaming if the first node is a Fragment until the promise in Suspense resolves | GoodFirstPicks

Bug: renderToPipeableStream doesn't initiate streaming if the first node is a Fragment until the promise in Suspense resolves

facebook/react 6 comments 1mo ago
View on GitHub
mediumopenScope: somewhat clearSkill match: maybeReactJavaScriptTypeScript

Why this is a good first issue

Behavioral inconsistency in streaming logic based on root node type.

AI Summary

The issue describes a behavioral inconsistency in `renderToPipeableStream` where streaming starts immediately with a `div` root node but waits for Suspense resolution with a `Fragment` root node. The fix requires understanding React's streaming logic and ensuring consistent behavior regardless of root node type. The scope is somewhat clear but involves core streaming functionality.

Issue Description

renderToPipeableStream behaves differently if the first element is a div or a Fragment. With a div it behaves well, it starts streamming just ahead, without waiting for the promise in Suspense to fullfill. With a Fragment it doesn't behaves well, it waits for the promise in Suspense to resolve to start streamming.

React version: 19.1.0

Steps To Reproduce

  1. Execute the code shown below with node, first do renderToStream("div"), and then do renderToStream(React.Fragment)
  2. You will see the difference in behaviour. First case is good, second not.

Link to code example:

const { renderToPipeableStream } = require("react-dom/server");
const React = require("react");

function renderToStream(Component) {
  const stream = renderToPipeableStream(
    React.createElement(
      Component,
      null,
      React.createElement(
        React.Suspense,
        null,
        new Promise((resolve) => setTimeout(resolve, 4000))
      )
    ),
    {
      onShellReady() {
        stream.pipe(process.stdout);
      },
    }
  );
}

renderToStream("div"); // OK
renderToStream(React.Fragment); // NOT OK

The current behavior

The current behavior is WRONG with React.Fragment. Enforces users to use an unnecessary parent div if they don't want to get stuck with a blank screen.

The expected behavior

The expected behavior is there is no difference in behaviour with React.Fragment and div. React.Fragment should start streamming immediately, as div does, and not wait for the promise in Suspense to resolve.

GitHub Labels

Status: Unconfirmed

Want to work on this?

Claim this issue to let others know you're working on it. You'll earn 10 points when you complete it!

Risk Flags

  • behavioral inconsistency
  • streaming logic
Loading labels...

Details

Points10 pts
Difficultymedium
Scopesomewhat clear
Skill Matchmaybe
Test Focusedno