How to run Lighthouse on localhost

Three ways to point Lighthouse at a local URL, and the part most guides skip: why the number it gives you is usually wrong, and what to do about it.

Short answer

Lighthouse runs on your machine, so localhost works. Use the Chrome DevTools Lighthouse panel, run npx lighthouse http://localhost:3000, or import it as a Node module. All three drive your own Chrome, so anything that browser can open is auditable, including VPN hosts and pages behind a login. The harder question is whether the score means anything: by default a local run reads optimistically, mostly because localhost has no network latency and your CPU is faster than the phone Lighthouse is pretending to be.

Three ways to run it

Method 01

The Chrome DevTools Lighthouse panel

Open your page in Chrome, open DevTools with Cmd Option I or Ctrl Shift I, select the Lighthouse panel, choose Mobile or Desktop and the categories you care about, then click Analyze page load.

Audit in a Guest or Incognito window with extensions disabled. Extensions inject scripts into the page under test and routinely move Performance by double digits, which is the single most common reason two people get different numbers for the same page.

Method 02

The command line

No install needed if you have Node.

$ npx lighthouse http://localhost:3000 --view

# desktop preset, performance only, JSON on disk
$ npx lighthouse http://localhost:3000 \
    --preset=desktop \
    --only-categories=performance \
    --output=json --output-path=./report.json

# headless, for a script or a CI step
$ npx lighthouse http://localhost:3000 \
    --chrome-flags="--headless=new"

# match the DevTools panel defaults exactly
$ npx lighthouse http://localhost:3000 \
    --throttling-method=simulate --form-factor=mobile

--view opens the HTML report in your browser when the run finishes. --output=json gives you the full audit tree, which is the same data every Lighthouse front end is rendering.

Method 03

As a Node module

When you want to script the run, for example to audit a list of routes or gate a build.

import lighthouse from 'lighthouse';
import * as chromeLauncher from 'chrome-launcher';

const chrome = await chromeLauncher.launch({
  chromeFlags: ['--headless=new'],
});

const result = await lighthouse('http://localhost:3000', {
  port: chrome.port,
  output: 'json',
  onlyCategories: ['performance'],
});

const { categories, audits } = result.lhr;
console.log('Performance', categories.performance.score * 100);
console.log('LCP', audits['largest-contentful-paint'].displayValue);

await chrome.kill();

Why a localhost score is usually wrong

Lighthouse will happily give you a number for a local page. Four things make that number diverge from what the same code does in production, and they mostly push in the same direction: optimistic.

01. A dev server is not your site

This is the big one, and it pushes the other way. A development server serves unminified bundles, an inline hot module replacement client, source maps, and framework development warnings, usually with no compression. None of it reaches users, all of it hurts the score, and it is entirely an artefact of the server you happen to be running.

Always audit a production build. Build it, serve the build, then audit that:

$ npm run build
$ npm start          # or: npx serve ./dist
$ npx lighthouse http://localhost:3000 --view

02. Localhost has no network

Round trip time to your own machine is effectively zero. There is no DNS lookup, no TLS handshake, no last-mile latency, and no CDN in front. Time to first byte is close to instant, which flatters First Contentful Paint and Largest Contentful Paint. Lighthouse's simulated throttling models a slow connection on top of what it measured, but it cannot model infrastructure that is not there.

03. Your CPU is not a phone

Lighthouse's mobile preset applies a flat 4x CPU slowdown, chosen so that a mid-range desktop lands roughly on mid-tier mobile. That multiplier is a fixed constant, not a measurement. On a fast laptop, 4x under-throttles: the emulated device ends up considerably quicker than the phone it is standing in for, Total Blocking Time reads low, and Performance reads high. Lighthouse records what it thinks of your machine as benchmarkIndex in the JSON, but nothing acts on it for you.

04. One run is an anecdote

Performance scores commonly move about 5 points between identical runs of an unchanged page. Total Blocking Time is the most volatile input and carries roughly 30 percent of the Performance score, and it responds to whatever else your CPU is doing: a build in another terminal, a sync client, a browser tab playing video. If you change something and the score moves 4 points, you have learned nothing.

The net effect

A local production build on a decent laptop typically scores well above the same code in production, often by 15 to 25 points, because reasons 02 and 03 both flatter it. A local dev server often scores well below, because reason 01 overwhelms the other two. Neither is your real score. This is why a local number and a PageSpeed Insights number should never be compared directly.

