# React 18 SSR from scratch: what this demo repo teaches and what it leaves out

> maxam2017/react-18-ssr is a small TypeScript demo that shows how to build server-side rendering with React 18's streaming and selective hydration, without Next.js. It is a teaching tool, not a production template.

**maxam2017/react-18-ssr** — Build react 18 + SSR from scratch 💪

- Repository: https://github.com/maxam2017/react-18-ssr
- Stars: 99 · Forks: 11
- Language: TypeScript
- License: not declared
- Published: 2026-08-17 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/maxam2017-react-18-ssr

## What this repo actually is

maxam2017/react-18-ssr is a deliberately small demonstration. The README says it was written because the author wanted to build React SSR once with the new React 18 APIs instead of using Next.js. The project is written in TypeScript and uses a Koa server. The core idea is to render React elements on the server, dehydrate them, and then use ReactDOM.hydrate on the client. The README lists three steps: set up a Koa server, use ReactDOMServer with renderToString or renderToPipeableStream, and call hydrate. That is the whole scope. There is no data fetching implementation; the README marks "Fetch data" as WIP. So the repo is a starting point for understanding the mechanics, not a framework or a library you would install.

## The problem it solves and who it is for

The problem is the classic SSR dilemma. A single-page application gives fast client-side navigation but hurts SEO and makes the first paint slow. A multi-page application renders HTML on the server but forces a full page reload on every navigation. React 18's new SSR architecture aims to combine both. The repo is for a developer who already knows React and wants to see how the new APIs fit together without the abstraction of Next.js. The README even frames SSR as a common interview question, which suggests the intended audience is someone studying for interviews or learning React internals. It is not for a team shipping a product. The caveat at the top says so directly: "This code isn't production-ready. Use with caution."

## The new SSR features: streaming and selective hydration

The README points to two features that React 18 unlocks: streaming HTML and selective hydration. It links to the React working group discussion for details, but the repo itself does not explain the mechanisms deeply. Streaming means the server can send HTML in chunks as it becomes ready, rather than waiting for the entire page to render. Selective hydration means the client can hydrate parts of the page as they load, instead of waiting for the whole bundle. The README says the old SSR process was "waterfall-like" and that Suspense changes that. In practice, this repo shows the API entry points: renderToPipeableStream is the new function that enables streaming, and it is required if you want to use React.lazy and Suspense for code splitting. The code splitting section says the most basic way is dynamic import, but React.lazy needs renderToPipeableStream. That is a concrete constraint the repo makes explicit.

## How to get it running: commands and config from the README

The README does not include a full setup guide, but it gives enough to infer the workflow. You need a Node server, and the README specifies Koa. You will install dependencies for React 18, react-dom, react-router-dom, and Koa. The routing section mentions react-router-dom with BrowserRoutes on the client and StaticRoutes on the server, and it links to the React Router SSR guide. For code splitting, you use dynamic import and React.lazy. The README does not list exact commands like npm install or npm run dev. It also does not show a package.json. So to run it, you must clone the repo and inspect the files yourself. The absence of a run guide is a limitation for a beginner, but the repo is small enough that reading the code may be sufficient. The main config keys you will encounter are the ReactDOMServer methods and the hydrate call, both of which are standard React 18 APIs.

## What the repo does not cover: a genuine limitation

The most obvious gap is data fetching. The README lists "Fetch data" as WIP, which means the demo does not show how to load data on the server before sending HTML. In a real SSR app, you often need to fetch data on the server, pass it to the client, and avoid double-fetching. This repo skips that entirely. Another limitation is that the README does not mention error handling during streaming. If a component throws while streaming, what happens to the response? The React working group discussion might cover that, but the repo does not. Also, the code is not production-ready, so performance optimizations like caching, compression, or CDN integration are absent. If you need a complete SSR solution, this repo will leave you with more questions than answers. It is a skeleton, not a meal.

## A real alternative: Next.js and the difference in approach

The README itself names Next.js as the alternative the author used before. Next.js is a full framework that wraps React SSR with file-based routing, static generation, and a data-fetching model. The difference in approach is that Next.js hides the server details. You do not write a Koa server or call renderToPipeableStream yourself; the framework does it for you. Next.js also provides conventions for data fetching, like getServerSideProps or server components, which this repo lacks. The trade-off is that Next.js adds a layer of abstraction and a larger dependency footprint. This repo, by contrast, shows the raw APIs, which is useful for understanding what Next.js does under the hood. If you want to learn, this repo is the better starting point. If you want to ship, Next.js is more practical. The README's caveat reinforces that distinction.

## Maintenance and upgrade cost

The README does not state a license, which is a concern. The repository metadata says "License: (unknown)". That means you cannot legally assume you are free to use the code in your own project without asking the author. For a learning repo, that is less of an issue, but for any real use, you should contact the author or find a licensed alternative. The repo is not archived, but the last push date is unknown, so you cannot tell if it is actively maintained. React 18 APIs are stable, so the code is unlikely to break soon, but the WIP data-fetching section suggests the author may not have finished the project. Upgrade cost is low for learning purposes: you can copy the patterns into your own project. But if you plan to extend the repo, you will have to write the data fetching and error handling yourself, which is the bulk of the work in a real SSR app.

## Conclusion

Adopt this repo if you want a minimal, readable example of React 18's renderToPipeableStream and selective hydration, and if you are comfortable reading code that the author explicitly labels as not production-ready. Do not use it as the base for a real application: the README states it is not production-ready, and the fetch-data feature is marked as work in progress. Before relying on it, verify that the code still runs with your installed React version and that you understand the trade-offs of streaming SSR, especially around error handling and data fetching, which the repo does not cover.

## FAQ

### Does React allow server-side rendering?

Yes, and this repository builds it from scratch. A Koa server renders dehydrated React elements with ReactDOMServer, using renderToString and, new in React 18, renderToPipeableStream, and ReactDOM.hydrate then makes the DOM interactive in the browser.

### How do I run the react-18-ssr example locally?

Run pnpm dev. It starts both watchers: dev:client builds src/index.tsx with Parcel and serves hot reloading on port 4000, and dev:server runs nodemon with ts-node against server.tsx under NODE_ENV=development. Node 18 is the declared engine and pnpm 9.6.0 the package manager.

### What is new about server-side rendering in React 18?

React 18 introduced a new SSR architecture in which the Suspense API removes the waterfall, unlocking streaming HTML and selective hydration. The README points at the React 18 working group discussion on that architecture for the longer explanation.

### Does react-18-ssr handle data fetching and routing?

Routing is set up through react-router-dom using both StaticRoutes for the server render and BrowserRoutes on the client. Data fetching is listed as WIP. Code splitting is demonstrated with dynamic import plus React.Suspense and React.lazy, which requires renderToPipeableStream.

### Is react-18-ssr ready for production use?

The README states that the code is not production-ready and says to use with caution. The last commit on main is 24 July 2024, the repository is not archived, and no releases are published.

## Sources

- [Official README](https://github.com/maxam2017/react-18-ssr#readme)
- [Project repository](https://github.com/maxam2017/react-18-ssr)
- [README](https://github.com/maxam2017/react-18-ssr/blob/main/README.md)
- [Releases](https://github.com/maxam2017/react-18-ssr/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/maxam2017-react-18-ssr
