Lighthouse CI Configuration Reference
Lighthouse CI uses configuration files to define how audits are collected, assertions are evaluated, and results are uploaded.
Configuration File Formats
Lighthouse CI supports multiple configuration file formats, checked in priority order:
.lighthouserc.js- JavaScript module (supports dynamic config)lighthouserc.js.lighthouserc.cjs- CommonJS explicitlighthouserc.cjs.lighthouserc.json- JSON formatlighthouserc.json.lighthouserc.yml- YAML formatlighthouserc.yml.lighthouserc.yamllighthouserc.yaml
JavaScript Config
// lighthouserc.js
module.exports = {
ci: {
collect: {
url: ['https://example.com/', 'https://example.com/about'],
numberOfRuns: 3,
},
assert: {
preset: 'lighthouse:recommended',
},
upload: {
target: 'temporary-public-storage',
},
},
}
JSON Config
{
"ci": {
"collect": {
"url": ["https://example.com/"],
"numberOfRuns": 5
},
"assert": {
"preset": "lighthouse:recommended"
}
}
}
Using CLI Flag
Override the default config file location:
lhci autorun --config=custom-config.js
Environment Variables
All configuration options can be set via environment variables using the LHCI_ prefix and double underscores for nesting:
# Equivalent to ci.collect.numberOfRuns
LHCI_COLLECT__NUMBER_OF_RUNS=5
# Equivalent to ci.upload.serverBaseUrl
LHCI_UPLOAD__SERVER_BASE_URL=https://lhci.example.com
# Equivalent to ci.upload.token
LHCI_UPLOAD__TOKEN=your-secret-token
Environment variables override config file values.
Collect Options
The collect configuration controls how Lighthouse audits are run.
Basic Collection
module.exports = {
ci: {
collect: {
// URLs to audit (required)
url: [
'https://example.com/',
'https://example.com/products',
'https://example.com/about',
],
// Number of times to audit each URL (default: 3)
// 5 runs = 2x more stable than 1 run (Google research)
// 3 runs = 37% variance reduction (DebugBear analysis)
numberOfRuns: 5,
// Lighthouse settings object
settings: {
preset: 'desktop',
onlyCategories: ['performance', 'accessibility'],
},
},
},
}
Static Site Collection
For auditing static builds before deployment:
module.exports = {
ci: {
collect: {
// Path to built static files
staticDistDir: './dist',
// URLs to audit (relative to staticDistDir)
url: [
'http://localhost/index.html',
'http://localhost/about/index.html',
],
numberOfRuns: 3,
},
},
}
Server Command
Start a local server before collection:
module.exports = {
ci: {
collect: {
startServerCommand: 'npm run serve',
startServerReadyPattern: 'Server listening on',
startServerReadyTimeout: 10000, // ms
url: ['http://localhost:8080/'],
numberOfRuns: 3,
},
},
}
The server process is automatically killed after collection completes.
Chrome Options
module.exports = {
ci: {
collect: {
// Path to Chrome executable
chromePath: '/usr/bin/google-chrome',
// Chrome launch flags
chromeFlags: '--no-sandbox --disable-gpu',
// Puppeteer script for authentication/setup
puppeteerScript: './scripts/puppeteer-script.js',
// Puppeteer launch options
puppeteerLaunchOptions: {
headless: true,
},
},
},
}
Puppeteer Script
For authenticated pages or complex setup:
// scripts/puppeteer-script.js
module.exports = async (browser, context) => {
const page = await browser.newPage()
await page.goto('https://example.com/login')
await page.type('#username', 'user')
await page.type('#password', 'pass')
await page.click('#submit')
await page.waitForNavigation()
}
Advanced Settings
module.exports = {
ci: {
collect: {
// Disable headless mode for debugging
headful: false,
// Preserve previous collection data instead of replacing
additive: false,
// Maximum wait time for page load
maxWaitForLoad: 45000, // ms
// Lighthouse settings override
// Note: simulated throttling (default) provides lowest variance
// See: https://www.debugbear.com/blog/cpu-throttling-in-chrome-devtools-and-lighthouse
settings: {
throttling: {
rttMs: 40,
throughputKbps: 10240,
cpuSlowdownMultiplier: 1,
},
screenEmulation: {
mobile: false,
width: 1350,
height: 940,
deviceScaleFactor: 1,
},
},
},
},
}
Assert Options
The assert configuration defines performance budgets and quality gates.
Presets
Three built-in presets provide baseline assertions:
module.exports = {
ci: {
assert: {
// All Lighthouse audits must pass
preset: 'lighthouse:all',
// OR recommended audits only
preset: 'lighthouse:recommended',
// OR recommended excluding PWA audits
preset: 'lighthouse:no-pwa',
},
},
}
Custom Assertions
Override preset or define custom assertions:
module.exports = {
ci: {
assert: {
preset: 'lighthouse:recommended',
assertions: {
// Category scores (0-1)
'categories:performance': ['error', { minScore: 0.9 }],
'categories:accessibility': ['warn', { minScore: 0.95 }],
'categories:seo': ['error', { minScore: 1 }],
// Specific audit scores
'first-contentful-paint': ['error', { maxNumericValue: 2000 }],
'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],
'total-blocking-time': ['error', { maxNumericValue: 300 }],
// Resource budgets
'resource-summary:script:size': ['error', { maxNumericValue: 300000 }],
'resource-summary:image:size': ['error', { maxNumericValue: 500000 }],
'resource-summary:document:size': ['error', { maxNumericValue: 50000 }],
// Pass/fail audits
'uses-http2': 'error',
'uses-long-cache-ttl': 'warn',
'offscreen-images': 'off',
},
},
},
}
Category assertions cover different audit groups: Performance evaluates speed metrics, Accessibility checks usability standards, SEO validates search optimization, and Best Practices ensures modern web standards.
Core Web Vitals assertions target key user experience metrics. When these fail, see metric-specific guides: LCP, CLS, INP.
Assertion Levels
'error'- Fails the build'warn'- Logs warning but doesn't fail'off'- Disables the assertion
Aggregation Methods
Control how multiple runs are combined:
module.exports = {
ci: {
assert: {
// How to aggregate multiple runs
// 'optimistic' (default), 'median', 'pessimistic', 'median-run'
aggregationMethod: 'median',
assertions: {
'first-contentful-paint': ['error', {
maxNumericValue: 2000,
aggregationMethod: 'pessimistic', // Override for this audit
}],
},
},
},
}
median- Middle value across runs (recommended for stability)optimistic- Best value across runs (preset default)pessimistic- Worst value across runs (strictest)median-run- All values from the median run
Assertion Syntax
{
assertions: {
// Boolean pass/fail
'audit-id': 'error',
// Score threshold
'audit-id': ['error', { minScore: 0.9 }],
// Numeric threshold
'audit-id': ['warn', { maxNumericValue: 1000 }],
// Both score and numeric
'audit-id': ['error', {
minScore: 0.8,
maxNumericValue: 2000,
}],
// Custom aggregation
'audit-id': ['error', {
maxNumericValue: 2000,
aggregationMethod: 'pessimistic',
}],
}
}
For detailed budget examples, see Performance Budgets.
Upload Options
The upload configuration controls where audit results are stored.
Temporary Public Storage
Free temporary storage hosted by Google (7 days retention):
module.exports = {
ci: {
upload: {
target: 'temporary-public-storage',
},
},
}
Returns a public URL to view results.
LHCI Server
Upload to your own Lighthouse CI server:
module.exports = {
ci: {
upload: {
target: 'lhci',
serverBaseUrl: 'https://lhci.example.com',
token: process.env.LHCI_TOKEN, // Build token from server
// Optional: ignore status code failures
ignoreDuplicateBuildFailure: true,
},
},
}
See LHCI Server Setup for server configuration.
Filesystem
Save results to local files:
module.exports = {
ci: {
upload: {
target: 'filesystem',
outputDir: './lhci-reports',
// Optional: report formats
reportFilenamePattern: '%%PATHNAME%%-%%DATETIME%%-report.%%EXTENSION%%',
},
},
}
Multiple Targets
Upload to multiple destinations:
module.exports = {
ci: {
upload: {
target: ['lhci', 'filesystem'],
serverBaseUrl: 'https://lhci.example.com',
token: process.env.LHCI_TOKEN,
outputDir: './lhci-reports',
},
},
}
Server Options
Configuration for running your own LHCI server.
Basic Server
module.exports = {
ci: {
server: {
port: 9001,
storage: {
sqlDialect: 'sqlite',
sqlDatabasePath: './lhci.db',
},
},
},
}
PostgreSQL Storage
module.exports = {
ci: {
server: {
port: 9001,
storage: {
sqlDialect: 'postgres',
sqlConnectionUrl: 'postgresql://user:pass@localhost:5432/lhci',
// Optional: SSL configuration
sqlConnectionSsl: true,
sqlDialectOptions: {
ssl: {
rejectUnauthorized: false,
},
},
},
},
},
}
MySQL Storage
module.exports = {
ci: {
server: {
port: 9001,
storage: {
sqlDialect: 'mysql',
sqlConnectionUrl: 'mysql://user:pass@localhost:3306/lhci',
},
},
},
}
Basic Authentication
module.exports = {
ci: {
server: {
port: 9001,
basicAuth: {
username: 'admin',
password: process.env.LHCI_ADMIN_PASSWORD,
},
storage: {
sqlDialect: 'sqlite',
sqlDatabasePath: './lhci.db',
},
},
},
}
Build Context
Lighthouse CI can automatically detect CI environment information. Override or supplement with environment variables:
# Git branch
LHCI_BUILD_CONTEXT__CURRENT_BRANCH=main
# Commit hash
LHCI_BUILD_CONTEXT__COMMIT_SHA=abc123
# Commit message
LHCI_BUILD_CONTEXT__COMMIT_MESSAGE="feat: add new feature"
# Author information
LHCI_BUILD_CONTEXT__AUTHOR=user@example.com
# Avatar URL
LHCI_BUILD_CONTEXT__AVATAR_URL=https://github.com/user.png
# PR or build number
LHCI_BUILD_CONTEXT__EXTERNAL_BUILD_URL=https://github.com/org/repo/pull/123
# GitHub repository slug
LHCI_BUILD_CONTEXT__GITHUB_REPO_SLUG=org/repo
Auto-detected in:
- GitHub Actions
- Travis CI
- CircleCI
- GitLab CI
- Jenkins
- AppVeyor
- Azure Pipelines
Configuration Examples
Single Page App
module.exports = {
ci: {
collect: {
staticDistDir: './build',
url: ['http://localhost/index.html'],
numberOfRuns: 5,
},
assert: {
preset: 'lighthouse:no-pwa',
assertions: {
'categories:performance': ['error', { minScore: 0.9 }],
'first-contentful-paint': ['error', { maxNumericValue: 2000 }],
'speed-index': ['error', { maxNumericValue: 3000 }],
},
},
upload: {
target: 'temporary-public-storage',
},
},
}
These assertions measure initial load speed. For optimization strategies, see the FCP and Speed Index definitions.
Multi-Page Site
module.exports = {
ci: {
collect: {
startServerCommand: 'npm run serve',
url: [
'http://localhost:8080/',
'http://localhost:8080/products',
'http://localhost:8080/about',
'http://localhost:8080/contact',
],
numberOfRuns: 3,
settings: {
preset: 'desktop',
},
},
assert: {
preset: 'lighthouse:recommended',
assertions: {
'categories:performance': ['warn', { minScore: 0.85 }],
'categories:accessibility': ['error', { minScore: 0.95 }],
'categories:seo': ['error', { minScore: 1 }],
},
},
upload: {
target: 'lhci',
serverBaseUrl: process.env.LHCI_SERVER_URL,
token: process.env.LHCI_TOKEN,
},
},
}
Production Site Monitoring
module.exports = {
ci: {
collect: {
url: ['https://example.com/'],
numberOfRuns: 5,
settings: {
preset: 'desktop',
throttling: {
rttMs: 40,
throughputKbps: 10240,
cpuSlowdownMultiplier: 1,
},
},
},
assert: {
assertions: {
'categories:performance': ['error', { minScore: 0.95 }],
'first-contentful-paint': ['error', { maxNumericValue: 1500 }],
'largest-contentful-paint': ['error', { maxNumericValue: 2000 }],
'cumulative-layout-shift': ['error', { maxNumericValue: 0.05 }],
'total-blocking-time': ['error', { maxNumericValue: 200 }],
},
aggregationMethod: 'pessimistic',
},
upload: {
target: ['lhci', 'filesystem'],
serverBaseUrl: process.env.LHCI_SERVER_URL,
token: process.env.LHCI_TOKEN,
outputDir: './reports',
},
},
}
Strict production budgets require optimization across all Core Web Vitals. Target values: LCP under 2.5s, CLS under 0.1, TBT under 200ms.
Authenticated Pages
// lighthouserc.js
module.exports = {
ci: {
collect: {
url: [
'http://localhost:3000/dashboard',
'http://localhost:3000/profile',
],
startServerCommand: 'npm start',
puppeteerScript: './scripts/login.js',
numberOfRuns: 3,
},
assert: {
preset: 'lighthouse:recommended',
},
upload: {
target: 'temporary-public-storage',
},
},
}
// scripts/login.js
module.exports = async (browser, context) => {
const page = await browser.newPage()
await page.goto('http://localhost:3000/login')
await page.type('#email', 'test@example.com')
await page.type('#password', 'password123')
await page.click('button[type="submit"]')
await page.waitForNavigation()
}
CI Integration
GitHub Actions
- name: Run Lighthouse CI
run: |
npm install -g @lhci/cli
lhci autorun
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
LHCI_TOKEN: ${{ secrets.LHCI_TOKEN }}
See GitHub Actions Integration.
GitLab CI
lighthouse:
script:
- npm install -g @lhci/cli
- lhci autorun
variables:
LHCI_TOKEN: $LHCI_TOKEN
Next Steps
- Performance Budgets - Deep dive into assertion strategies
- LHCI Server Setup - Self-host result storage
- GitHub Actions - CI/CD integration
- GitLab CI - GitLab integration