Lighthouse CI as a performance monitoring layer
Lighthouse CI is a suite of free tools that make it possible to run Lighthouse as part of a continuous integration pipeline. A single Lighthouse report captures a page's performance at one moment in time; Lighthouse CI adds the dimension of history, making it possible to trace how performance has shifted across commits and releases. That history can pinpoint the effect of a specific code change or enforce performance budgets before code is merged. Though performance is the most frequent use case, the same infrastructure also tracks SEO, accessibility, and other categories covered by Lighthouse.
The core of Lighthouse CI is its command line interface, a separate tool from the standard Lighthouse CLI. The CLI provides a set of commands — including autorun, which runs Lighthouse multiple times, selects the median report, and uploads it for storage. Behavior is configured through a lighthouserc.js file in the root of the repository, or by passing additional flags.
In practice, teams typically interact with Lighthouse CI in one of several ways:
- Running it as a step within an existing CI pipeline
- Using a GitHub Action that executes Lighthouse on every pull request and leaves a comment with results
- Tracking performance over time through a dashboard provided by Lighthouse Server
All of these approaches sit on top of the Lighthouse CI CLI.
Alternative approaches include third-party performance monitoring services, which may be preferable if you'd rather outsource server management and test device infrastructure, or if you want built-in alerting (email or Slack, for example) without building those integrations yourself.
Running Lighthouse CI locally first
Before wiring Lighthouse CI into a provider like GitHub Actions, run it locally to verify your lighthouserc.js configuration behaves as expected. Start by installing the CLI:
npm install -g @lhci/cli
Lighthouse CI requires a lighthouserc.js file at the root of your repo. This file contains all Lighthouse CI configuration. The instructions here assume your project uses git. Next, create the file and add an empty configuration as a starting point:
touch lighthouserc.js
module.exports = {
ci: {
collect: {
/* Add configuration here */
},
upload: {
/* Add configuration here */
},
},
};
Lighthouse CI starts a local server each time it runs so that Lighthouse can load your site even with no other server active. The server is shut down automatically when the run completes. You must configure how that server should serve your content via one of two properties in the ci.collect object:
staticDistDir— for static sites, points to the directory containing static files that Lighthouse CI should serve during testing.startServerCommand— for dynamic sites, the command used to start your own server, which Lighthouse CI launches as a subprocess during testing and terminates afterward.
// Static site example
collect: {
staticDistDir: './public',
}
// Dynamic site example
collect: {
startServerCommand: 'npm run start',
}
Next, set the URLs to audit with the url property in ci.collect. The value is an array of one or more URLs. By default, Lighthouse CI runs Lighthouse three times against each URL.
collect: {
// ...
url: ['http://localhost:8080']
}
Configure report storage by adding the target property to ci.upload with a value of 'temporary-public-storage'. Reports uploaded to temporary public storage are kept for seven days and then automatically deleted. This option is the fastest way to get started; other storage targets are documented in the Lighthouse CI configuration reference.
upload: {
target: 'temporary-public-storage',
}
The report location will resemble the following URL pattern:
https://storage.googleapis.com/lighthouse-infrastructure.appspot.com/reports/1580152437799-46441.report.html
Run the CLI with the autorun command to trigger three Lighthouse runs and upload the median report:
lhci autorun
Successful output looks like this:
✅ .lighthouseci/ directory writable
✅ Configuration file found
✅ Chrome installation found
⚠️ GitHub token not set
Healthcheck passed!
Started a web server on port 65324...
Running Lighthouse 3 time(s) on http://localhost:65324/index.html
Run #1...done.
Run #2...done.
Run #3...done.
Done running Lighthouse!
Uploading median LHR of http://localhost:65324/index.html...success!
Open the report at https://storage.googleapis.com/lighthouse-infrastructure.appspot.com/reports/1591720514021-82403.report.html
No GitHub token set, skipping GitHub status check.
Done running autorun.
You can ignore the GitHub token not set message in the console warning — that token is only required for the GitHub Action integration covered later in this guide. Clicking the https://storage.googleapis.com... link in the output opens the median Lighthouse report in a browser.
The autorun defaults are configurable both via CLI flags and through the configuration file. For example, to increase the number of runs per URL to five, set the numberOfRuns property in ci.collect:
module.exports = {
// ...
collect: {
numberOfRuns: 5
},
// ...
},
};
Then re-run autorun:
lhci autorun
Terminal output should confirm five runs were executed:
✅ .lighthouseci/ directory writable
✅ Configuration file found
✅ Chrome installation found
⚠️ GitHub token not set
Healthcheck passed!
Automatically determined ./dist as `staticDistDir`.
Set it explicitly in lighthouserc.json if incorrect.
Started a web server on port 64444...
Running Lighthouse 5 time(s) on http://localhost:64444/index.html
Run #1...done.
Run #2...done.
Run #3...done.
Run #4...done.
Run #5...done.
Done running Lighthouse!
Uploading median LHR of http://localhost:64444/index.html...success!
Open the report at https://storage.googleapis.com/lighthouse-infrastructure.appspot.com/reports/1591716944028-6048.report.html
No GitHub token set, skipping GitHub status check.
Done running autorun.
Further configuration options are described in the official Lighthouse CI configuration documentation.
Integrating Lighthouse CI with your CI provider
Lighthouse CI works with any common CI tool. The "Configure Your CI Provider" section of the Lighthouse CI getting-started guide contains configuration file examples for popular CI systems, showing how to run Lighthouse CI and collect performance measurements during the build.
Collecting measurements is a reasonable starting point, but advanced setups often go further: making the CI process fail when predefined criteria aren't met. The assert property in lighthouserc.js controls this behavior by evaluating assertions against the Lighthouse results.
Assertions support three severity levels:
off: ignore the assertion entirelywarn: print failures to stderr but do not exit with an errorerror: print failures to stderr and exit Lighthouse CI with a non-zero exit code, which fails the build step
The following lighthouserc.js configuration sets assertions on the performance and accessibility category scores:
module.exports = {
ci: {
collect: {
// ...
},
assert: {
assertions: {
'categories:performance': ['warn', {minScore: 1}],
'categories:accessibility': ['error', {minScore: 1}]
}
},
upload: {
// ...
},
},
};
When the assertion fails, console output looks like this:
Full details on available assertion options are in the Lighthouse CI configuration reference.
Run Lighthouse checks from a GitHub Action
A GitHub Action can generate a fresh Lighthouse report on every push to any branch. Combined with a GitHub status check, those results can be displayed directly on each pull request.
Create a directory named
.github/workflowsin the root of your repository. GitHub reads workflow configuration from this directory.mkdir .github mkdir .github/workflowsInside
.github/workflows, create a file calledlighthouse-ci.yaml.touch lighthouse-ci.yamlPopulate
lighthouse-ci.yamlwith the workflow definition:name: Build project and run Lighthouse CI on: [push] jobs: lhci: name: Lighthouse CI runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Use Node.js 10.x uses: actions/setup-node@v1 with: node-version: 10.x - name: npm install run: | npm install - name: run Lighthouse CI run: | npm install -g @lhci/[email protected] lhci autorun --upload.target=temporary-public-storage || echo "LHCI failed!"This defines a workflow with a single job that runs on every push. The job has four steps:
- Check out the repository
- Install and configure Node
- Install the required npm packages
- Run Lighthouse CI and upload results to temporary public storage.
Commit the file and push it to GitHub. The workflow will trigger on the push.
Open the Actions tab of your project to confirm the run. The Build project and Run Lighthouse CI workflow should appear under the latest commit.
To inspect a report, open the Actions tab, click the relevant commit, open the Lighthouse CI workflow step, and expand the output of the run Lighthouse CI step.
Add a GitHub status check
A status check displays a message on every pull request, typically reporting whether tests passed or a build succeeded.
Visit the Lighthouse CI GitHub App page and click Configure.
If you are in multiple GitHub organizations, select the one that owns the repository.
Choose All repositories to enable Lighthouse CI everywhere, or Only select repositories to limit it, then pick the repositories. Click Install & Authorize.
Copy the displayed token; you will add it to your repository secrets in the next step.
Open your repository's Settings page, click Secrets, then Add a new secret.
Set the Name field to
LHCI_GITHUB_APP_TOKENand paste the copied token into Value. Click Add secret.Go back to
lighthouse-ci.yamland reference the new secret in the "run Lighthouse CI" step.
- name: run Lighthouse CI
run: |
npm install -g @lhci/[email protected]
lhci autorun --upload.target=temporary-public-storage || echo "LHCI failed!"
+ env:
+ LHCI_GITHUB_APP_TOKEN: $
The status check is ready. Test it by creating a pull request or pushing a commit to an existing one.
Host the Lighthouse CI server for historical reports
The Lighthouse CI server offers a dashboard for browsing historical Lighthouse reports and works as a private, long-term store for them.
The comparison view shows:
- The two commits being compared.
- How much the Lighthouse score changed between them.
- Only metrics that changed; everything else is hidden.
- Regressions in pink.
- Improvements in blue.
The server is intended for teams comfortable deploying and managing their own infrastructure. Setup instructions, including Heroku and Docker deployment recipes, are available in the Lighthouse CI server documentation.



