Frontend Development 7 min read

How to Upgrade Your Server‑Side Rendering to React 18: New APIs & Best Practices

This guide explains how to migrate a React server‑side rendering setup to React 18 by installing the latest version, replacing renderToString with pipeToNodeWritable, and adopting the new API surface while handling Suspense and streaming nuances.

KooFE Frontend Team
KooFE Frontend Team
KooFE Frontend Team
How to Upgrade Your Server‑Side Rendering to React 18: New APIs & Best Practices

本文源于翻译 Upgrading to React 18 on the server

Overview

Steps to upgrade the server to React 18:

Install the latest React 18 version.

Replace

renderToString

with

pipeToNodeWritable

to unlock new features.

React 18 improves the SSR architecture for better performance, making these changes very useful.

API Changes

Historically, React did not support Suspense on the server. React 18 changes this, offering different APIs for varying levels of Suspense support:

renderToString

: works with limited Suspense support.

renderToNodeStream

: not recommended; fully supports Suspense but not streaming.

pipeToNodeWritable

: recommended ; fully supports both Suspense and streaming.

Existing API

renderToString(React.Node): string

This API can still be used, but it lacks the new capabilities, so we recommend switching to

pipeToNodeWritable

. Since it is not deprecated,

renderToString

can still be used.

In React 18,

renderToString

only offers very limited support for

<Suspense>

. Previously, using

<Suspense>

would throw an error. Starting with React 18, Suspense boundaries are marked as “client‑rendered” and immediately render the HTML inside the fallback. After the client loads JavaScript, the content is re‑rendered. Using a top‑level

<Suspense>

that suspends during rendering can cause the server‑rendered app to exit.

This change does not affect existing applications because Suspense never worked on the server before. However, conditionally rendering

<Suspense>

on the client may cause mismatched content to be removed from the DOM, which React does not support.

Note: This behavior is not very useful, but it is the best we can do because

renderToString

is synchronous and cannot “await” anything. That is why we recommend using the new

pipeToNodeWritable

.

Deprecated API

renderToNodeStream(React.Node): Readable

In React 18, using

renderToNodeStream

is fully discouraged and will emit warnings. It was the first streaming API but its functionality is limited (it cannot wait for data). It buffers the entire content until the stream ends, so it no longer performs true streaming, making its use confusing.

We are replacing it with

pipeToNodeWritable

.

Recommended API

pipeToNodeWritable(React.Node, Writable, Options): Controls

This is the API we recommend moving forward; it supports all new features:

Fully built‑in support (integrated data fetching).

Use

lazy

for code‑splitting without flash‑of‑content issues.

Delayed content in the HTML stream appears later.

In the latest Alpha version, you can use it like this:

<code>import { pipeToNodeWritable } from 'react-dom/server';
</code>

This API is not yet integrated with data fetching. Common Suspense mechanisms work, but we have no guidance yet on pre‑populating client caches from server data.

Open questions remain, such as handling the

&lt;title&gt;

tag because the stream may start before an “ideal” title is available. Developers are encouraged to experiment with solutions.

Other APIs

There are a few related APIs for generating static markup:

renderToStaticMarkup

: still usable (limited Suspense support).

renderToStaticNodeStream

: not recommended (full Suspense support, no streaming).

These have not yet received the new recommended API equivalents for

pipeToNodeWritable

.

Frontend DevelopmentReactserver-side renderingReact 18API Migration
KooFE Frontend Team
Written by

KooFE Frontend Team

Follow the latest frontend updates

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.