> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/GoogleChrome/lighthouse/llms.txt
> Use this file to discover all available pages before exploring further.

# Understanding results

> A guide to the Lighthouse Result (LHR) object structure, score interpretation, and report formats.

Every Lighthouse run produces a **Lighthouse Result object** (LHR). The LHR is the source of truth behind the HTML report — everything you see rendered in the report is derived from it. You interact with it directly when using Lighthouse programmatically, consuming CLI JSON output, or building tooling on top of Lighthouse.

***

## The `RunnerResult` object

When you call `lighthouse()` from Node, the return value wraps the LHR:

```js theme={null}
import lighthouse from 'lighthouse';
import * as chromeLauncher from 'chrome-launcher';

const chrome = await chromeLauncher.launch({chromeFlags: ['--headless']});
const runnerResult = await lighthouse('https://example.com', {port: chrome.port});

// The full LHR as a JS object
const lhr = runnerResult.lhr;

// The formatted report string (HTML by default)
const report = runnerResult.report;

// Check a specific score
console.log('Performance score:', lhr.categories.performance.score * 100);

await chrome.kill();
```

<ResponseField name="lhr" type="LH.Result" required>
  The Lighthouse Result object. Contains all audit results, scores, and metadata.
</ResponseField>

<ResponseField name="report" type="string | string[]" required>
  The formatted report. A string for single-format runs; an array when multiple `--output` formats are requested.
</ResponseField>

<ResponseField name="artifacts" type="object" required>
  Raw gathered artifacts from the page (traces, network logs, DOM snapshots, etc.).
</ResponseField>

***

## Top-level LHR fields

<ResponseField name="lighthouseVersion" type="string" required>
  The version of Lighthouse that generated this result (e.g. `"12.0.0"`).
</ResponseField>

<ResponseField name="fetchTime" type="string" required>
  ISO-8601 timestamp of when the result was generated (e.g. `"2024-01-15T10:30:00.000Z"`).
</ResponseField>

<ResponseField name="requestedUrl" type="string" required>
  The URL that was originally passed to Lighthouse.
</ResponseField>

<ResponseField name="mainDocumentUrl" type="string" required>
  The URL of the main document request during the final navigation.
</ResponseField>

<ResponseField name="finalDisplayedUrl" type="string" required>
  The URL shown in the browser after all redirects and history API changes. Use this as the canonical URL for the run.
</ResponseField>

<ResponseField name="userAgent" type="string" required>
  The Chrome user agent string used during the audit.
</ResponseField>

