Run a scan from your application
Use the JavaScript and TypeScript SDK when you want to start scans from your own code. For a one-off scan, the quickstart is the shorter route.
Install the packages
The core package runs the scan. The report package creates the HTML report:
npm install @forkpoint/agent-lighthouse-core @forkpoint/agent-lighthouse-report
Run a scan and save its report
This example runs in Node.js:
import { writeFile } from "node:fs/promises";
import { runScan } from "@forkpoint/agent-lighthouse-core";
import { generateHtmlReport } from "@forkpoint/agent-lighthouse-report";
const report = await runScan("https://example.com");
await writeFile("scan-report.html", generateHtmlReport(report));
if (report.overallScore === null) {
console.log("No overall score. Check the report for coverage limits.");
} else {
console.log(`Overall score: ${report.overallScore}/100`);
}
Open scan-report.html in a browser to review the findings. The example overwrites that file on each run.
Choose the options you need
You can limit categories, supply specific pages, receive progress events, or cancel a scan. The programmatic options list the supported settings.
Treat an unscored result separately from zero. When you compare results, keep the scan options and tool version consistent.
Build your own display
Use buildReportView(report) from the report package if you need its prepared report view. Keep findings, coverage limits, and scoring status visible beside the number.
Call getRegistrySummary() from the core package for the number of audits, categories and tiers in the installed version. Do not copy those numbers into your own text.
The package guide explains the other entry points.
Read reports in browser code
The root entry loads the scanner, which needs Node.js. Browser code that reads a saved report can import the contracts entry instead. It has no dependencies:
import {
getScoreTier,
SCORE_TIER_LABELS,
type ScanReport,
} from "@forkpoint/agent-lighthouse-core/contracts";
function headline(report: ScanReport): string {
if (report.overallScore === null) return "Not scored";
return SCORE_TIER_LABELS[getScoreTier(report.overallScore)];
}
The entry carries the report types (ScanReport, CheckResult and the rest), the values they use (CheckStatus, PageType, ScoreTier, EvidenceKey and others), category IDs and names, and the coverage tags that say why a check did not run. The root entry exports the same values, and both entries return the same objects.
Take each category’s weight from the report, in categories[].weight. That is the weight the scan used. The root entry’s CATEGORY_MASS describes the version you installed, which can differ from the version that wrote an older report.
Declare page purpose in v7
Use a declaration when you know the page’s purpose. Leave it out when you want detection.
const report = await runScan("https://example.com/guide", {
pageType: "article",
pages: [{ url: "https://example.com/products/widget", pageType: "product" }],
});
The supported types are homepage, category, product, article, and general. Invalid types and malformed override URLs fail before the scan starts. A target declaration takes precedence over a matching entry in pages.
Read each check’s optional coverage and advisoryResults. Keep nested advisory findings out of score calculations and audit counts. pagesScanned[].classification explains purpose; pageAttempts preserves failed reads. buildReportView(report).pageScope prepares the same data for a display. Saved older reports keep these fields absent.
The v7 migration notes describe the changed semantics. Package publication remains a separate release step.