Local versus production, factor by factor

Factor On localhost Effect on score What to do
Bundle Unminified with HMR, if it is a dev server Reads low Audit a production build, never the dev server
Network latency Effectively zero RTT, no DNS, no TLS Reads high Compare local to local only, never to a PSI run
CPU throttling Flat 4x, tuned for a mid-range desktop Reads high on fast hardware Calibrate the multiplier to your own benchmarkIndex
Run-to-run noise About 5 points, driven by TBT Unreliable either way Take the median of three to five runs
Compression and caching Often absent from a local server Reads low Serve the build the way production serves it
Field data None, and none is possible Not applicable Read CrUX against the public origin instead

Making a local number mean something

You cannot make a local audit predict production. You can make it a reliable instrument for detecting change, which is what you actually want while you are writing code.

  1. Audit a production build. Everything else is noise on top of a broken measurement.
  2. Take the median of three to five runs. Lighthouse ships computeMedianRun for exactly this. A single run cannot distinguish a real regression from CPU jitter.
  3. Calibrate the CPU throttle. Read your host's benchmarkIndex and pick a multiplier that actually lands on mid-tier mobile from your hardware, rather than trusting the default 4x.
  4. Hold the environment still. Same machine, same power state, nothing heavy in the background, no extensions. A laptop on battery throttles its own CPU and will quietly change your results.
  5. Compare like with like. Track local against local over time. Use production numbers to answer "how are we doing" and local numbers to answer "did this change help".

The LightAudit Score console does the repetition, calibration and history automatically, and flags when the machine rather than the page moved the score. But the discipline matters more than the tool: a median of five runs from the CLI beats a single run from anything.

What you still cannot get locally

Lighthouse gives you lab data: one controlled run in a simulated environment. It does not give you field data, the Core Web Vitals that real Chrome users actually experienced, because that comes from the Chrome UX Report and requires a public origin with enough real traffic to report on. No local tool can produce it for localhost, and none ever will.

If what you actually wanted was PageSpeed Insights against a local address, that is a different and slightly worse problem: PSI cannot reach localhost at all, because it fetches your URL from Google's own network.

Frequently asked questions

Can Lighthouse run on localhost?

Yes. Unlike PageSpeed Insights, Lighthouse runs on your own machine, driving your own copy of Chrome, so it can audit any address that browser can open. That includes localhost on any port, a private network address, a staging host that only resolves inside your VPN, an intranet application, and a page behind a login you are already signed in to.

Why is my Lighthouse score higher on localhost than in production?

Usually because localhost has no network. Round trip time to your own machine is effectively zero, so time to first byte and First Contentful Paint read far better than they will over real DNS, TLS and internet latency. On top of that, the default mobile preset applies a flat 4x CPU throttle calibrated for a mid-range desktop, so on a fast machine it under-throttles and Total Blocking Time reads low. A local production build on a fast laptop can easily score 15 to 25 points above the same code in production.

Should I run Lighthouse against the dev server or a production build?

Always a production build. A dev server ships unminified bundles, an inline hot module replacement client, source maps, and framework development warnings, and it usually serves without compression. None of that reaches your users, and all of it hurts the score, so a dev server audit tells you almost nothing useful. Build first, serve the build, then audit that.

Why does my Lighthouse score change every time I run it?

Because Lighthouse is measuring a real page load on a machine doing other work. Performance scores commonly move about 5 points between identical runs. Total Blocking Time is the most volatile input and is worth roughly 30 percent of the Performance score, and it is highly sensitive to whatever else your CPU is doing. The fix is to stop reading single runs: audit each URL three to five times and take the median, which is what Lighthouse's own computeMedianRun function exists to do.

Can Lighthouse audit a site behind a VPN or a login?

Yes. Because Lighthouse drives a browser on your machine, it inherits your network position: if your VPN is connected and the host resolves, Lighthouse can reach it. For pages behind a login, the DevTools panel uses your existing session in that tab, and from the CLI you can point Lighthouse at a Chrome instance you have already authenticated in, or drive the sign-in with Puppeteer first.

Numbers you can defend in a code review

LightAudit Score runs Lighthouse locally with the discipline built in: median of N with an isolated Chrome per run, throttling calibrated to your hardware, drift warnings when the machine rather than the page moved the score, and history on disk. Free, open source, no account.

See what it does