View all services
Talk to QA Advisor
Browse the Knowledge Hub211 resources
/Tools Library/Lighthouse
Tools Library · Review and guide

Lighthouse review: what it is, tutorial and setup

Lighthouse is Google’s open-source auditing tool for web pages. It loads a page in Chrome, records a trace and other data, and scores performance, accessibility, best practices and SEO, with a newer agentic browsing category in development. It runs in Chrome DevTools, as a CLI and as a Node module, powers PageSpeed Insights, and Lighthouse CI asserts on its results in pipelines.

QAble has evaluated this tool and works alongside it. The factual sections are complete; our view is bounded to what we have actually seen rather than a long-term verdict.

last reviewed
13 October 2026
version covered
Lighthouse 13
licence
Open source

Reviewed by Viral Patel

Co-Founder, QAbleLast reviewed 13 October 2026

At a glance

Lighthouse at a glance

Official site
Vendor
Google
Category
Accessibility testing, Performance testing, Monitoring
Licence
Open source (Apache 2.0)
Platforms
Chrome, Node.js, CLI
Integrates with
Chrome DevTools, PageSpeed Insights, GitHub Actions
First released
2016
Version reviewed
Lighthouse 13

Verdict

Our verdict on Lighthouse

Strengths

  • Already in Chrome DevTools, so anyone can audit a page in a minute without installing anything
  • One report covers performance, accessibility, best practices and SEO, with specific fixes for each finding
  • Simulated throttling makes runs fast and fairly repeatable on ordinary hardware
  • User flows audit interactions and states after load, not just the initial navigation
  • Free under Apache 2.0, with Lighthouse CI for assertions and history in pipelines

Weaknesses

  • Lab scores vary between runs and machines, so single results mislead
  • A simulated device is not your users; field data can disagree sharply with the score
  • Lighthouse 13 removed or renamed many audit IDs that older scripts and budgets use
  • The current Lighthouse CI release bundles Lighthouse 12, not 13

Our take

Lighthouse is the easiest way into front-end quality measurement, and running it in CI through Lighthouse CI, with assertions and stored history per build, is the part teams under-use. Treat its performance score with care: it is a lab measurement of one load on a simulated mid-range mobile device and connection, so it indicates rather than reflects what users experience, and field data such as the Chrome UX Report is the authority on real-user Core Web Vitals. QAble has evaluated Lighthouse rather than maintained a long-running pipeline on it, so this is a bounded take. Two current details matter: Lighthouse 13 replaced many performance audits with insights, breaking scripts keyed on old audit IDs, and the current Lighthouse CI release still bundles Lighthouse 12.

We have evaluated this tool rather than maintained a long-running suite on it, so this is a bounded view rather than a long-term verdict. The rest of this page is factual.

How it works

What is Lighthouse and how does it work?

Gatherers collect, audits judge, categories score

Lighthouse drives Chrome through Puppeteer and the Chrome DevTools Protocol. Gatherers collect artifacts while the page loads: a performance trace, a log of protocol events including every network request, and page data such as the accessibility tree. Audits then evaluate those artifacts, each producing a score, and categories weight selected audits into the scores shown at the top of the report. Everything is assembled into the Lighthouse Result object, the JSON from which the HTML report is rendered. Because audits work from recorded artifacts, the same run can be re-scored and inspected later, and custom audits can be added through configuration.

A simulated mobile device by default

Unless told otherwise, Lighthouse emulates a mobile device and applies simulated throttling. It loads the page unthrottled, then models how the load would have unfolded on a slow 4G connection, defined as 150 ms latency with 1.6 Mbps down and 750 Kbps up. The Lighthouse docs describe this as fast and deterministic but subject to edge cases, and recommend packet-level throttling for deep investigation. It is also why the original trace in DevTools does not match the reported metrics, and why a desktop run, with the desktop preset, produces very different numbers from the default mobile run.

The performance score is weighted metrics

