Hydration Proof

Search documentation

Find a page or section

Every command, every flag and every exit code.

The hydration-proof CLI has nine commands. test, the default, loads every route of your app in a real browser and reports hydration problems. The others record a baseline, merge CI shards, open a development overlay or a dashboard, write a config, migrate an old one, download browsers and check your setup.

CommandWhat it does
testTest the app's routes for hydration problems (default)
baselineRecord the current findings; "test --new-only" then fails only on new ones
merge-reportsCombine the reports of parallel CI jobs
devBrowse the app with a hydration overlay
uiOpen a local dashboard to run tests and read reports
initCreate hydration-proof.config.ts (and a CI workflow with --ci)
migrateUpdate a config written for an older version
installDownload the browser (Chromium by default)
doctorCheck the environment and configuration

How to run the hydration-proof CLI

hydration-proof <command> [options]

Run hydration-proof <command> --help for the options of a command. Command-line options override the config file. Every example on this page uses npx; the tabs show the pnpm, Yarn and Bun equivalents.

test

Tests your app's routes for hydration problems. By default it builds the app if there is no build output yet, starts it on a free port, discovers the routes and tests each one in Chromium.

npx hydration-proof test
npx hydration-proof test --url http://localhost:3000 --route / --route /pricing
npx hydration-proof test --mode both --probe
npx hydration-proof test --changed --shard 1/3

A few flags need more than the table says:

  • --url tests an app that is already running: nothing is built or started.
  • --route turns route discovery off; only the routes you name are tested. See routes for everything else that picks routes.
  • --mode takes production (the default), development or both, and the short forms prod and dev. both marks issues found in only one mode.
  • --sitemap reads robots.txt and /sitemap.xml. --crawl follows same-origin links to a depth of 2, at most 50 routes.
  • --changed without a ref compares with the pull request's base branch, or main.
  • --reporter defaults to list,json,html.
OptionWhat it does
-c, --config <file>Config file (default: hydration-proof.config.*)
-u, --url <url>Test an app that is already running
-r, --route <path>Test only this route (repeatable)
--grep <regex>Only routes whose path matches
-s, --scenario <name>Only this scenario (repeatable)
--mode <mode>production (default), development, or both
--build / --no-buildAlways rebuild / never build before testing
--browser <name>chromium (default), firefox or webkit
--channel <name>Use an installed browser, e.g. chrome
--no-matrixTest the scenarios without the environment matrix
--probeProve causes by reloading pages with one thing changed
--interactionsType, click and scroll while pages load; check nothing is lost
--navigationCompare client-side navigation with direct loads (Next.js)
--repeat <n>Load every page n times and report flaky findings
--reporter <list>Comma-separated: list,json,html,junit,sarif,github,gitlab
-o, --output <dir>Report directory (default: .hydration-proof/report)
-w, --workers <n>Pages tested in parallel
--timeout <ms>Per-page timeout
--retries <n>Retries for pages that fail to load
--fail-on <level>error (default), warning, info or never
--shard <i/n>Run part i of n (for parallel CI jobs)
--changed [ref]Only routes affected by files changed since ref (default: the pull request base or main)
--new-onlyFail only on findings that are not in the baseline
--update-baselineWrite the baseline from this run's findings
--project <name>Only this monorepo project (repeatable)
--crawlAlso test same-origin links found on pages
--sitemapAlso test routes listed in /sitemap.xml
--no-cacheDiscover routes again instead of using the cache
--watchKeep the app running and test the routes each change affects
--headedShow the browser

baseline

Tests the app and records every finding in the baseline file (ci.baseline, by default .hydration-proof/baseline.json). Afterwards, hydration-proof test --new-only fails only on findings that are not in it.

npx hydration-proof baseline
npx hydration-proof test --new-only

Entries keep the date they were first seen. Add reason and expires (YYYY-MM-DD) to an entry by hand: they are kept when the baseline is written again, and an expired entry fails the run. Baselines and budgets covers adopting hydration-proof on an app with known problems.

Takes the same options as test.

merge-reports

Combines the reports of parallel CI jobs (--shard) into one. Each argument is a report folder or a report.json file, and screenshots are copied next to the merged report.

npx hydration-proof merge-reports shards/1 shards/2 shards/3 --output .hydration-proof/report

