Skip to content
Back to skills

Lighthouse

BSecurity

Run Lighthouse audits and iteratively fix issues until target scores are met. Optimizes performance, accessibility, best practices, and SEO.

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 2, 2026
ai-agentsjavascriptgojavabashreactnextjsgitapiperformance

Works with

  • cli
  • api

Security analysis

B88/100
  • criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study

Pro shows the line behind each finding and how to fix it

Scanned September 2, 2026

npx -y skills add ADWilkinson/claude-code-tools --skill lighthouse --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Lighthouse?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Lighthouse
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/adwilkinson-lighthouse/badge)](https://www.skillsdirectory.com/skills/adwilkinson-lighthouse)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: lighthouse
author: Andrew Wilkinson (github.com/ADWilkinson)
description: Run Lighthouse audits and iteratively fix issues until target scores are met. Optimizes performance, accessibility, best practices, and SEO.
allowed-tools: Bash, Read, Edit, Write, Glob, Grep, TodoWrite
disable-model-invocation: true
---

# /lighthouse

> **Quick Reference**: Build production → Start server → Run Lighthouse → Apply known fixes → Re-run until target (default 95) → Report results.

Run Lighthouse audits on a web app and iteratively fix issues until target scores are achieved.

## Arguments

Parse user input for:
- `<url>` - URL to audit (default: detect from dev server)
- `--target <n>` - Target score for all categories (default: 95)
- `--categories <list>` - Categories to check: performance,accessibility,best-practices,seo (default: all)
- `--fix` - Automatically apply known fixes (default: true)
- `--max-iterations <n>` - Maximum optimization iterations (default: 5)

## Step 1: Detect Project and Start Server

### Detect project type
```bash
# Check for package.json
if [ -f "package.json" ]; then
    # Check for framework
    grep -l "next\|vite\|react-scripts\|nuxt\|gatsby" package.json
fi
```

### Detect package manager
```bash
if [ -f "bun.lockb" ]; then PM="bun"
elif [ -f "pnpm-lock.yaml" ]; then PM="pnpm"
elif [ -f "yarn.lock" ]; then PM="yarn"
else PM="npm"; fi
```

### Build and start server
For accurate results, always test production builds:

**Next.js:**
```bash
$PM run build && $PM start &
# Wait for server, typically port 3000
```

**Vite:**
```bash
$PM run build && $PM run preview &
# Wait for server, typically port 4173 or 5173
```

**Create React App:**
```bash
$PM run build && npx serve -s build &
```

Wait for server to respond before proceeding:
```bash
sleep 5
curl -s -o /dev/null -w "%{http_code}" http://localhost:$PORT
```

## Step 2: Run Lighthouse Audit

```bash
npx lighthouse $URL \
  --output=json \
  --output-path=./lighthouse-report.json \
  --only-categories=performance,accessibility,best-practices,seo \
  --chrome-flags="--headless --no-sandbox" 2>&1
```

### Parse Results
```bash
cat lighthouse-report.json | jq '{
  performance: (.categories.performance.score * 100),
  accessibility: (.categories.accessibility.score * 100),
  bestPractices: (.categories["best-practices"].score * 100),
  seo: (.categories.seo.score * 100)
}'
```

### Check failing audits
```bash
cat lighthouse-report.json | jq '.audits | to_entries |
  map(select(.value.scoreDisplayMode == "binary" and .value.score == 0)) |
  map({id: .key, title: .value.title})'
```

### Get details for specific audit
```bash
cat lighthouse-report.json | jq '.audits["<audit-id>"].details.items'
```

## Step 3: Apply Known Fixes

For each failing audit, apply the appropriate fix:

### Accessibility Fixes

**color-contrast** - Text doesn't meet WCAG contrast requirements
- Check audit details for specific failing elements
- Increase contrast to 4.5:1 for small text, 3:1 for large text
- Replace opacity-based colors (e.g., `text-gray-500/60`) with solid colors
- Verify both light and dark theme variants

**aria-dialog-name** - Dialogs missing accessible names
- Add `aria-label` or `aria-labelledby` to dialog elements
- Third-party modals may not be fixable

**label-content-name-mismatch** - Accessible name doesn't match visible text
- Remove redundant `aria-label` when visible text is sufficient
- If both needed, ensure `aria-label` contains the visible text

**aria-allowed-attr** - Invalid ARIA attributes
- Remove `aria-pressed` from `role="tab"` or `role="combobox"` elements
- Check component libraries for incorrect ARIA usage

**button-name / link-name** - Missing accessible names
- Add text content or `aria-label` to interactive elements
- Ensure icon-only buttons have descriptive labels

**target-size** - Touch targets too small
- Increase padding to ensure 24x24px minimum
- Common fix: `py-1` → `py-2` or add `p-2`

### Best Practices Fixes

**errors-in-console** - Browser errors logged
- Fix 404 errors for missing resources
- Make analytics/tracking conditional on production:
  ```tsx
  // Next.js (server component)
  {process.env.VERCEL && <Analytics />}

  // Client-side check
  {typeof window !== 'undefined' &&
   !window.location.hostname.includes('localhost') && <Analytics />}
  ```

**valid-source-maps** - Missing source maps
- Enable in build config:
  ```ts
  // vite.config.ts
  build: { sourcemap: true }

  // next.config.js
  productionBrowserSourceMaps: true
  ```

**third-party-cookies** - Third-party cookies detected
- Often from auth providers or analytics - may require architectural changes
- Document as acceptable if core functionality depends on it

### SEO Fixes

**document-title** - Missing title
- Add `<title>` in head or use framework metadata API

**meta-description** - Missing meta description
- Add `<meta name="description" content="...">`

**viewport** - Missing or invalid viewport
- Ensure `<meta name="viewport" content="width=device-width, initial-scale=1">`

**crawlable-anchors** - Links not crawlable
- Ensure links have valid `href` attributes
- Avoid `javascript:void(0)` or empty hrefs

### Performance Fixes

**font-display** - Fonts blocking render
- Add `font-display: swap` to @font-face rules
- Use framework font optimization (next/font, etc.)

**render-blocking-resources** - CSS/JS blocking render
- Defer non-critical scripts
- Preload critical resources:
  ```html
  <link rel="preload" href="/font.woff2" as="font" type="font/woff2" crossorigin>
  ```

**unused-javascript** - Large unused JS bundles
- Implement code splitting with dynamic imports
- Tree-shake unused dependencies
- Large third-party SDKs may be unavoidable

**largest-contentful-paint** - Slow LCP
- Preload LCP image/element
- Reduce server response time
- Minimize render-blocking resources

**cumulative-layout-shift** - Layout shifts
- Set explicit dimensions on images/embeds
- Reserve space for dynamic content

## Step 4: Iterate Until Target Met

After applying fixes:

1. Rebuild the project
2. Restart the preview server
3. Re-run Lighthouse
4. Check if all categories meet target score
5. If not, identify remaining issues and continue fixing
6. Repeat until target met or max iterations reached

### Iteration Tracking

After each iteration, report progress in this format:

```
Iteration #2 of 5
=================
                    Before → After  (Δ)
Performance:          65   →   78   (+13)
Accessibility:        88   →   95   (+7)
Best Practices:       73   →   85   (+12)
SEO:                  91   →   100  (+9)
                    ─────────────────────
Total:              317   →  358   (+41)

Issues fixed this run:
  ✓ Added aria-label to icon buttons (accessibility)
  ✓ Enabled source maps (best-practices)
  ✓ Added meta description (seo)

Remaining issues (by priority):
  Critical:
    - render-blocking-resources (performance, -15 pts)
  Serious:
    - unused-javascript (performance, -8 pts)
  Moderate:
    - image-size-responsive (performance, -3 pts)

Progress: 358/400 (89.5%) | Target: 380/400 (95%)
Status: CONTINUE (22 points to target)
```

## Step 5: Report Results

### Success Report
```
Lighthouse Optimization Complete

| Category       | Initial | Final | Target |
|----------------|---------|-------|--------|
| Performance    | 65      | 95    | 95     |
| Accessibility  | 88      | 100   | 95     |
| Best Practices | 73      | 96    | 95     |
| SEO            | 91      | 100   | 95     |

Changes Made:
- [List specific fixes applied]

Remaining Issues (if any):
- [Document issues that can't be fixed and why]
```

### When Target Can't Be Met
If scores can't reach target, clearly explain:
- What's blocking improvement
- Whether it's fixable with more effort vs. architectural constraint
- Recommend adjusted target if appropriate

## Common Patterns

```bash
# Quick audit only (no fixes)
/lighthouse --no-fix

# Single category
/lighthouse --categories accessibility

# Lower target
/lighthouse --target 80

# Audit production URL
/lighthouse https://example.com
```

## Cleanup

```bash
# Remove lighthouse reports
rm -f lighthouse-report.json lh-report.json

# Kill preview server
pkill -f "next start\|vite preview" 2>/dev/null
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.