The performance score is a weighted average of metric scores only: Total Blocking Time 30%, Largest Contentful Paint 25%, Cumulative Layout Shift 25%, First Contentful Paint 10% and Speed Index 10%. Interaction to Next Paint appears with zero weight, since a page load contains no real interaction. Each metric’s raw value is mapped to a score using curves derived from real-world HTTP Archive data, and 90 or above is rated good. Insights and diagnostics suggest improvements but do not count towards the score, which is why fixing a flagged insight sometimes leaves the number unchanged.

Navigation, timespan and snapshot modes

Since version 10, Lighthouse can audit more than a cold page load. Navigation mode is the classic run, and the only one that produces a performance score. Timespan mode records an arbitrary period with interactions, measuring layout shifts and blocking time across, for example, a single-page application transition, but gives no overall score. Snapshot mode audits the page as it stands, so accessibility and best practices can be checked in an open menu or a multi-step form. A user flow strings these together through the Node API with Puppeteer, producing one report for a whole journey.

Categories have changed with recent majors

The default categories are now performance, accessibility, best practices, SEO and, since 13.3 in May 2026, agentic browsing, which checks things such as llms.txt and WebMCP integration and is described in the code as still under development. The progressive web app category was removed in Lighthouse 12. The accessibility category runs a subset of axe-core rules, with the current release depending on axe-core 4.13 or a later 4.x, and weights them into a score. Lighthouse 13, released in October 2025, removed many performance audits in favour of insights shared with the DevTools Performance panel, and requires Node.js 22.19 or later.

Strengths

What it does well

Available everywhere Chrome is

The same engine runs in the DevTools Lighthouse panel, the CLI, the Node module and PageSpeed Insights. A developer can reproduce in the browser exactly what a pipeline measured, and a non-technical stakeholder can run an audit without any setup, which makes Lighthouse a common language between QA, developers and product owners.

Insights that point at causes

Performance findings are now insights shared with the DevTools Performance panel: render-blocking requests, LCP breakdown, layout shift culprits, image delivery, font display, duplicated JavaScript, cache policy and more. Each names the resources or elements involved and an estimated saving, so a finding reads as a task rather than a symptom.

Audits of journeys, not just landing pages

User flows audit a login, a checkout or a single-page transition by combining navigation, timespan and snapshot steps in one script, driven by Puppeteer. Teams can measure layout shift during interaction and check accessibility of states that only exist mid-journey, which a URL-only audit cannot reach.

Assertions and history with Lighthouse CI

Lighthouse CI runs Lighthouse several times per URL, three by default, asserts on categories, audits or metric values with ESLint-style error or warn levels, and uploads results to temporary public storage or a self-hosted LHCI server that keeps history and diffs between builds. It can report status checks to GitHub through a GitHub App or token.

Structured results for your own tooling

Every run can emit JSON, the Lighthouse Result object, alongside or instead of HTML. Scores, metric values and individual audit details are all addressable, so teams can feed dashboards, compare builds, or fail a job on a single metric with a few lines of Node, without depending on any hosted service.

Checks for AI agents

The agentic browsing category, added to the default config in 13.3, checks whether a site is usable by AI agents: an llms.txt file, agent resource discovery, an accessibility tree agents can use, and WebMCP tool registration and schema validity. It is explicitly under development, so treat it as early guidance rather than a pass mark.

Pricing

Lighthouse pricing and licensing

Lighthouse is free and open source under the Apache 2.0 licence, maintained by Google’s Chrome team. There are no paid tiers. PageSpeed Insights, which runs Lighthouse on Google’s infrastructure and adds field data, is also free. Lighthouse CI is free and open source, with an optional self-hosted server. The real costs are CI time for repeated runs, a stable machine if you want comparable numbers, and the engineering effort of acting on findings.

  • Licence: Apache 2.0 for Lighthouse and for Lighthouse CI.
  • No tiers: every category, mode, preset and output format is in the open-source package, the DevTools panel and PageSpeed Insights.
  • Lighthouse CI storage: temporary public storage is free but public to anyone with the link; a self-hosted LHCI server keeps reports private and needs hosting and a database.
  • Infrastructure: shared CI runners add variance, so serious performance tracking often needs a dedicated machine or more runs per URL, which costs runner minutes.
  • Hidden cost: maintenance of scripts, budgets and dashboards keyed on audit IDs, which change at major versions such as 13.

