What is React hydration?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
Hydration is the step where React takes server-rendered HTML that is already on screen and attaches its own component tree and event listeners to it, turning static markup into a working app — without recreating the DOM.
// server
const html = renderToString(<App />); // HTML the user sees first
// browser
hydrateRoot(document.getElementById('root'), <App />);
// not createRoot — that would throw the HTML away and rebuild it
What React actually does
It renders your components as usual, but instead of creating DOM nodes it walks the existing ones and matches them up. Where its output agrees with the HTML, it keeps the node and only records the fibre and the listeners. Event handling is delegated at the root, so it does not add a listener per element.
That gives you the three-phase load everyone measures: HTML visible (FCP/LCP), JavaScript downloaded and hydration running, then interactive (TTI). Between phase one and three the page looks ready but a click does nothing — the "uncanny valley".
Hydration mismatches
If the client's first render disagrees with the server's HTML, React warns and, in React 18+, falls back to client rendering for that subtree. The usual causes:
- Values that differ per environment:
Date.now(),Math.random(),new Date().toLocaleString(),window.innerWidth. - Reading
localStorageor a cookie during render. - Invalid HTML nesting — a
<div>inside a<p>— because the browser silently restructures it and React then sees a tree it did not produce. - A browser extension injecting nodes.
The fix is to render the same thing on both sides and move the difference into an effect, or mark the element suppressHydrationWarning when the difference is genuinely expected, like a timestamp.
const [now, setNow] = useState(null); // same on both sides
useEffect(() => setNow(Date.now()), []); // filled in after hydration
How modern React reduces the cost
Hydration used to be all-or-nothing and blocking. Now:
- Streaming SSR with
<Suspense>lets HTML arrive in chunks. - Selective hydration hydrates boundaries independently, and prioritises whichever one the user just clicked.
- Server Components never hydrate at all — they ship no JavaScript, so only
"use client"subtrees pay the cost.
That last point is the practical takeaway: the way to make hydration fast is to hydrate less of the page.
