What is Lighthouse?
Lighthouse is Google's open-source, automated tool for improving web page quality. It provides audits for performance, accessibility, progressive web apps, SEO, and more. Running Lighthouse programmatically unlocks powerful possibilities for quality monitoring beyond manual DevTools audits.
While Lighthouse's browser-based interface provides quick insights, programmatic execution enables automated testing pipelines, custom reporting workflows, and quality gates in continuous integration environments. By integrating Lighthouse into your web development workflow, you ensure every deployment meets rigorous quality standards.
Lighthouse evaluates pages across five key categories to ensure comprehensive quality assurance.
Performance
Measures how quickly pages render and become interactive, including FCP, LCP, TBT, and CLS metrics.
Accessibility
Checks that pages follow WCAG guidelines, verifying proper ARIA labels, color contrast, alt text, and semantic HTML.
Best Practices
Evaluates modern web development standards, including HTTPS usage, proper doctype, and avoidance of deprecated APIs.
SEO
Ensures pages are discoverable by search engines through proper meta tags, crawlable content, and mobile-friendly design.
Progressive Web App
Validates that pages meet criteria for installability, offline functionality, and PWA standards.
Why Run Lighthouse Programmatically?
Programmatic execution offers several advantages over manual testing:
Automation Integration
Embed Lighthouse tests into CI/CD pipelines to catch regressions before deployment. Automated quality gates prevent performance regressions from reaching production. By integrating with your continuous integration workflow, you can ensure every code change meets quality standards.
Custom Reporting
Access raw audit data through the LHR (Lighthouse Result) object to create tailored dashboards, trend analysis, and team-specific reports. This flexibility allows you to surface the metrics that matter most to your stakeholders.
Multi-Page Testing
Programmatically audit entire sites by iterating through URLs, generating comprehensive quality reports across all pages. This systematic approach ensures no page falls below quality thresholds.
Configurable Testing
Specify emulated form factors (mobile/desktop), throttling settings, and specific audit categories to focus testing where needed. Tailor your testing approach to match your users' real-world conditions.
Getting Started with Lighthouse npm
The Lighthouse package provides programmatic access to all Lighthouse functionality. Installation requires Node.js and the lighthouse package.
Installation
npm install --save-dev lighthouse
This installs Lighthouse as a development dependency, making it available for testing scripts and CI/CD workflows.
Core Dependencies
Running Lighthouse programmatically requires a Chrome/Chromium browser instance. The chrome-launcher package handles browser launch and management:
npm install chrome-launcher
Chrome Launcher automatically detects available Chrome installations, manages port allocation, and provides clean browser termination.
Basic Programmatic Execution
Running Lighthouse programmatically involves launching Chrome, executing audits, and handling results.
Foundational Example
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
async function runLighthouse(url) {
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
const options = {
port: chrome.port,
output: 'json',
onlyCategories: ['performance', 'accessibility']
};
const results = await lighthouse(url, options);
await chrome.kill();
return results.lhr;
}
runLighthouse('https://example.com')
.then(report => console.log('Performance score:', report.categories.performance.score));
This script launches headless Chrome, runs performance and accessibility audits, and outputs results as JSON. The lhr (Lighthouse Result) object contains comprehensive audit data including category scores, individual audit results, and metadata.
Understanding the LHR Object
The Lighthouse Result object provides structured access to all audit data:
- categories: Audit category scores with numeric values and audit references
- audits: Individual audit results with pass/fail status and remediation guidance
- configSettings: Configuration used for the audit run
- environment: System environment information during testing
- Timing breakdown of audit phase execution
Emulated Form Factors
Testing on emulated mobile and desktop devices helps identify responsive performance issues:
const mobileConfig = {
emulatedFormFactor: 'mobile',
throttling: {
rttMs: 150,
throughputKbps: 1.6 * 1024,
cpuSlowdownMultiplier: 2
}
};
const desktopConfig = {
emulatedFormFactor: 'desktop',
throttling: {
rttMs: 40,
throughputKbps: 10 * 1024,
cpuSlowdownMultiplier: 1
}
};
Mobile testing uses slower network conditions and simulates constrained CPU to approximate real-world mobile experiences. Desktop testing uses faster throttling to represent typical desktop performance.
| Metric | Description | Good Score (< 0.9) |
|---|---|---|
| First Contentful Paint (FCP) | Time until first text/image renders | < 1.8s |
| Largest Contentful Paint (LCP) | Time until largest element renders | < 2.5s |
| Total Blocking Time (TBT) | Main thread blocked during load | < 200ms |
| Cumulative Layout Shift (CLS) | Visual stability during load | < 0.1 |
| Speed Index | How quickly content becomes visible | < 3.4s |
CI/CD Integration
Programmatic Lighthouse shines in continuous integration environments where automated quality gates prevent performance regressions.
Quality Gate Implementation
const thresholds = {
performance: 0.9,
accessibility: 0.95,
'best-practices': 0.9,
seo: 0.9
};
function validateThresholds(lhr) {
for (const [category, threshold] of Object.entries(thresholds)) {
const score = lhr.categories[category]?.score || 0;
if (score < threshold) {
throw new Error(`${category} score ${score} below threshold ${threshold}`);
}
}
}
This validation function can be integrated into CI/CD pipelines to fail builds when quality metrics fall below acceptable levels.
Multi-URL Auditing
Audit entire sites by iterating through URL lists and executing audits in parallel for efficiency:
async function auditSiteParallel(urls, concurrency = 5) {
const chunks = [];
for (let i = 0; i < urls.length; i += concurrency) {
chunks.push(urls.slice(i, i + concurrency));
}
const allResults = [];
for (const chunk of chunks) {
const promises = chunk.map(url => lighthouse(url, options));
const settled = await Promise.allSettled(promises);
allResults.push(...settled);
}
return allResults;
}
Building Custom Reports
Programmatic access to raw results enables custom reporting beyond Lighthouse's default HTML output.
Extracting Key Metrics
function extractMetrics(lhr) {
return {
performanceScore: lhr.categories.performance.score,
accessibilityScore: lhr.categories.accessibility.score,
fcp: lhr.audits['first-contentful-paint'].numericValue,
lcp: lhr.audits['largest-contentful-paint'].numericValue,
tbt: lhr.audits['total-blocking-time'].numericValue,
cls: lhr.audits['cumulative-layout-shift'].numericValue,
failingAudits: Object.entries(lhr.audits)
.filter(([_, audit]) => !audit.score && audit.score !== 1)
.map(([id, audit]) => ({
id,
title: audit.title,
description: audit.description,
url: audit.helpUrl
}))
};
}
Trend Analysis
Track metrics over time by storing results in a time-series database for performance trend analysis and regression detection. This data-driven approach supports continuous improvement of your web performance optimization efforts. For teams seeking deeper automation, explore how AI-powered DevOps automation can streamline quality assurance workflows.
1async function checkPerformanceRegression(2 beforeUrl,3 afterUrl,4 threshold = 0.055) {6 const [before, after] = await Promise.all([7 lighthouse(beforeUrl, options),8 lighthouse(afterUrl, options)9 ]);10 11 const beforeScore = before.lhr.categories.performance.score;12 const afterScore = after.lhr.categories.performance.score;13 const regression = beforeScore - afterScore;14 15 if (regression > threshold) {16 console.error(17 `Performance regression: ${(regression * 100).toFixed(1)}%`18 );19 return false;20 }21 22 return true;23}Performance Regression Testing
Run Lighthouse before and after code changes to detect performance impacts and prevent regressions from reaching production.
Accessibility Monitoring
Continuous accessibility auditing ensures inclusive experiences and maintains WCAG compliance across all pages.
Performance Budget Enforcement
Define and enforce performance budgets in CI/CD to maintain performance standards and prevent degradation.
Multi-Page Site Auditing
Systematically audit entire sites by iterating through URLs, generating comprehensive quality reports.
Best Practices for Programmatic Lighthouse
Consistent Testing Environments
Environment consistency ensures reliable, reproducible results. Use containerized Chrome instances with fixed versions to eliminate browser variability. This approach is essential for maintaining reliable CI/CD quality gates.
Warm-Up Runs
Initial Lighthouse runs may show inflated metrics due to cold start effects. Run one or more warm-up iterations before recording measurements:
async function warmedLighthouse(url, warmUpRuns = 1) {
for (let i = 0; i < warmUpRuns; i++) {
await lighthouse(url, options);
}
return lighthouse(url, options);
}
Resource Cleanup
Always properly terminate Chrome instances to prevent resource leaks:
async function safeLighthouse(url, options) {
let chrome;
try {
chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
options.port = chrome.port;
return await lighthouse(url, options);
} finally {
if (chrome) await chrome.kill();
}
}
The finally block ensures Chrome terminates even if Lighthouse throws an error.
Error Handling
Implement retry logic with exponential backoff for network reliability:
async function resilientLighthouse(url, retries = 3) {
for (let attempt = 1; attempt <= retries; attempt++) {
try {
return await lighthouse(url, options);
} catch (error) {
if (attempt === retries) throw error;
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
}
}
}
Frequently Asked Questions
What is the difference between running Lighthouse in DevTools vs programmatically?
DevTools provides a quick visual interface for one-off audits, while programmatic execution enables automation, custom reporting, CI/CD integration, and multi-page testing at scale.
Can I test authenticated pages with programmatic Lighthouse?
Yes, you can pass custom headers and cookies through the options object to test authenticated routes, A/B test variations, and pages requiring specific request headers.
How do I run Lighthouse in a CI/CD pipeline?
Install Lighthouse as a dev dependency, launch Chrome programmatically, run audits with appropriate thresholds, and fail builds when scores fall below acceptable levels. Use the LHR object to extract metrics and validate against quality gates.
Why do my Lighthouse scores vary between runs?
Network conditions, system load, and browser state can cause score variations. Run multiple iterations and use median values, implement warm-up runs, and ensure consistent testing environments for reliable results.