Checked against the vendor’s own pages on 13 October 2026. Pricing changes; confirm on the official site before buying.

Getting started

Lighthouse tutorial: getting started

Setup, step by step

  1. For a first look, open Chrome DevTools, choose the Lighthouse panel and analyse the page load in an incognito window.
  2. For scripted runs, install Node.js 22.19 or later and the lighthouse package.
  3. Run the CLI against a URL with JSON and HTML output and open the HTML report.
  4. Run it three to five times and compare, to see how much the score moves on your machine.
  5. Move to the Node module or Lighthouse CI once you know what you want to track.

Install

npm install -g lighthouse
# Node.js 22.19 or later
lighthouse https://example.com --output=json --output=html --output-path=./reports/home --view

A first example

// audit.mjs: run with node audit.mjs (lighthouse and chrome-launcher installed)
import fs from 'node:fs'
import lighthouse from 'lighthouse'
import * as chromeLauncher from 'chrome-launcher'

const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] })
const options = {
  logLevel: 'error',
  output: 'html',
  onlyCategories: ['performance', 'accessibility'],
  port: chrome.port, // the Node API connects to an already running Chrome
}

const result = await lighthouse('https://example.com', options)
fs.writeFileSync('report.html', result.report)

// lhr is the Lighthouse Result object: scores are 0 to 1
const { performance, accessibility } = result.lhr.categories
console.log('Performance', Math.round(performance.score * 100))
console.log('Accessibility', Math.round(accessibility.score * 100))
console.log('LCP ms', result.lhr.audits['largest-contentful-paint'].numericValue)

chrome.kill()

What trips people up first

The score changes every time you run it. That is expected: the Lighthouse documentation lists page nondeterminism such as ads and A/B tests, network and server variability, other processes competing for CPU, browser extensions and antivirus software as sources of variance. Run from the CLI or an incognito window so extensions do not interfere, run three to five times, and compare medians rather than single values. In CI, keep the machine type fixed and assert with the median-run aggregation method. Treat a change of a few points as noise unless it persists across runs.

In practice

Using Lighthouse in practice

Lighthouse CI in GitHub Actions

Lighthouse CI’s autorun command builds on sensible defaults: it finds a static build directory or starts your server, runs Lighthouse three times per URL, applies assertions and uploads results. The official guide installs the CLI globally in the workflow. Start with collection and upload only, then add assertions once the team understands its baseline. Note that temporary public storage makes reports reachable by anyone with the link; use a self-hosted LHCI server or uploads as build artifacts for anything confidential. Remember also that @lhci/cli 0.15.1, the current release, bundles Lighthouse 12.6.1, so CI results can differ from DevTools running Lighthouse 13.

# .github/workflows/lighthouse.yml
name: lighthouse
on: [pull_request]
jobs:
  lhci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          # LHCI status checks need the pull request head commit
          ref: ${{ github.event.pull_request.head.sha }}
      - uses: actions/setup-node@v7
        with:
          node-version: 24
          cache: npm
      - run: npm ci
      - run: npm run build
      # Reads lighthouserc.js; flags for child commands need the = syntax
      - run: |
          npm install -g @lhci/[email protected]
          lhci autorun
        env:
          LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}

Assertions that do not flap

Assertions fail builds, so they must survive normal variance. Raise numberOfRuns to five for performance-sensitive pages and use the median-run aggregation, which picks the most representative run, rather than the default optimistic method, which takes the best value. Assert on metric values with maxNumericValue for the two or three metrics you actually care about, rather than on the whole performance score. Accessibility can be asserted strictly because it does not vary between runs. Begin with warn, watch a few weeks of results, then promote to error.

// lighthouserc.js
module.exports = {
  ci: {
    collect: {
      startServerCommand: 'npm run start',
      url: ['http://localhost:3000/', 'http://localhost:3000/product/42'],
      numberOfRuns: 5,
    },
    assert: {
      assertions: {
        // Not affected by run-to-run variance: hold it high
        'categories:accessibility': ['error', { minScore: 0.95 }],
        // Metric budgets on the most representative run
        'largest-contentful-paint': ['warn', { maxNumericValue: 2500, aggregationMethod: 'median-run' }],
        'total-blocking-time': ['warn', { maxNumericValue: 300, aggregationMethod: 'median-run' }],
        'cumulative-layout-shift': ['error', { maxNumericValue: 0.1, aggregationMethod: 'median-run' }],
      },
    },
    upload: { target: 'temporary-public-storage' },
  },
}

