React Server Components are a new feature that lets you build apps that span the server and client, combining the interactivity of client-side apps with the performance of server rendering. In this tutorial, you’ll learn what React Server Components are, how they work, and how to use them in a Next.js app. What are React Server Components? are React components that run on the server and stream their output to the client. They can access data directly from the backend, without sending it to the client or bundling it into the JavaScript code. This reduces the network and bundle size, resulting in faster loading and rendering. React Server Components React Server Components have a special file extension: . They can only use modules or other server components as dependencies, and they cannot use any browser APIs or client-side features. They can render other server components, client components, or shared components. .server.js Node.js Client components are regular React components that run on the browser and have a file extension. They can use any browser APIs or client-side features, and they can render other client components or shared components. .client.js Shared components are React components that can run on both the server and the client and have a file extension. They can use any features that are available on both environments, such as hooks, context, or custom components. They can render other shared components. .js React Server Components can pass data to client components using props. The data passed from server to client is serialized and deserialized using a custom format that preserves references and supports streaming. This means that data can be sent incrementally as it becomes available, and circular or repeated data structures can be handled efficiently. How do React Server Components work? React Server Components work by using a special renderer that streams the output of server components to the client as a -like format. The client then parses the stream and renders the corresponding client components using . The server and the client communicate using a protocol that supports streaming, such as . JSON ReactDOM HTTP/2 The rendering process of React Server Components has three phases: The server renders the server components and sends their output to the client as a stream of data. The output includes information about which client components need to be rendered on the browser, along with their props. Server rendering: The client receives the stream of data from the server and renders the client components using . The client also keeps track of which server components have been rendered and which ones are still pending. Client rendering: ReactDOM The client compares the rendered output of the server components with the expected output based on their props. If there is any mismatch, the client requests a re-render of those server components from the server. Reconciliation: The reconciliation phase ensures that the server and the client are always in sync and that any changes in data or props are reflected correctly on both sides. How to use React Server Components in Next.js? is a popular framework for building React apps that supports both static and dynamic rendering. Next.js also supports as an experimental feature since . Next.js React Server Components version 13 To use React Server Components in Next.js, we need to enable them in our file: next.config.js module.exports = { experimental: { appDirectory: true, }, }; This will enable the directory feature, which allows us to create an directory in our project root where we can place our components, components, and components. Next.js will automatically handle the file extensions and the rendering logic for us. app/ app/ server client shared Next, we need to that are for React Server Components: install some dependencies required npm install react@experimental react-dom@experimental npm install @react-server/components @react-server/transport-webpack These packages provide the React Server Components , the , and the for bundling our code. renderer streaming protocol webpack plugin Next, we need to create an file that will be our entry point for our server-side rendering: app/pages/_app.server.js import { pipeToNodeWritable } from "react-dom/server"; import { createFromFetch } from "@react-server/components"; export default function handleRequest(req, res) { const manifest = require("../../.next/server-components-manifest.json"); const url = `${req.protocol}://${req.get("host")}${req.originalUrl}`; const stream = createFromFetch( fetch(url, { headers: req.headers, method: req.method, body: req, }), manifest ); pipeToNodeWritable(stream, res, () => {}); } This file uses the function from to create a stream of data from the server components based on the request URL and the manifest file generated by Next.js. It then uses the function from to send the stream to the response object. createFromFetch @react-server/components pipeToNodeWritable react-dom/server Next, we need to create an file that will be our entry point for our client-side rendering: app/pages/_app.client.js import { hydrateRoot } from "react-dom"; import { createFromFetch } from "@react-server/components"; import App from "./_app"; hydrateRoot( document.getElementById("_next"), <App pageProps={{}} Component={createFromFetch( new Response(document.getElementById("_next_data_").textContent, { headers: { "Content-Type": "application/json" }, }) )} /> ); This file uses the function from to render the client components into the existing DOM tree. It also uses the function from to create a stream of data from the server components based on the script tag that contains the initial data sent by the server. hydrateRoot react-dom createFromFetch @react-server/components Finally, we need to create an file that will be our shared component for wrapping our pages: app/pages/_app.js import React from "react"; export default function App({ Component, pageProps }) { return <Component {...pageProps} />; } This file simply renders the component that corresponds to the current page, along with any props that are passed to it. Now we can create our pages using . React Server Components For example, we can create an file that will be our home page: app/pages/index.server.js import React from "react"; import { useFetch } from "@react-server/components"; import Header from "../components/Header"; // shared component import Footer from "../components/Footer"; // shared component import PostList from "../components/PostList.server"; // server component export default function Home() { const posts = useFetch("/api/posts"); // fetch data from the backend return ( <div> <Header /> {/* render a shared component */} <h1>Welcome to React Server Components</h1> <PostList posts={posts} /> {/* render a server component */} <Footer /> {/* render a shared component */} </div> ); } This file uses the hook from to fetch data from the backend using a relative URL. It then renders a shared component ( ), a server component ( ), and another shared component ( ). The component can render other server components or client components as needed. useFetch @react-server/components <Header /> <PostList /> <Footer /> PostList We can also create an file that will be our dynamic page for displaying a single post: app/pages/[id].server.js import React from "react"; import { useFetch } from "@react-server/components"; import Header from "../components/Header"; // shared component import Footer from "../components/Footer"; // shared component import PostDetails from "../components/PostDetails.server"; // server component export default function Post({ id }) { const post = useFetch(`/api/posts/${id}`); // fetch data from the backend return ( <div> <Header /> {/* render a shared component */} <PostDetails post={post} /> {/* render a server component */} <Footer /> {/* render a shared component */} </div> ); } This file uses the hook from to fetch data from the backend using a dynamic URL based on the page parameter. It then renders a shared component ( ), a server component ( ), and another shared component ( ). The component can render other server components or client components as needed. useFetch @react-server/components <Header /> <PostDetails /> <Footer /> <PostDetails /> Conclusion React Server Components are a new feature that lets you build apps that span the server and client, combining the interactivity of client-side apps with the performance of server rendering. In this tutorial, you learned how to use React Server Components in a Next.js app, how they work, and what are the benefits and limitations of using them. React Server Components are still an experimental feature and may change in the future. However, they offer a promising way of building modern web apps with React. Sources https://nextjs.org/docs/advanced-features/react-18/server-components https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html https://zhuanlan.zhihu.com/p/340816128 https://www.freecodecamp.org/news/what-are-react-server-components/ https://www.plasmic.app/blog/how-react-server-components-work