What Is Hydration in Web Development?

Hydration is the moment a server-rendered page wakes up. The HTML was there instantly; the buttons did nothing until the JavaScript arrived and claimed them.

What Is Hydration in Web Development? — Troiana insight cover

In short

Hydration is the process by which a JavaScript framework takes HTML that was rendered on the server or at build time and attaches event handlers and state to it in the browser, turning static markup into a working application without re-rendering it. It gives fast first paint and crawlable content while keeping client-side interactivity. Its cost is that the framework must download, parse and run over the whole page before anything responds, which delays interaction on large pages; islands architecture, progressive and selective hydration, and resumability reduce that cost by hydrating only what needs it.

The problem it solves

A purely client-rendered application sends an empty HTML shell and builds the page in the browser, which is slow to show anything and invisible to crawlers that do not run JavaScript. Rendering on the server fixes both: the browser receives complete HTML and can display it immediately.

But server-rendered HTML is inert. A button is just a <button>; nothing is listening to it. The framework in the browser needs to take over, and it can either throw the server's HTML away and rebuild it, which wastes the work and flashes, or adopt it. Hydration is adoption: the framework walks the existing DOM, matches it against what it would have rendered, and attaches the event handlers, state and reactivity to the elements already there.

How it works

The server (or the build step) renders the component tree to an HTML string and sends it, usually with the application's initial data serialised in a script tag. The browser displays the HTML. The JavaScript bundle downloads and runs, reconstructs the component tree in memory, and reconciles it with the DOM node by node. Where they match, it attaches behaviour. Once the whole tree is processed, the page is interactive.

React, Vue with Nuxt, Svelte with SvelteKit, Solid and their peers all do a version of this. In React it is hydrateRoot; in the Next.js world it is what happens after every server-rendered page loads.

The cost

Hydration requires the framework and the component code for the whole page to be downloaded, parsed and executed before the page responds to input. On a large page on a mid-range phone that can be seconds. During that time the page looks complete and does nothing, which users find more confusing than a loading state; the industry name for it is the uncanny valley. A click during the gap may be lost or, worse, replayed unexpectedly once hydration completes.

This is the source of the poor Interaction to Next Paint scores that JavaScript-heavy sites post even when they render on the server: the HTML arrived quickly and the interactivity arrived late. Hydration also duplicates work: the server rendered the tree, and the browser renders it again in memory to match it.

Hydration errors

The framework expects the server's HTML to match what it renders on the client. When they differ, it reports a hydration mismatch: a warning in development and, in React 18 and later, a fallback to client rendering for the affected subtree in production, which costs performance and can flash.

Common causes: rendering something that differs between server and browser, such as the current time, a random value, or window dimensions; content that depends on browser-only state such as local storage or the user's timezone; invalid HTML nesting that browsers correct differently from the server; and third-party scripts or browser extensions modifying the DOM before hydration. The fix is to render the same thing in both places, defer browser-dependent values until after hydration, and validate the HTML.

The alternatives

Partial hydration and islands. Render the whole page as static HTML and hydrate only the interactive components, each as an independent island with its own small bundle. Astro popularised this; the content of a page never needs JavaScript, so it never pays for it. This is the right model for content sites with a few interactive widgets.

Progressive and selective hydration. Hydrate components in priority order, the visible and interactive ones first, and stream the rest; React's streaming server rendering with Suspense does this, so a page can respond in parts before the whole tree is ready.

Resumability. Qwik's approach: serialise not just the HTML but the application's state and event listeners so the browser can resume exactly where the server left off, executing code only when an interaction requires it, with no up-front hydration pass at all.

Server components. React Server Components render parts of the tree on the server with no client-side JavaScript for them at all; only the components marked as client components hydrate. This shrinks the hydration work to the genuinely interactive parts.

No framework for content pages. A static site with small scripts for the few interactive parts has nothing to hydrate. For marketing and content sites, this is often the fastest option and the simplest.

What to take from it

If a site renders on the server and still scores poorly on interactivity, hydration is the likely reason, and the fix is to hydrate less: fewer client components, islands for widgets, streaming for large pages, and static HTML for content that does not need to be interactive. The rendering strategy decides how much hydration a page needs; the framework decides how cheaply it happens. If a product feels loaded but unresponsive on phones, book a call; measuring the hydration cost is a quick profile.

Common questions

What is hydration in React?

The process by which React, in the browser, takes HTML rendered on the server and attaches event handlers and state to the existing elements instead of re-rendering them, using hydrateRoot. The page displays immediately from the server's HTML and becomes interactive once React has downloaded, run and reconciled the component tree against the DOM.

What is a hydration error?

A mismatch between the HTML the server rendered and what the framework renders in the browser, caused by values that differ between the two, such as dates, random numbers or browser-only state, or by invalid HTML nesting. React warns in development and falls back to client rendering for the affected part in production. Render the same thing in both places and defer browser-dependent values until after hydration.

Why is hydration slow?

Because the framework must download, parse and execute the JavaScript for the whole page, then walk the entire DOM to attach behaviour, before anything responds to input. On large pages and mid-range phones that can take seconds, during which the page looks complete but does nothing. Islands, streaming, selective hydration and server components reduce the work.

What is islands architecture?

A pattern in which a page is delivered as static HTML and only the interactive components, the islands, are hydrated, each with its own small JavaScript bundle. Content between the islands never loads JavaScript. Astro is the best-known framework built on it, and it suits content sites with a few interactive widgets.

What is the difference between hydration and resumability?

Hydration re-runs the application in the browser to reconstruct state and attach listeners to server-rendered HTML, which costs time proportional to the page. Resumability, pioneered by Qwik, serialises the state and listeners with the HTML so the browser resumes without an up-front pass, loading code only when an interaction needs it.

Have something worth building right?