Auditing logged-in journeys with user flows

Most important pages sit behind a login, and the cold-load audit of a public URL misses them. User flows solve this with the Node API: Puppeteer logs in, then the flow records a navigation to the dashboard, a timespan around an interaction such as filtering a list, and a snapshot of an open dialog. The result is one report covering each step. Keep flows short and deterministic, since every step inherits the variance of a lab run, and use them for regression tracking of specific journeys rather than as a substitute for field data.

// flow.mjs
import fs from 'node:fs'
import puppeteer from 'puppeteer'
import { startFlow } from 'lighthouse'

const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('https://app.example.com/login')
await page.type('#email', '[email protected]')
await page.type('#password', process.env.QA_PASSWORD)
await page.click('#sign-in')
await page.waitForSelector('#dashboard')

const flow = await startFlow(page)
await flow.navigate('https://app.example.com/orders') // scored page load

await flow.startTimespan() // layout shift and blocking time during use
await page.click('#filter-open')
await page.waitForSelector('.order-row')
await flow.endTimespan()

await flow.snapshot() // accessibility of the current state

await browser.close()
fs.writeFileSync('flow-report.html', await flow.generateReport())

Reading lab scores against field data

A lab run answers whether this build, on this simulated device, regressed. It does not answer how fast the site is for users. PageSpeed Insights shows both for public URLs: Lighthouse lab data, and Chrome UX Report field data collected from real Chrome users over the previous 28 days for First Contentful Paint, Largest Contentful Paint, Interaction to Next Paint and Cumulative Layout Shift. When they disagree, field data is the truth about users, and the lab is the tool for finding and checking fixes. Interaction to Next Paint in particular is a field metric; a page load contains no real interaction, which is why its lab weight is zero.

Keeping scripts and budgets current

Anything that reads Lighthouse JSON is coupled to audit IDs, and majors change them. Lighthouse 13 removed audits that insights replaced, for example layout-shifts became cls-culprits-insight and dom-size became dom-size-insight, while redirects, server-response-time and uses-text-compression folded into document-latency-insight. Some audits went with no replacement, including first-meaningful-paint, font-size, offscreen-images, uses-rel-preload and third-party-facades. Search dashboards, assertion files and budgets for these IDs before upgrading, pin the Lighthouse version in CI so upgrades are deliberate, and keep Node.js at 22.19 or later. Performance scoring itself did not change in 13, so score trends remain comparable.

Pitfalls

Common pitfalls

Treating one run as the answer

Why it happens: Scores move between runs because of page nondeterminism, network and server variance, and competition for CPU on the machine running the audit.

The fix: Run three to five times and use the median, keep the CI machine type fixed, and compare trends across builds rather than single numbers.

Reporting the lab score as user experience

Why it happens: The default run simulates one mid-range mobile device on a slow 4G connection. Real users have different devices, networks and caches.

The fix: Report field data from the Chrome UX Report or your own real-user monitoring as the measure of experience, and use Lighthouse to find and verify fixes.

Scripts breaking on Lighthouse 13 audit IDs

Why it happens: Lighthouse 13 removed audits replaced by insights, such as layout-shifts and dom-size, and others with no replacement, such as font-size and uses-rel-preload.

The fix: Map old IDs to their insight equivalents using the Lighthouse 13 release notes, update assertions and dashboards, and pin the Lighthouse version so the next change is planned.

Looking for the PWA category

Why it happens: Lighthouse 12 removed the progressive web app category after Chrome changed its installability criteria. Older tutorials and CI configs still reference it.

The fix: Remove PWA assertions and categories from configs, and use the PWA documentation and DevTools Application panel for installability checks.

Expecting Lighthouse CI to run Lighthouse 13

