Hydration Proof

Search documentation

Find a page or section

Everything the CLI does, from your own script.

Use the hydration-proof Node API when you want to run checks from a script. run() returns a report and exit code without ending your process. That lets you set up data, start a server, or handle the report yourself. The exports below come from hydration-proof.

Run a test with run()

run-from-node.ts
import { run } from "hydration-proof";
 
const { exitCode, report } = await run({
  overrides: { url: "http://localhost:3000", reporters: ["json"] },
  write: (text) => process.stdout.write(text),
});
 
// The report is the same object the JSON reporter writes.
for (const issue of report.issues) {
  if (issue.severity !== "error") continue;
  console.log(
    `${issue.route.pattern} ${issue.code} ${issue.source?.file ?? "(no source)"} — ${issue.cause?.title ?? "unknown cause"}`
  );
}
 
process.exit(exitCode);

run() loads the config from cwd or the path in config. Use overrides to set options such as url, routes, reporters, failOn, probes, or shard for this run. write receives terminal output, and reporters adds custom report writers.

function run(options?: RunOptions): Promise<RunResult>

Runs a test the way hydration-proof test does and resolves with the report and exit code. It never calls process.exit.

OptionTypeDefaultDescription
cwdstringprocess.cwd()Directory the config is looked up from.
configstring—Config file path; found automatically when omitted.
overridesCliOverrides—The same overrides the command line applies, e.g. { url, routes, reporters, failOn }.
write(text: string) => void—Where progress and the terminal report are written.
reportersReporter[]—Extra reporters (in addition to the configured ones).
signalAbortSignal—Abort the run (the app and browser are shut down).
OptionTypeDefaultDescription
report*Report—The full report, the same object report.json holds.
exitCode*ExitCode—The exit code the CLI would use. See ExitCode.
failures*string[]—Human-readable reasons the run failed.
files*string[]—Report files that were written.
notes*string[]—Informational notes printed at the end of the run.
outputDir*string—Where the reports were written.

Pass an AbortSignal to stop a run. hydration-proof shuts down the app and browser when the signal aborts:

run-with-timeout.ts
import { run } from "hydration-proof";
 
// Stop the run, the app and the browser after ten minutes.
await run({ signal: AbortSignal.timeout(10 * 60_000) });

Handle errors with RunError

Page findings go in the report; they do not throw. run() throws RunError when it cannot start or finish the check, for example because the config is invalid or the browser cannot launch. The error includes the CLI exit code:

hydration.ts
import { run, RunError } from "hydration-proof";
 
try {
  const result = await run();
  process.exitCode = result.exitCode;
} catch (error) {
  if (!(error instanceof RunError)) throw error;
  console.error(error.message);
  process.exitCode = error.exitCode;
}
class RunError extends Error { override name: string; readonly exitCode: ExitCode; readonly details: string | undefined; constructor(message: string, exitCode: ExitCode, details?: string); }

Thrown by run() for failures that stop a run before any page is tested, with the exit code the CLI would use.

Exit codes

ExitCode gives a name to each CLI exit code:

NameCodeMeaning
Ok0Every page passed the policy
Failed1Findings, a budget or an expired ignore rule failed the policy
Usage2Invalid configuration or command-line usage
Server3The app could not be built, started or reached
Browser4The browser is missing or failed to launch
Internal70A bug in hydration-proof
Interrupted130Interrupted (Ctrl+C)
const ExitCode: { /** Every page passed the policy. */ readonly Ok: 0; /** Issues, budget or expired ignore rules failed the policy. */ readonly Failed: 1; /** Invalid configuration or command-line usage. */ readonly Usage: 2; /** The app could not be built, started or reached. */ readonly Server: 3; /** The browser is missing or failed to launch. */ readonly Browser: 4; /** A bug in hydration-proof. */ readonly Internal: 70; /** Interrupted (Ctrl+C). */ readonly Interrupted: 130; }

Exit codes. They are stable: 0 ok, 1 failed, 2 usage or config error, 3 server, 4 browser, 70 internal error. An interrupted run exits 130.

Read and merge reports

readReport() loads report.json from a folder or file. mergeReports() combines reports from shards or projects and removes duplicate findings. The CLI's merge-reports command also applies CI policy and writes configured report formats.

merge.ts
import { writeFileSync } from "node:fs";
import { mergeReports, readReport } from "hydration-proof";
 
const report = mergeReports(
  ["shards/shard-1", "shards/shard-2"].map((dir) => readReport(dir))
);
 
writeFileSync("merged-report.json", JSON.stringify(report, null, 2));
console.log(`${report.summary.failed} pages failed`);
function mergeReports(inputs: readonly MergeInput[]): Report

Combines the reports of sharded or per-project runs into one, removing duplicates. The CLI's merge-reports command wraps it.

function readReport(path: string): MergeInput

Read report.json from a folder or a file path.

Configs, plugins and adapters

Use defineConfig(), definePlugin(), and defineAdapter() for type checking and editor completion. ADAPTERS lists the built-in adapters in detection order. See plugins and adapters for examples.

function defineConfig(config: HydrationProofConfig): HydrationProofConfig

Identity helper that gives hydration-proof.config.ts type checking and completion.

function definePlugin(plugin: HydrationProofPlugin): HydrationProofPlugin

Identity helper with type checking for plugins.

function defineAdapter(definition: AdapterDefinition): Adapter

Create an adapter for a framework hydration-proof does not know.

ISSUES lists the issue codes and their metadata. docsUrl() gives you a documentation link for a code:

list-codes.ts
import { docsUrl, ISSUES } from "hydration-proof";
 
for (const [code, issue] of ISSUES) {
  console.log(`${code} ${issue.severity} ${issue.title} ${docsUrl(code)}`);
}
const ISSUES: ReadonlyMap<IssueCode, IssueDefinition>

Every issue code with its name, title, default severity and description. The issue code reference is generated from it.

function docsUrl(code: IssueCode): string

The documentation URL for an issue code, e.g. https://hydration.jscrate.dev/docs/issues/hp1001.

Schemas and versions

configJsonSchema() returns the config's JSON Schema, also available at /schema/config.json and in the package at schema/config.json. VERSION is the installed package version. REPORT_SCHEMA_VERSION is the schemaVersion in report.json; its current value is 1.

function configJsonSchema(): JsonSchema

The JSON Schema of the config file, the same one published at /schema/config.json.

const VERSION: string

The installed version of hydration-proof.

const REPORT_SCHEMA_VERSION = 1

The schemaVersion written into report.json. It changes only in a major release.

What is stable in the hydration-proof Node API

The following stability promise applies from version 1.0 onward:

  • Stable: run(), defineConfig, definePlugin, defineAdapter, mergeReports, ISSUES and the types they use; the exit codes; and report.json with schemaVersion: 1, where fields are added but never removed or repurposed.
  • Not stable: anything the package does not export; the HTML report's markup and embedded data; the wording of messages, the set of evidence entries and confidence scores; and which cause a finding is given. Treat a cause as an explanation for a person, not something to assert on.

If your script depends on what fails, set failOn or a budget explicitly; a code's default severity can change. See compatibility.