Hydration Proof

Search documentation

Find a page or section

Fifteen rules, one for each way the server render and the first browser render can differ.

These are the ESLint rules for React hydration in eslint-plugin-hydration-proof: 15 rules, each for one way the server render and the browser's first render can differ. Every rule is on in all three presets; the presets change only the severity and whether Server Components are checked. Install the plugin to use them.

All ESLint rules for React hydration

RuleWhat it reportsrecommendedstrict
no-date-in-renderDisallow reading the current time while a component rendersErrorError
no-random-in-renderDisallow random values while a component rendersErrorError
no-browser-global-in-renderDisallow reading browser-only globals such as window and document while a component rendersErrorError
no-storage-in-initial-renderDisallow reading localStorage or sessionStorage while a component renders, including state initializersErrorError
no-match-media-in-renderDisallow evaluating media queries with matchMedia while a component rendersErrorError
no-locale-without-explicit-localeRequire an explicit locale for locale-sensitive formatting during renderWarningError
no-timezone-without-explicit-timezoneRequire an explicit timeZone when dates are formatted or split into parts during renderWarningError
no-unstable-idDisallow ids built from random values, the clock or module-level countersErrorError
no-global-render-counterDisallow changing module-level variables while a component rendersErrorError
no-window-render-branchDisallow rendering different output depending on whether the code runs on the server or in the browserErrorError
no-invalid-interactive-nestingDisallow HTML nesting that the browser repairs while parsing, such as <div> in <p> or <a> in <a>ErrorError
audit-suppress-hydration-warningReport suppressHydrationWarning where it has no effect or hides more than intendedErrorError
no-client-only-initial-stateDisallow initial state and refs computed from browser-only valuesWarningError
require-stable-server-snapshotRequire useSyncExternalStore to have a getServerSnapshot that returns the same value on the server and during hydrationErrorError
require-deterministic-list-orderRequire list ordering during render to be the same on the server and in the browserWarningError

Each rule page shows what it reports, why it breaks hydration, code the rule reports and code it accepts, its options and its exact messages.

What each group of rules catches

Time and random values

no-date-in-render reports Date.now(), new Date(), performance.now() and Temporal.Now in render code. no-random-in-render reports Math.random(), crypto.randomUUID(), uuid, nanoid and lodash's random helpers. Both values change between the server render and hydration; see time and random values.

Browser-only values

The server has no window, storage or screen, so anything read from them renders differently on each side:

The matching fix guides are browser-only APIs, storage and media queries.

Locale, time zone and list order

These are warnings in recommended, because the output only differs when the server and the visitor use a different locale or time zone.

Ids and counters

no-unstable-id reports random, time-based or counter ids where useId() belongs. no-global-render-counter reports module-level variables changed during render, which keep counting on the server across requests. See generated ids that differ.

Markup

no-invalid-interactive-nesting reports <div> in <p>, <a> in <a>, <button> in <button> and table rows outside <tbody>: nesting the browser repairs before React hydrates (invalid HTML). audit-suppress-hydration-warning reports suppressHydrationWarning that does nothing or covers too much (suppressed differences). Both also check Server Components: React hydrates the elements a Server Component renders, and the root layout, where <html suppressHydrationWarning> lives, is one.

useSyncExternalStore

require-stable-server-snapshot reports useSyncExternalStore without a getServerSnapshot, and a getServerSnapshot that reads the browser, the clock or random values. It is the rule behind the fix several other rules recommend.

Presets

PresetSeverityServer Components
recommendedDefinite mismatches are errors; locale, time zone, initial state and list order are warnings.Checked (the setting defaults to 'none')
nextSame as recommended.Files under app/ without 'use client' are skipped
strictEvery rule is an error, and every suppressHydrationWarning needs a reason (reportAll: true).Checked unless you add the setting

Set up a preset shows the config for each, and one report per problem explains which rule reports a construct when two could.