Why it happens: @lhci/cli 0.15.1, published in June 2025 and still the latest release, depends on Lighthouse 12.6.1, so CI results come from version 12.

The fix: Know which version produced each number, keep assertions to audit IDs that exist in both 12 and 13, and compare CI against CI rather than against DevTools.

Auditing with extensions and a busy machine

Why it happens: Browser extensions inject scripts and antivirus or other processes compete for CPU, which the Lighthouse docs list as high-impact sources of variance.

The fix: Audit from an incognito window or the CLI, close heavy applications, and in CI avoid running audits alongside other jobs on the same runner.

Compared

How Lighthouse compares

ToolMeasuresDataRuns wherePages behind loginCost
LighthousePerformance, accessibility, best practices, SEO, agenticLab, simulated mobile by defaultDevTools, CLI, Node module, CIYes, via Puppeteer and user flowsFree, Apache 2.0
PageSpeed InsightsLighthouse categories plus Core Web VitalsLighthouse lab plus 28-day CrUX field dataGoogle-hosted web page and APIField data needs public, indexable URLsFree
axe-coreAccessibility onlyRule results on the live pageInside your test frameworkYes, any state tests reachFree, MPL 2.0

FAQ

Frequently asked questions

Is Lighthouse free?

Yes. Lighthouse is open source under the Apache 2.0 licence and built into Chrome DevTools, with no paid tier. PageSpeed Insights, which runs Lighthouse on Google’s servers and adds real-user field data, is free, and Lighthouse CI is free and open source too. Costs only appear in what you run around it: CI minutes for repeated runs and hosting if you self-host an LHCI server.

Why does my Lighthouse score change every run?

Because a lab measurement inherits variance from the page, the network, the server and the machine. Ads and A/B tests change what loads, servers respond at different speeds, and other processes or browser extensions compete for CPU. Simulated throttling reduces but does not remove this. Run several times, compare medians, keep CI hardware fixed, and treat small changes as noise unless they persist.

What is the difference between Lighthouse and PageSpeed Insights?

PageSpeed Insights runs Lighthouse on Google’s infrastructure for a public URL and shows its lab results, and alongside them shows field data from the Chrome UX Report, collected from real Chrome users over the previous 28 days. Lighthouse alone gives only lab data, but runs anywhere, including on localhost, staging and pages behind a login, and can be scripted and asserted in CI.

What changed in Lighthouse 13?

Lighthouse 13, released on 10 October 2025, removed performance audits that were replaced by insights shared with the DevTools Performance panel, removed several audits with no replacement such as font-size and uses-rel-preload, and requires Node.js 22.19 or later. Performance scoring did not change. Later 13.x releases added the agentic browsing category; 13.5.0 came out on 17 September 2026.

Where did the PWA category go?

It was removed in Lighthouse 12, released in April 2024, following Chrome’s updated installability criteria. Lighthouse no longer scores progressive web app features, and the project points users to the updated PWA documentation and DevTools for installability checks. Any configuration or assertion that names the PWA category or its audits needs updating.

Can Lighthouse test pages behind a login?

Yes. In DevTools, log in first and run the audit in that tab. From code, use Puppeteer to log in and either hand the page to a user flow with startFlow, or pass the browser’s debugging port to the Lighthouse Node module. Lighthouse CI supports a Puppeteer script for authentication as well. PageSpeed Insights cannot, since it fetches the page from Google’s servers.

Is a high Lighthouse accessibility score enough?

No. The accessibility category runs a subset of axe-core’s automated rules and weights them into a score, so a page can score highly while a critical journey is unusable by keyboard or screen reader. Use the score as a quick indicator, use axe-core directly in tests to gate builds on specific violations, and test key journeys manually with assistive technology.

Alternatives

Lighthouse alternatives worth weighing

axe-core

The accessibility rules engine behind most other tools, embeddable in any automated test suite.

WebPageTest

Detailed front-end performance testing from real locations, devices and connection speeds.

Resources

Where to go next

Ready

Picking the wrong tool costs more than picking late.

QAble advises on toolchain decisions and then implements them, with engineers who have run these tools on real delivery. Start with a free QA audit.

Talk to QA Advisor