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()
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.
| Option | Type | Default | Description |
|---|---|---|---|
| cwd | string | process.cwd() | Directory the config is looked up from. |
| config | string | — | Config file path; found automatically when omitted. |
| overrides | CliOverrides | — | 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. |
| reporters | Reporter[] | — | Extra reporters (in addition to the configured ones). |
| signal | AbortSignal | — | Abort the run (the app and browser are shut down). |
| Option | Type | Default | Description |
|---|---|---|---|
| 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:
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:
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:
| Name | Code | Meaning |
|---|---|---|
Ok | 0 | Every page passed the policy |
Failed | 1 | Findings, a budget or an expired ignore rule failed the policy |
Usage | 2 | Invalid configuration or command-line usage |
Server | 3 | The app could not be built, started or reached |
Browser | 4 | The browser is missing or failed to launch |
Internal | 70 | A bug in hydration-proof |
Interrupted | 130 | Interrupted (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.
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[]): ReportCombines the reports of sharded or per-project runs into one, removing duplicates. The CLI's merge-reports command wraps it.
function readReport(path: string): MergeInputRead 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): HydrationProofConfigIdentity helper that gives hydration-proof.config.ts type checking and completion.
function definePlugin(plugin: HydrationProofPlugin): HydrationProofPluginIdentity helper with type checking for plugins.
function defineAdapter(definition: AdapterDefinition): AdapterCreate an adapter for a framework hydration-proof does not know.
Issue codes and documentation links
ISSUES lists the issue codes and their metadata. docsUrl() gives you a
documentation link for a code:
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): stringThe 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(): JsonSchemaThe JSON Schema of the config file, the same one published at /schema/config.json.
const VERSION: stringThe installed version of hydration-proof.
const REPORT_SCHEMA_VERSION = 1The 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,ISSUESand the types they use; the exit codes; andreport.jsonwithschemaVersion: 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
evidenceentries 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.
Related
- The CLI: the same run from the command line
- Write a plugin: reporters, detectors and route providers
- Adapters for other frameworks
- The report format
- Compatibility and stability