With --config, the config's CI policy (failOn, budgets, ignore rules) decides the exit code. See CI for a sharded workflow.

OptionWhat it does
-o, --output <dir>Where the merged reports go (default: .hydration-proof/report)
--reporter <list>Comma-separated reporters (default: list,json,html)
-c, --config <file>Config for the CI policy (failOn, budgets, ignore rules)
--fail-on <level>error (default), warning, info or never

dev

Opens your app in a browser window with a hydration overlay. It starts the development server for you (or uses --url), and every page you open is checked: findings appear in the overlay and in the terminal.

npx hydration-proof dev
npx hydration-proof dev --route /dashboard --mode production

From the overlay you can highlight the element, open the source file in your editor and copy a report. The editor comes from HYDRATION_PROOF_EDITOR, VISUAL or EDITOR, or the first of cursor, code, windsurf, zed, webstorm, idea or subl found on PATH. See the dev overlay.

OptionWhat it does
-c, --config <file>Config file
-u, --url <url>Use an app that is already running
-r, --route <path>Page to open first (default: the first configured route, or /)
-s, --scenario <name>Scenario to browse in (default: the first one)
--mode <mode>development (default) or production
--browser <name>chromium (default), firefox or webkit
--channel <name>Use an installed browser, e.g. chrome

ui

Starts a local dashboard: run tests from the browser, follow their output and read the latest report. It listens on 127.0.0.1 only, and the printed URL contains an access token that every request needs.

npx hydration-proof ui --open
OptionWhat it does
-c, --config <file>Config file
-p, --port <port>Port (default: a free port)
--openOpen the dashboard in the default browser

init

Creates hydration-proof.config.ts for your project and ignores the report folder in git. With --ci github it also writes .github/workflows/hydration.yml; with --ci gitlab, .gitlab/hydration-proof.yml.

npx hydration-proof init
npx hydration-proof init --ci github

The config it writes sets reporters: ['list', 'json']. Without that option, the default is list, json and html. Existing files are only overwritten with --force.

OptionWhat it does
--ci <provider>Also write a CI workflow: github (.github/workflows/hydration.yml) or gitlab (.gitlab/hydration-proof.yml)
--forceOverwrite existing files

migrate

Checks a config written for an older version and lists the options that were renamed or replaced. It reads the config without validating it.

npx hydration-proof migrate
npx hydration-proof migrate --write
2 changes for hydration-proof.config.ts
  server.start → server.command
    The start command is `server.command`.
  normalize.maskText → redact.patterns
    Text masking is now redaction (it applies to every report). Move the patterns to `redact: { patterns: [...] }`.

--write applies the renames that are safe and keeps the old file as <file>.backup. A key is only renamed when it appears exactly once in the file, so a start inside projects or a "[data-start]" selector is never touched. Anything that needs a judgment call is listed as a change to make by hand. The exit code is 0 when the config is current or the changes were reported, and 2 when there is no config file or it has options this version does not know.

OptionWhat it does
-c, --config <file>Config file
--writeChange the file (a copy is kept as <file>.backup)

install

Downloads the browsers hydration-proof drives, using the same Playwright version it runs with. Chromium is the default.

npx hydration-proof install
npx hydration-proof install chromium firefox webkit
npx hydration-proof install --with-deps  # Linux CI: also system dependencies

Browsers go into Playwright's shared cache, so a project that already uses the same Playwright version does not download them again.

OptionWhat it does
--with-depsAlso install system dependencies (Linux CI)

doctor

Checks Node.js, Playwright, the browsers, the config file and framework detection. Run it first when something does not start; the troubleshooting page covers the common failures.

npx hydration-proof doctor

No options.

Exit codes

CodeMeaning
0Every page passed
1The run failed: issues at or above --fail-on, too many warnings, a budget exceeded, or an expired ignore rule
2Invalid configuration or command-line usage
3The app could not be built, started or reached
4The browser is not installed or could not start
70Internal error (please report it)
130Interrupted

dev, ui and test --watch exit with 0 when you stop them with Ctrl+C. These values are stable: see compatibility.

Running it with pnpm, Yarn or Bun

The binary is installed into your project, so each package manager runs the local copy:

npmpnpmYarnBun
npx hydration-proof testpnpm exec hydration-proof testyarn hydration-proof testbunx hydration-proof test