<ResponseField name="categories" type="object" required>
  Category scores and audit references. See [Categories](#categories).
</ResponseField>

<ResponseField name="audits" type="object" required>
  Individual audit results keyed by audit ID. See [Audits](#audits).
</ResponseField>

<ResponseField name="configSettings" type="object" required>
  The resolved configuration settings used for this run. See [configSettings](#configsettings).
</ResponseField>

<ResponseField name="timing" type="object" required>
  Timing information for the run. See [Timing](#timing).
</ResponseField>

<ResponseField name="categoryGroups" type="object">
  Display groups used to visually cluster audits within a category in the HTML report.
</ResponseField>

<ResponseField name="runtimeError" type="object">
  Present when a fatal error prevented a valid result. Contains `code` and `message` fields. If set, treat the result as unreliable.
</ResponseField>

<ResponseField name="runWarnings" type="string[]">
  Top-level warnings about the run (e.g. throttling was overridden).
</ResponseField>

### Example

```json theme={null}
{
  "lighthouseVersion": "12.0.0",
  "fetchTime": "2024-01-15T10:30:00.000Z",
  "requestedUrl": "https://example.com",
  "mainDocumentUrl": "https://www.example.com/",
  "finalDisplayedUrl": "https://www.example.com/",
  "categories": {},
  "audits": {},
  "configSettings": {},
  "timing": {}
}
```

***

## Categories

The `lhr.categories` object contains one entry per scored category. Each key is the category ID (e.g. `"performance"`).

<ResponseField name="id" type="string" required>
  The category identifier, e.g. `performance`, `accessibility`, `best-practices`, `seo`.
</ResponseField>

<ResponseField name="title" type="string" required>
  The human-readable category name shown in the report.
</ResponseField>

<ResponseField name="description" type="string" required>
  A brief description of what the category measures.
</ResponseField>

<ResponseField name="score" type="number | null" required>
  The weighted average of all audit scores in the category, in the range `0`–`1`. May be `null` for non-scored categories.
</ResponseField>

<ResponseField name="auditRefs" type="object[]" required>
  References to the audits that contribute to this category.

  <Expandable title="auditRef properties">
    <ResponseField name="id" type="string">The audit ID.</ResponseField>
    <ResponseField name="weight" type="number">The audit's weight in the category score.</ResponseField>
    <ResponseField name="group" type="string">Optional display group ID.</ResponseField>
  </Expandable>
</ResponseField>

### Example

```json theme={null}
{
  "performance": {
    "id": "performance",
    "title": "Performance",
    "description": "These encapsulate your web app's performance...",
    "score": 0.87,
    "auditRefs": [
      {"id": "first-contentful-paint", "weight": 10, "group": "metrics"},
      {"id": "interactive", "weight": 10, "group": "metrics"}
    ]
  },
  "seo": {
    "id": "seo",
    "title": "SEO",
    "description": "These checks ensure your page is following basic SEO advice...",
    "score": 0.54,
    "auditRefs": [{"id": "crawlable-anchors", "weight": 1}]
  }
}
```

***

## Audits

The `lhr.audits` object contains every audit result, keyed by the audit ID.

<ResponseField name="id" type="string" required>
  The audit identifier in kebab-case (e.g. `"first-contentful-paint"`).
</ResponseField>

<ResponseField name="title" type="string" required>
  The display name of the audit. May change between pass and fail states. Supports Markdown code spans.
</ResponseField>

<ResponseField name="description" type="string" required>
  Explains why the audit matters, with links to Lighthouse documentation. Supports Markdown links.
</ResponseField>

<ResponseField name="score" type="number | null" required>
  A value in the range `0`–`1`, or `null` when `scoreDisplayMode` is `informative`, `manual`, `notApplicable`, or `error`.
</ResponseField>

<ResponseField name="scoreDisplayMode" type="string" required>
  Controls how the score is rendered. See [Score display modes](#score-display-modes).
</ResponseField>

<ResponseField name="displayValue" type="string">
  Human-readable summary shown alongside the audit result (e.g. `"2.4 s"`, `"5 resources found"`).
</ResponseField>

<ResponseField name="numericValue" type="number">
  The raw numeric value for the audit (e.g. milliseconds for timing metrics).
</ResponseField>

<ResponseField name="explanation" type="string">
  A string explaining why the audit failed.
</ResponseField>

<ResponseField name="warnings" type="string[]">
  Messages about potentially invalid or edge-case conditions.
</ResponseField>

<ResponseField name="details" type="object">
  Structured data used to render the audit's details table in the report. Structure varies by audit type.
</ResponseField>

### Example

```json theme={null}
{
  "is-on-https": {
    "id": "is-on-https",
    "title": "Does not use HTTPS",
    "description": "All sites should be protected with HTTPS... [Learn more](https://...)",
    "score": 0,
    "scoreDisplayMode": "binary",
    "displayValue": "1 insecure request found",
    "details": {
      "type": "table",
      "headings": [{"key": "url", "valueType": "url", "label": "Insecure URL"}],
      "items": [{"url": "http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"}]
    }
  }
}
```

***

## Score interpretation

Audit and category scores are values between `0` and `1`. The report renders them as 0–100.

| Range      | Value  | Color  | Meaning           |
| ---------- | ------ | ------ | ----------------- |
| 0.9 – 1.0  | 90–100 | Green  | Pass              |
| 0.5 – 0.89 | 50–89  | Orange | Needs improvement |
| 0.0 – 0.49 | 0–49   | Red    | Fail              |

```js theme={null}
// Convert a score to the 0-100 display value
const score = lhr.categories.performance.score * 100;

if (score >= 90) console.log('Pass');
else if (score >= 50) console.log('Needs improvement');
else console.log('Fail');
```

<Note>
  Performance scores are highly sensitive to environment. Always run multiple times and average the results before drawing conclusions.
</Note>

***

## Score display modes

The `scoreDisplayMode` field on each audit determines how it is presented.

| Mode            | Score value | Description                                                     |
| --------------- | ----------- | --------------------------------------------------------------- |
| `numeric`       | `0`–`1`     | Scored on a continuous scale. Used by most performance metrics. |
| `binary`        | `0` or `1`  | Pass/fail. Score is exactly 0 or 1.                             |
| `informative`   | `null`      | Not scored. Informational only, shown as a neutral item.        |
| `manual`        | `null`      | Requires human review. Not automatically assessed.              |
| `notApplicable` | `null`      | The audit does not apply to this page. Hidden from the report.  |
| `error`         | `null`      | The audit encountered an error and could not run.               |

***

## `configSettings`

Reflects the configuration that was actually used for the run, after merging flags and config.

```json theme={null}
{
  "output": ["json"],
  "maxWaitForLoad": 45000,
  "throttlingMethod": "devtools",
  "throttling": {
    "rttMs": 150,
    "throughputKbps": 1638.4,
    "requestLatencyMs": 562.5,
    "downloadThroughputKbps": 1474.56,
    "uploadThroughputKbps": 675,
    "cpuSlowdownMultiplier": 4
  },
  "gatherMode": false,
  "disableStorageReset": false,
  "formFactor": "mobile",
  "blockedUrlPatterns": null,
  "onlyAudits": null,
  "onlyCategories": null,
  "skipAudits": null
}
```

***

## `timing`

Contains performance information about the Lighthouse run itself.

| Field   | Type   | Description                                                                          |
| ------- | ------ | ------------------------------------------------------------------------------------ |
| `total` | number | Total time in milliseconds Lighthouse spent loading the page and running all audits. |

```json theme={null}
{
  "total": 32189
}
```

***

## Report formats

Lighthouse can produce three report formats from the same LHR.

| Format | Flag            | Description                                                                               |
| ------ | --------------- | ----------------------------------------------------------------------------------------- |
| HTML   | `--output html` | Self-contained HTML file with all styles and screenshots embedded. The default output.    |
| JSON   | `--output json` | The full LHR serialized as JSON. Suitable for programmatic processing and CI integration. |
| CSV    | `--output csv`  | A flat CSV file with one row per audit. Does not include flow results.                    |

### Accessing reports programmatically

```js theme={null}
import lighthouse, {generateReport} from 'lighthouse';

const runnerResult = await lighthouse('https://example.com', {port: chrome.port});

// The LHR (structured data)
const lhr = runnerResult.lhr;
console.log('Performance:', lhr.categories.performance.score * 100);

// Generate specific formats from the same LHR
const htmlReport = generateReport(lhr, 'html');
const jsonReport = generateReport(lhr, 'json');
const csvReport  = generateReport(lhr, 'csv');
```

<Tip>
  For CI use cases, consume the JSON output programmatically rather than parsing the HTML report. The LHR schema is versioned and more stable.
</Tip>

### Viewing JSON output online

Run Lighthouse with `--output=json` and drag the file onto the [Lighthouse Viewer](https://googlechrome.github.io/lighthouse/viewer/) to render the full HTML report in a browser without saving an HTML file locally. Reports shared from the viewer are stored as secret GitHub Gists under your account.
